Autor Tema: como recibir caracteres correctamente  (Leído 1891 veces)

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

Desconectado PICX

  • PIC10
  • *
  • Mensajes: 20
como recibir caracteres correctamente
« en: 15 de Septiembre de 2006, 18:49:00 »
hola amigos
me encuentro enviando la convesion adc a 10bits por unidades ,decenas ,centenas ,unidades de mil osea q mando 1,0,2,2 dato por dato;
e consultado mucho el foro implementando varios metodos pero ninguno me funciona,creo que por interrupcion es el mas correcto llenando un buffer y luego imprimendolo pero aparentemente no se llena el buffer o no se lo q pasa .

ojala me puedan ayudar ,o alguna sugerencia gracias

resultado es la variable de la conversion

 unidades=resultado;

   dato1=umil;
   dato2=centenas;
   dato3=decenas;



                printf(lcd_putc,"\fEnvia~%u,%u,%u,%u",dato1,dato2,dato3,unidades);
                delay_ms(1000);
                fputc(dato1,maestro);
                delay_ms(4);
                fputc(dato2,maestro);
                delay_ms(4);
                fputc(dato3,maestro);
                delay_ms(4);
                fputc(unidades,maestro);
                delay_ms(4);
                }

de esta manera lo recibo


#include <16F877a.h>
#use delay(clock=4000000)
#fuses HS,NOWDT,NOPROTECT,NOLVP,NOBROWNOUT
#define use_portd_lcd TRUE
#byte CMCON=0x01F       /*Deshabilitamos Comparadores*/
#use rs232(stream=esclavo1,baud=9600, xmit=PIN_C1,rcv=PIN_C0,force_sw)
#include "lcd.c"
#use standard_io(C)
#define RX_BUFFER_SIZE 4

int RXdataIndex;
int RXbuffer[RX_BUFFER_SIZE] = {0,0,0,0};
int checkCommFlag;
int c;

#int_RDA
void RDA_isr()
{
   RXbuffer[RXdataIndex] = getc();
   RXdataIndex++;

   if(RXdataIndex == RX_BUFFER_SIZE)
   {

         disable_interrupts(INT_RDA);
         checkCommFlag = 1;

   }
}


void main()
{

   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(FALSE);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);

   lcd_init();
   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);

for(;;){
if(checkCommFlag=1){
   c=RXbuffer[RXdataIndex];
   printf(lcd_putc,"\f~%u!",c);         //hacer cosas con el buffer de datos

   checkCommFlag = 0;         //se vuelven a tener en cuenta las interrupciones
   enable_interrupts(INT_RDA);
   RXdataIndex=0;

   }
      }
}
 :( :( :(

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5544
    • Picmania by Redraven
Re: como recibir caracteres correctamente
« Respuesta #1 en: 15 de Septiembre de 2006, 18:59:07 »
Bueno, varias cosas:  :mrgreen:

Yo siempre le añado el kbhit() para confirmar que tengo algo pendiente de recibir ya que antes de recibir realmente un carácter le pregunta a la USART si tiene algo por entregar.

Además si debo deshabilitar RDA lo hago fuera de la misma rutina de tratamiento de la interrupción para evitar liar al compilador ya que él mismo deshabilita al RDA al entrar y la restaura al terminar de procesarla.

Y tambien tengo cuidado al hacer una comparación asignación como if(checkCommFlag=1) que deberia ser if(checkCommFlag==1)   Recuerda que tal como lo has puesto el valor del Flag es siempre 1 :D

Además reinicio el índice del buffer de recepción antes de volver a habilitar la interrupción no sea que ésta me aturrulle y llegue antes de haberlo inicializado.

Código: C
  1. #int_RDA
  2. void RDA_isr()
  3. {
  4.    if(kbhit()){
  5.       RXbuffer[RXdataIndex] = getc();
  6.      if(RXdataIndex++== RX_BUFFER_SIZE)
  7.      {
  8.          checkCommFlag = 1;
  9.      }
  10.   }
  11. }
  12.  
  13. ...
  14.  
  15. if(checkCommFlag==1){
  16.   disable_interrupts(INT_RDA);
  17.   checkCommFlag=0;
  18.   ... // Hago todo lo que tenga que hacer con lo recibido
  19.    RXdataIndex=0;
  20.    enable_interrupts(INT_RDA);
  21. }
« Última modificación: 15 de Septiembre de 2006, 19:05:52 por RedPic »
Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado PICX

  • PIC10
  • *
  • Mensajes: 20
Re: como recibir caracteres correctamente
« Respuesta #2 en: 19 de Septiembre de 2006, 01:09:23 »
gracias redpic por contestarme la inquietud :mrgreen:

e corregido el programa y todavia no logro que funcione voy a perder comunicaciones :(
a lo mucho que logro hacer es q aparesca el 42 cuando coloco checkCommFlag=1 , se que no debo asignar de esta manera,pero esto quiere decir que nunca se llena el buffer lo peor es que por mas que miro los dos programas no encuentro donde puede estar fallando

si alguien tiene conocimiento al respecto le agradeceria una pequeña ayuda,
no habia podido responder ni para agradecer por mirar estos programas :mrgreen:


PROGRAMA TRANSMISOR

#include <16F877A.h>   // Dispositivo a utilizar
#device adc=10
#fuses HS,NOWDT,NOPROTECT,NOLVP,NOBROWNOUT  // Fusibles
#use delay(clock=4000000)
#use rs232(stream=maestro,baud=9600, xmit=PIN_c6,rcv=PIN_c7,force_sw)
#define use_portb_lcd TRUE
#include "lcd.c"


int unidades, decenas, centenas, umil;
int dato1,dato2,dato3,dato4;
void borra_lcd()
{
 lcd_putc("\f");
}


/////////////////////////////////////// PRINCIPAL //////////////////////////////////////
void main()
{
long int valor;
long int resultado;

set_tris_B(0b00000000);           // Puerto B configurado como salida
port_b_pullups(FALSE);            // Desactivamos pull-ups del puerto B
setup_adc_ports(RA0_RA1_RA3_ANALOG); //Configura A0,A1 y A3 como entradas analógicas y Vdd como voltaje de referencia
setup_adc(ADC_CLOCK_INTERNAL);   // Reloj para el conversor
set_adc_channel(0);               // Seleccion del canal 0 (RA0)
lcd_init();

 do
{
valor = read_adc();
delay_us(10);
printf(lcd_putc,"Conversion ADC");
delay_ms(2000);
printf(lcd_putc,"\nTENSION:%LU",valor);
delay_ms(2000);
borra_lcd();

enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);

resultado=valor;
umil=0,centenas=0,decenas=0,unidades=0;


if (resultado>=1000)
   {
    do{
      resultado-=1000;
      umil++;
    }while (resultado>=1000);
   }

   if (resultado>=100)
   {
    do{
      resultado-=100;
      centenas++;
    }while (resultado>=100);
   }
   if (resultado>=10)
   {
    do{
      resultado-=10;
      decenas++;
    }while (resultado>=10);
   }
     unidades=resultado;

   dato1=umil;
   dato2=centenas;
   dato3=decenas;


                printf(lcd_putc,"\fEnvia~%u,%u,%u,%u",dato1,dato2,dato3,unidades);
                delay_ms(1000);
                fputc(dato1,maestro);
                delay_ms(4);
                fputc(dato2,maestro);
                delay_ms(4);
                fputc(dato3,maestro);
                delay_ms(4);
                fputc(unidades,maestro);
                delay_ms(4);
                }

 WHILE(TRUE);
 }


PROGRAMA RECEPTOR

#include <16F877a.h>
#use delay(clock=4000000)
#fuses HS,NOWDT,NOPROTECT,NOLVP,NOBROWNOUT
#define use_portd_lcd TRUE
#byte CMCON=0x01F       /*Deshabilitamos Comparadores*/
#use rs232(stream=esclavo1,baud=9600, xmit=PIN_C1,rcv=PIN_C0,force_sw)
#include "lcd.c"
#use standard_io(C)
#define RX_BUFFER_SIZE 4

int RXdataIndex;
int RXbuffer[RX_BUFFER_SIZE] = {0,0,0,0};
int checkCommFlag;
int c;

#int_RDA
void RDA_isr()
{
    if(kbhit()){
      RXbuffer[RXdataIndex] = getc(esclavo1);
      RXdataIndex++;

   if(RXdataIndex == RX_BUFFER_SIZE)
             {
         checkCommFlag = 1;
       }
   }
}


void main()
{

   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(FALSE);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);


   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);

for(;;){
lcd_init();
if(checkCommFlag==1){
   disable_interrupts(INT_RDA);
   checkCommFlag = 0;

   c=RXbuffer;
   printf(lcd_putc,"\f~%u!",c);         //hacer cosas con el buffer de datos

   RXdataIndex=0;              //se vuelven a tener en cuenta las interrupciones
   enable_interrupts(INT_RDA);


   }
      }
}

 :( :(


 

anything