Autor Tema: (SOLUCIONADO) problema con USART 18F252  (Leído 2595 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado kordrak

  • PIC10
  • *
  • Mensajes: 17
(SOLUCIONADO) problema con USART 18F252
« en: 23 de Enero de 2012, 14:24:10 »
Hola, me preguntaba si alguien me podria ayudar a resolver mi problema, tengo un 18f252 montado en una red RS485, el cual debe activar un pulsador y encender un led cuando es activado y/o apagar el led & desactivar el pulsador cuando es desactivado.
Pero lamentablemente el PIC parece no estar recibiendo nada, e probado conectado un 18f452 y con este si logro recibir datos..(lamentablemente este pic es demasiado grande para mi proyecto)

el  formato del mensaje que estoy enviando es el siguiente:

Mensaje[0]=0x3C - "<" (inicio de trama)
Mensaje[1]=0x00 - 0x1F   - Direccion(0 a 31)
Mensaje[2]=0x5A - 0x64 (tiempo, donde 0x5A es interpretado como 1 segundo y 0x64 son 10 seg.)
Mensaje[3]=0xC8 o 0xD2 o 0xDC,  los que representan activado, desactivado o echo(responder con su direccion) respectivamente
Mensaje[4]=reservado (0xFF)
Mensaje[5]=reservado (0xFF)
Mensaje[6]=reservado (0xFF)
Mensaje[7]=0x3E - ">" (temino de trama)

En un principio trate usando interrupciones para captar los datos, pero me no logre hacerlas funcionar.. (el codigo de las interrupciones viene a ser las partes comentadas de codigo)

pienso que probablemente mi problema sea que estoy configurando algo mal desde el principio.. pero llevo ya harto rato mirando y reescribiendo el codigo y no pillo la "pana"  :?

en fin, se agradece de antemano cualquier ayuda que me puedan brindar!!

ahi va el codigo:

PIC18F252,  10MHz, C18

Código: [Seleccionar]
#include <p18f252.h>
#include <adc.h>
#include <delays.h>
#include <usart.h>
#include <stdlib.h>

// CONFIGURACION PIC
#pragma config OSC = HS
#pragma config WDT = OFF
#pragma config LVP = OFF
#pragma config DEBUG = ON

char Mensaje[8], LeePortA;
unsigned char dato, head = 0;
unsigned int c = 0;
int estado, Dir, Tp, N_Dir;
int parse = 0;

//void rx_handler (void);
void SET_DIR(void);
void ProcesarMensaje(unsigned char Mensaje[8]);
void ProcesarPulsador(unsigned char);
void ConfiguraUSART1(void);
void ConfiguraUSART2(void);
void ProcesarUSART(unsigned char);

//#pragma code rx_interrupt = 0x18  //low priority Interrupt
//void rx_int (void)
//{
// _asm goto rx_handler _endasm
//}
//#pragma code
//
//#pragma interruptlow rx_handler
//enum {START_WAIT, RECEIVING, MSG_RECEIVED} state = START_WAIT;
//  
//void rx_handler (void)
//{
//unsigned char c;
// if (PIR1bits.RCIF == 1) // si se genero la interrupcion por la recepcion de un caracter
// {  
// c = getcUSART(); // obtener un nuevo caracter desde USART
// switch(state)
// {
// case START_WAIT: // espera que comience el mensaje
// if(c ==0x3C) // caracter de inicio recibido
// {
// head = 0; // reset el index del buffer...
// state = RECEIVING; // comienza a recibir datos
// }
// break;
//        case RECEIVING: // si esta recibiendo
// if(c==0x3E) // si llega ">"
// {
// state = MSG_RECEIVED;// actualizar estado a mensaje recibido
// parse = 0;
// }
// else // si llega cualquier otra cosa
// {
// Mensaje[head] = c; // guardar caracter en el buffer
// if (++head >= 7) // si el buffer esta llenor...
// state = START_WAIT; // espera por el siguiente mensaje
// }
// break;
// }
// }
// if(RCSTAbits.OERR)           // si se perdio un caracter (Overrun Error)
// {
// RCSTAbits.CREN = 0;           // Reset al bit de error
// RCSTAbits.CREN = 1;
// }
//}

void main(void){
ConfiguraUSART1();
TRISA = 0xFF; // Puerto A como entrada
TRISB = 0x08; // Puerto B Salidas menos RB3(Pulsador)
PORTB = 0x00; // Inicializo PortB en cero
PORTBbits.RB4 = 0; // habilita escucha(bit de control para un 75176)
SET_DIR(); // Setea direccion(segun switch{binario})

// while(BusyUSART());
// PORTBbits.RB4 = 1;
// putrsUSART("Nuevo Modulo Conectado\r\n");

// CloseUSART();
// ConfiguraUSART2();
while(1)
{
if(DataRdyUSART()){
while(BusyUSART());
dato = ReadUSART();
}
ProcesarUSART(dato);
ProcesarMensaje(Mensaje);
if (estado == 1)
{
PORTBbits.RB0 = 1; // enciende led estado
ProcesarPulsador(Tp);
}

// if(state == MSG_RECEIVED) // si recibo mensaje...
// {   // parse it...
// parse = 999; // Parse The message (to be implemented)
// ProcesarMensaje(Mensaje);
// state = START_WAIT; // permite seguir esperando mensaje
// }
// if (estado == 1)
// {
// PORTBbits.RB0 = 1;
// ProcesarPulsador(Tp);
// }
} // end while
CloseUSART();
}  // end Main

void ConfiguraUSART1(void){
TRISC = 0b10000000;  // bit 7 input 6 output
OpenUSART( USART_TX_INT_OFF &
USART_RX_INT_OFF &
USART_ASYNCH_MODE &
USART_EIGHT_BIT &
USART_CONT_RX &
USART_BRGH_HIGH, 64);
  }

void ConfiguraUSART2(void){
TRISC = 0b10000000;
OpenUSART( USART_TX_INT_OFF &
USART_RX_INT_ON &
USART_ASYNCH_MODE &
USART_EIGHT_BIT &
USART_CONT_RX &
USART_BRGH_HIGH, 64);

RCONbits.IPEN = 1; /* Enable interrupt priority */
PIE1bits.RCIE = 1; /* Make RX USART receive interrupt low priority */
IPR1bits.RCIP = 0;
INTCONbits.GIEL = 1; /* Enable all low priority interrupts */
}

void ProcesarUSART(unsigned char dato){
if(dato == 0x3C){ // si dato es inicio de trama, guardar en..
Mensaje[0] = dato;
}
else if(dato == 0x3E){ // si dato es final de trama, guardar en..
Mensaje[7] = dato;
}
else if(dato>=0x00 && dato<=0x1F){ // si es direccion...
Mensaje[1] = dato;
}
else if(dato>=0x5A && dato<=0x63){ // si es tiempo...
Mensaje[2] = dato;
}
else if(dato == 0xC8 || dato == 0xD2 || dato == 0xDC){ // si es Accion...
Mensaje[3] = dato;
}
}

void ProcesarMensaje(unsigned char Mensaje[]){
/*
Mensaje[ < Direccion Tiempo Accion 0xFF 0xFF 0xFF > ];
[0] 0x3C: bit de Inicio trama
[1] Direccion: 1 - 32
[2] Tiempo: 1 - 10 s
[3] Accion: Activar(1) || Desactivar(0) || echo_dir(3)
[4] RESERVADO
[5] RESERVADO
[6] RESERVADO
[7] 0x3E(>): bit de Termino DE TRAMA
*/
if (Mensaje[1] == Dir){
Tp = Mensaje[2];
switch(Mensaje[3]){
case 0xC8: estado = 0; break;
case 0xD2: estado = 1; break;
case 0xDC: while (BusyUSART());
PORTBbits.RB4 = 1;
WriteUSART(Dir); break;
}
}
PORTBbits.RB4 = 0; // CTRL
}

void ProcesarPulsador(unsigned char Tp){
if (PORTBbits.RB3 == 1){ // si se presiona el pulsador
PORTBbits.RB1 = 1; // Activa Rele
PORTBbits.RB0 = 0; // Apaga Led
estado = 0;
switch(Tp){
case 0x5A : Delay10KTCYx(250); break; // 1 segundo
case 0x5B : Delay10KTCYx(250); Delay10KTCYx(250); break; // 2 segundos
case 0x5C : Delay10KTCYx(250); Delay10KTCYx(250); Delay10KTCYx(250); break;
case 0x5D : Delay10KTCYx(250); Delay10KTCYx(250); Delay10KTCYx(250); Delay10KTCYx(250); break;
case 0x5E : Delay10KTCYx(250); Delay10KTCYx(250); Delay10KTCYx(250); Delay10KTCYx(250); Delay10KTCYx(250); break;
case 0x5F : Delay10KTCYx(250); Delay10KTCYx(250); Delay10KTCYx(250); Delay10KTCYx(250); Delay10KTCYx(250); Delay10KTCYx(250); break;
case 0x60 : Delay10KTCYx(250); Delay10KTCYx(250); Delay10KTCYx(250); Delay10KTCYx(250); Delay10KTCYx(250); Delay10KTCYx(250); Delay10KTCYx(250); break;
case 0x61 : Delay10KTCYx(250); Delay10KTCYx(250); Delay10KTCYx(250); Delay10KTCYx(250); Delay10KTCYx(250); Delay10KTCYx(250); Delay10KTCYx(250); Delay10KTCYx(250); break;
case 0x62 : Delay10KTCYx(250); Delay10KTCYx(250); Delay10KTCYx(250); Delay10KTCYx(250); Delay10KTCYx(250); Delay10KTCYx(250); Delay10KTCYx(250); Delay10KTCYx(250); Delay10KTCYx(250); break;
case 0x63 : Delay10KTCYx(250); Delay10KTCYx(250); Delay10KTCYx(250); Delay10KTCYx(250); Delay10KTCYx(250); Delay10KTCYx(250); Delay10KTCYx(250); Delay10KTCYx(250); Delay10KTCYx(250); Delay10KTCYx(250); break;
}
PORTBbits.RB0 = 0; // LED
PORTBbits.RB1 = 0; // RELE
estado = 0;
}
}

void SET_DIR(void){
OpenADC(ADC_FOSC_RC & ADC_RIGHT_JUST & ADC_0ANA_0REF, ADC_INT_OFF);
/*
PRIMERO DEFINE TODO EL PUERTO A COMO DIGITAL(al parecer viene activado como analogo por defecto), LUEGO
LEE PUERTO A, DEFINE UNA DIRECCION DEPENDIENDO DEL NUMERO BINARIO CONFIGURADO
*/
LeePortA = PORTA;
switch(LeePortA){
case 0b00000000: Dir = 0x00; N_Dir = 1; break;
case 0b00000001: Dir = 0x01; N_Dir = 2; break;
case 0b00000010: Dir = 0x02; N_Dir = 3; break;
case 0b00000011: Dir = 0x03; N_Dir = 4; break;
case 0b00000100: Dir = 0x04; N_Dir = 5; break;
case 0b00000101: Dir = 0x05; N_Dir = 6; break;
case 0b00000110: Dir = 0x06; N_Dir = 7; break;
case 0b00000111: Dir = 0x07; N_Dir = 8; break;
case 0b00001000: Dir = 0x08; N_Dir = 9; break;
case 0b00001001: Dir = 0x09; N_Dir = 10; break;
case 0b00001010: Dir = 0x0A; N_Dir = 11; break;
case 0b00001011: Dir = 0x0B; N_Dir = 12; break;
case 0b00001100: Dir = 0x0C; N_Dir = 13; break;
case 0b00001101: Dir = 0x0D; N_Dir = 14; break;
case 0b00001110: Dir = 0x0E; N_Dir = 15; break;
case 0b00001111: Dir = 0x0F; N_Dir = 16; break;
case 0b00010000: Dir = 0x10; N_Dir = 17; break;
case 0b00010001: Dir = 0x11; N_Dir = 18; break;
case 0b00010010: Dir = 0x12; N_Dir = 19; break;
case 0b00010011: Dir = 0x13; N_Dir = 20; break;
case 0b00010100: Dir = 0x14; N_Dir = 21; break;
case 0b00010101: Dir = 0x15; N_Dir = 22; break;
case 0b00010110: Dir = 0x16; N_Dir = 23; break;
case 0b00010111: Dir = 0x17; N_Dir = 24; break;
case 0b00011000: Dir = 0x18; N_Dir = 25; break;
case 0b00011001: Dir = 0x19; N_Dir = 26; break;
case 0b00011010: Dir = 0x1A; N_Dir = 27; break;
case 0b00011011: Dir = 0x1B; N_Dir = 28; break;
case 0b00011100: Dir = 0x1C; N_Dir = 29; break;
case 0b00011101: Dir = 0x1D; N_Dir = 30; break;
case 0b00011110: Dir = 0x1E; N_Dir = 31; break;
case 0b00011111: Dir = 0x1F; N_Dir = 32; break;
}
}
« Última modificación: 25 de Enero de 2012, 16:21:50 por kordrak »

Desconectado _LAB_

  • PIC10
  • *
  • Mensajes: 36
Re: problema con USART 18F252
« Respuesta #1 en: 23 de Enero de 2012, 23:13:57 »
Hola!!!
Amigo creo k es buena idea usar interrupciones al recibir datos, sin embargo no lo haria como tú lo tienes posteado....
Yo crearia un array del largo de la trama, al recibir interrupcion tomaria todo lo que hay caracter x caracter (sin salir de la interrupcion), luego de tomar todos los datos comprueba si tu trama es correcta.
La configuracion del USART si es a 9600 creo k esta correcta.
Y deberias probar si tu pic esta realmente conectado al usart prueba enviando algun dato por el puerto y revisalo en la PC..
Tienes que tratar de descartar posibles problemas. y trata usando solo un puerto inicialmente...
En una de esas es hasta el PIC!!
« Última modificación: 23 de Enero de 2012, 23:16:09 por _LAB_ »

Desconectado MGLSOFT

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 7918
Re: problema con USART 18F252
« Respuesta #2 en: 23 de Enero de 2012, 23:45:13 »
Esos dos PICs son de la misma familia, salvo los puertos fisicos y alguna otra pavada, se puede usar el mismo codigo sin problemas.
Yo creo que se ha embromado el PIC18F252, prueba grabar y probar con otro, especialmente si ese mismo codigo funciona en el PIC18F452, y a este le sobra suficiente memoria y RAM y ROM, deberia funcionar en el PIC18F252 sin problemas...
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado kordrak

  • PIC10
  • *
  • Mensajes: 17
Re: problema con USART 18F252
« Respuesta #3 en: 24 de Enero de 2012, 14:36:58 »
Hola!, gracias por sus respuestas

_LAB_, me interesa esa forma de recuperar el mensaje, la verdad estuve intentando hacer algo similar el otro dia, pero no tengo ni idea de si lo que habia hecho funcionaba(en el 452).. como no me funciono en el 252, borre el codigo y segui intentando con otras formas.

efectivamente estoy usando el usart con la configuracion estandar, y deberia estar correcta, ya que de lo contrario tengo varios pics malos xD (siempre uso la misma configuracion[10Mhz, 9600 baudios, 8 bit..])

con respecto a este pic en particular es mi primera vez usandolo (recien comprado), probe todos los puertos por separado, lo unico que no e logrado hechar a andar bien es el USART, voy a buscar a ver si tengo algun 232 por ahi para probar con un pc.. no habia pensado en esa opcion.


MGLSOFT, de hecho es porque son de la misma familia que decidi usar el 252 (tengo mas experiencia usando el 452), lamentablemente el comprar otro en este momento puede ser una opcion(no me la puede ganar xD.. tiene que haber una solucion.. si fuera un pic viejo el cuento seria otro).

 

Desconectado kordrak

  • PIC10
  • *
  • Mensajes: 17
Re: problema con USART 18F252
« Respuesta #4 en: 25 de Enero de 2012, 16:21:18 »
solucionado mi problema.
luego de haber re-leido y re-escrito todo el codigo unas 500 veces, decido probar con una ultima y desesperada posibilidad.

resulto ser que, al parecer, y a diferencia del 18F452, el 252 necesita que le digan que sus puertos comiencen en cero

dicho de otra forma, la solucion fue ,
 agregar un PORTC = 0x00;
despues de definir el puerto como entrada y salida para sus respectivos puertos

saludos y espero el dato le pueda servir a alguien con un problema similar