TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: sauron en 04 de Junio de 2009, 19:24:55

Título: Como puedo recibir datos por rs232?
Publicado por: sauron en 04 de Junio de 2009, 19:24:55
Hola compañeros foristas.
Al ser mi primer post es mi deber presentarme, soy estudiante de electrónica y estoy entrando al mundo de los pic.

He estado practicando la comunicación pic-pc y tengo una duda que gracias de antemano me la puedan aclarar:

Para practicar estoy usando el 16f84a, mi duda es: ¿Como puedo recibir una cadena de caracteres (por rs232) para compararlo con el pic?, por ejemplo: Deseo que el pic reciba "soy yo" y lo compare, es decir, la oración completa y no un solo caracter, y luego al ser positiva la comparación pues el pic dirá que fue correcta.
Ya he practicado y me ha funcionado cuando se trabaja con un solo caracter, pero la duda es con una cadena completa.

Gracias compañeros y seguiré en esta gran comunidad. :o

salu2
Título: Re: Como puedo recibir datos por rs232?
Publicado por: Suky en 05 de Junio de 2009, 02:19:06
Este es un ejemplo que trae el PICC:

Código: C
  1. char string[30];
  2.  
  3. printf("Password: ");
  4.  
  5. gets(string);
  6.  
  7. if(strcmp(string, password)){ //Compara con el real con el ingresado.
  8.    printf("OK");
  9. }
Título: Re: Como puedo recibir datos por rs232?
Publicado por: MLO__ en 05 de Junio de 2009, 02:37:44
Como envias "sos vos", esto quedara guardado en el bufer string[30] byte a byte: {'s','o','s',' ','v','o','s',\0}.

Es decir, recibes caracter a caracter por medio de la interrupcion y cada caracter lo vas añadiendo al bufer para luego hacer la comparacion.
Título: Re: Como puedo recibir datos por rs232?
Publicado por: sauron en 05 de Junio de 2009, 19:00:54
Vale compañeros muy agradecido por la aclaración, a la vez voy a usar de ahora la ayuda del picc (gracias Suky).

Tambien MLO gracias por la explicación interna.

Para quien le pueda interesar sobre la función gets, adjunto un simple código que hice como ejemplo...

Código: [Seleccionar]
#include <16f84A.h>
#include <string.h>
#use delay(clock=4M)
#fuses NOWDT,NOPUT
#use rs232(baud=9600, xmit=PIN_A0, rcv=PIN_A1, FORCE_SW) //manejo del RS232

char string[30];
char pass[8]="entrar";

void main(void){
 SET_TRIS_A(0b00010);
 while(1){
  printf("\n\rPassword: "); // el password es: entrar
  gets(string);
  if(!strcmp(string, pass))  // cuando la comparación NO es igual, retorna 1
   printf("\n\rPassword correcto");
  else
   printf("\n\rError, intente de nuevo");
 }
}

Como tengo que trabajar con el RS232, voy a empezar a meterme con las interrupciones, si me pudieran dar una guía para empezar muy agradecido, ya que meterme de una con (por ejemplo) int_RDA que creo que es para el RS232, para uno que no tiene idea es complicado al no entender, gracias ignorancia :D.


salu2.
Título: Re: Como puedo recibir datos por rs232?
Publicado por: MLO__ en 05 de Junio de 2009, 22:51:18
Hola.

Para el manejo de la interrupcion seria asi -lo pones antes del void main (void)-

Código: C#
  1. #int_RDA
  2. void serial_isr(void)
  3. {    
  4.   if(kbhit())
  5.  {
  6.     bufer[ContBufer++]=getc();
  7.   }
  8. }

y en el main habilitas la interrupcion con enable_interrupts(INT_RDA);

Saludos
Título: Re: Como puedo recibir datos por rs232?
Publicado por: Suky en 06 de Junio de 2009, 01:13:16
Código: C#
  1. #int_RDA
  2. void serial_isr(void)
  3. {    
  4.   gets(string);
  5. }

Utilizando gets creo que así debería funcionar. Y para la habilitación de interrupciones no te olvides también de enable_interrupts(GLOBAL).
Título: Re: Como puedo recibir datos por rs232?
Publicado por: micronet3 en 06 de Junio de 2009, 22:03:10
hola , al ver esta instruccion me causo extrañeza
#use delay(clock=4M)
funciona asi, o lo correcto seria
#use delay(clock=4000000)?
lo he compilado en ccs y no funciona
Título: Re: Como puedo recibir datos por rs232?
Publicado por: Suky en 06 de Junio de 2009, 22:06:48
Siempre he usado la última opción :wink:
Título: Re: Como puedo recibir datos por rs232?
Publicado por: MLO__ en 06 de Junio de 2009, 22:57:42
Eso depende de la version, yo he usado las dos y me funcionan sin problemas.
Título: Re: Como puedo recibir datos por rs232?
Publicado por: sauron en 07 de Junio de 2009, 01:06:31
Probando el codigo de la interrupción, por mas que le he dado vuelta, el CCS siempre dice:
"Invalid Pre-Processor directive", es decir, error con la #int_rda, sera por el 16f84a?, ya he visto varios ejemplos en el foro con la int_rda y pues he escrito el codigo bien, tambien según lo que me han dicho ustedes.
Título: Re: Como puedo recibir datos por rs232?
Publicado por: micronet3 en 08 de Junio de 2009, 02:00:18
pero si el 16f84a no tiene implementado por hardware el puerto usart por lo tanto no puede generar interrupcion #rda, sera por eso?
Título: Re: Como puedo recibir datos por rs232?
Publicado por: sauron en 08 de Junio de 2009, 02:10:26
pero si el 16f84a no tiene implementado por hardware el puerto usart por lo tanto no puede generar interrupcion #rda, sera por eso?

Tambien estaba pensando eso, esperar que lo confirmen los expertos :)
Título: Re: Como puedo recibir datos por rs232?
Publicado por: MLO__ en 08 de Junio de 2009, 02:16:24
Bueno, no soy un experto pero el 16F84A no tiene USART, por lo tanto no se puede usar la #int_RDA. Para saber que interrupciones posee el micro se revisa el .h del micro respectivo.
Título: Re: Como puedo recibir datos por rs232?
Publicado por: micronet3 en 08 de Junio de 2009, 02:17:02
es por eso amigo, lo que generan interrupciones en el pic son los perifericos de estos, en este caso, el 16f84a no tiene este periferico.
Título: Re: Como puedo recibir datos por rs232?
Publicado por: Suky en 08 de Junio de 2009, 10:10:23
Probando el codigo de la interrupción, por mas que le he dado vuelta, el CCS siempre dice:
"Invalid Pre-Processor directive", es decir, error con la #int_rda, sera por el 16f84a?, ya he visto varios ejemplos en el foro con la int_rda y pues he escrito el codigo bien, tambien según lo que me han dicho ustedes.
(http://img254.imageshack.us/img254/7936/auch.gif) (http://img254.imageshack.us/img254/7936/auch.gif) Nunca me fije que micro estabas usando! Claro, el PIC16F84 no tiene módulo USART.
Pero hay una solución, usar la interrupción externa por RB0 y flanco descendente. Esta interrupción detectaría el bit start. En C no lo he realizado, pero probaría lo siguiente:

Código: C
  1. #use rs232(baud=9600, xmit=PIN_A0, rcv=PIN_B0, FORCE_SW) // Pin RB0 para la recepción.
  2.  
  3. #int_EXT
  4. void  EXT_isr(void)
  5. {
  6.      gets(string);
  7. }
  8.  
  9.  
  10.  
  11. void main()
  12. {
  13.  
  14.    ext_int_edge(H_TO_L);
  15.    enable_interrupts(INT_EXT);
  16.    enable_interrupts(GLOBAL);
  17.  
  18. }



Título: Re: Como puedo recibir datos por rs232?
Publicado por: sauron en 08 de Junio de 2009, 13:53:08
Todos tienen razon, sin el USART no se puede usar la int_RDA, pero usando el codigo de Suky se puede lograr la interrupción deseada. Usando el código funciona perfectamente:

Código: [Seleccionar]
#include <16f84A.h>
#include <string.h>
#use delay(clock=4M)
#fuses NOWDT,NOPUT
#use rs232(baud=9600, xmit=PIN_A0, rcv=PIN_B0, FORCE_SW) //manejo del RS232

char string[30];
char pass[8]="entrar";

#int_EXT
void EXT_isr(void)
{
 gets(string);
}

void main(void)
{
 SET_TRIS_B(0b00000001);
 SET_TRIS_A(0b00000);
 ext_int_edge(H_TO_L);
 enable_interrupts(global);
 enable_interrupts(INT_EXT);
 pedir: printf("\n\rPassword: ");
 delay_ms(5000);          //Espera 5 segundos por el password
 if(!strcmp(string, pass)) //cuando la comparación NO es igual, retorna 1
 {
  printf("\n\rPassword correcto");
  disable_interrupts(global); // apagado del programa
  disable_interrupts(INT_EXT);
//  goto pedir;      //Para que vuelva a pedir el password
 }
 else
 {
  printf("\n\rError, intente de nuevo");
  goto pedir;      //Para que vuelva a pedir el password
 }
}

Ya estoy comprendiendo el uso de las interrupciones :), pero como todo lo nuevo salen las observaciones:
1. Observé que el programa no termina a pesar de que no hay ciclos infinitos, así que le agregué la desactivación de las interrupciones.
2. Si no se pone el salto "goto", luego de que muestra "error" observo que el programa queda allí "en espera" hasta que se presione ENTER para luego volver al delay, esto siempre ocurre con este tipo de interrupción?
3. Interesante prueba de aprendizaje, pero mejor voy a usar un micro que tenga USART para tener mas facilidad

salu2.
Título: Re: Como puedo recibir datos por rs232?
Publicado por: Suky en 08 de Junio de 2009, 15:13:47
Yo lo haría de la siguiente manera:
Código: C
  1. #include <16f84A.h>
  2. #include <string.h>
  3. #use delay(clock=4M)
  4. #fuses NOWDT,NOPUT
  5. #use rs232(baud=9600, xmit=PIN_A0, rcv=PIN_B0, FORCE_SW) //manejo del RS232
  6.  
  7. char string[30];
  8. char pass[8]="entrar";
  9. int1 kbhit_rs232=0; // Para saber si llego dato desde la PC.
  10.  
  11. #int_EXT
  12. void EXT_isr(void)
  13. {
  14.  gets(string);
  15.  kbhit_rs232=1;
  16. }
  17.  
  18. void main(void)
  19. {
  20.  SET_TRIS_B(0b00000001);
  21.  SET_TRIS_A(0b00000);
  22.  ext_int_edge(H_TO_L);
  23.  enable_interrupts(global);
  24.  enable_interrupts(INT_EXT);
  25.  
  26. while(1){
  27.  printf("\n\rPassword: ");
  28.  while(kbhit_rs232==0){} //Espero a que llegue dato desde la PC.
  29.  kbhit_rs232=0; // Reinicio bandera para proxima espera.
  30.  
  31.  if(!strcmp(string, pass)) //cuando la comparación NO es igual, retorna 1
  32.  {
  33.   printf("\n\rPassword correcto");
  34.   disable_interrupts(global); // apagado del programa
  35.   disable_interrupts(INT_EXT);
  36.  }
  37.  else
  38.  {
  39.   printf("\n\rError, intente de nuevo");
  40.  }
  41. }
  42. }
Título: Re: Como puedo recibir datos por rs232?
Publicado por: sauron en 08 de Junio de 2009, 20:08:26
Yo lo haría de la siguiente manera:

Vale suky que elegancia como lo arreglaste, funciona perfecto!

Hoy fui a buscar el pic 16f876 o parecido para probar en físico, pero lo unico que hay es el 16F84a, con éste ultimo no se pueden conectar dos puertos seriales a la vez verdad?

Gracias!
Título: Re: Como puedo recibir datos por rs232?
Publicado por: gera en 08 de Junio de 2009, 22:37:40
Hola!
Fijate si conseguis el 16f628 o el 16f873. Son muy comunes y tienen modulo UART. De ese modo podes implementar un puerto serie por hardware y otro por software.
Suerte!!
Título: Re: Como puedo recibir datos por rs232?
Publicado por: micronet3 en 09 de Junio de 2009, 08:00:01
wow amigo suky, que hermosa solucion.
Título: Re: Como puedo recibir datos por rs232?
Publicado por: sauron en 10 de Junio de 2009, 03:55:21
Hola!
Fijate si conseguis el 16f628 o el 16f873. Son muy comunes y tienen modulo UART. De ese modo podes implementar un puerto serie por hardware y otro por software.
Suerte!!

Gracias compañero por la sugerencia, de todas maneras tampoco hay esos modelos, estan agotados, tengo que esperar como una semana a que lleguen, así que mientras llegan estoy simulando.

Quiero comunicar dos dispositivos full duplex, por el momento estoy empezando y uso el 16F876, un puerto por hardware (pines C6 y C7) y el otro por software (pines B0(int) y B1), la interrupción RDA funciona perfecto, pero tengo problemas con la EXT del RB0, ya que la interrupción no funciona correctamente y no recibe los datos como debe. Todo lo estoy probando con proteus y el virtual terminal
Este es el codigo...

Código: [Seleccionar]
#include <16f876.h>
#include <string.h>
#use delay(clock=4M)
#fuses NOWDT,NOPUT,NOPROTECT
#use rs232(STREAM=ALARMA, baud=9600, xmit=PIN_C6, rcv=PIN_C7, parity=N, bits=8)
#use rs232(STREAM=MODEM, baud=9600, xmit=PIN_B2, rcv=PIN_B0, parity=N, bits=8)

char string_alarma[16];
char string_modem[16];
int1 kbhit_alarma=0; // Para saber si llego dato desde la alarma.
int1 kbhit_modem=0; // Para saber si llego dato desde el modem.

#int_RDA
void rda_isr()
{
 gets(string_alarma);
 kbhit_alarma=1;
}
 
#int_EXT
void ext_isr()
{
 gets(string_modem);
 kbhit_modem=1;
}

void main(void)
{
 SET_TRIS_B(0b00000001);
 SET_TRIS_C(0b10000000);
 ext_int_edge(H_TO_L);
 enable_interrupts(int_RDA);
 enable_interrupts(int_EXT);
 enable_interrupts(GLOBAL);
 while(1)
 {
  while(kbhit_alarma==0&&kbhit_modem==0){} //Espero a que llegue dato desde algun dispositivo.
  if(kbhit_alarma)
   fprintf(MODEM,"\n\rEl dato de la alarma fue: %s",string_alarma);
  if(kbhit_modem)
   fprintf(ALARMA,"\n\rEl dato del modem fue: %s",string_modem);
  kbhit_alarma=0;
  kbhit_modem=0; // Reinicio bandera para proxima espera.
 }
}

La idea es escribir en un virtual terminal y que el otro lo reciba y viceversa, pero solo uno escribe y funciona (int_rda) y el otro no (int_ext).

Gracias compañeros por las sugerencias, anexo el esquemático con el cof, hex y demás por si quieren probarlo, no se ve complicado pero bendita ignorancia :) ...disculpen tantas preguntas pero llega un momento donde uno se traba
Título: Re: Como puedo recibir datos por rs232?
Publicado por: Suky en 10 de Junio de 2009, 14:18:25
Faltaba colocar con que puerto recibir los datos:
Código: C
  1. #int_EXT
  2. void ext_isr()
  3. {
  4.  gets(string_modem,MODEM);
  5.  kbhit_modem=1;
  6. }
  7.  
  8. #int_RDA
  9. void rda_isr()
  10. {
  11.  gets(string_alarma,ALARMA);
  12.  kbhit_alarma=1;
  13. }

Y cuando se devolvían los datos estaban invertidos la selección de puertos:

Código: C
  1. if(kbhit_alarma){
  2.    fprintf(ALARMA,"\n\rEl dato de la alarma fue: %s",string_alarma);}
  3.   if(kbhit_modem){
  4.    fprintf(MODEM,"\n\rEl dato del modem fue: %s",string_modem);}
Título: Re: Como puedo recibir datos por rs232?
Publicado por: gera en 10 de Junio de 2009, 14:31:37
El stream seria como un descriptor para saber por donde se tienen q recibir o enviar los datos?
Título: Re: Como puedo recibir datos por rs232?
Publicado por: Suky en 10 de Junio de 2009, 15:03:27
El stream seria como un descriptor para saber por donde se tienen q recibir o enviar los datos?
Exactamente!
Título: Re: Como puedo recibir datos por rs232?
Publicado por: sauron en 10 de Junio de 2009, 16:07:54
Faltaba colocar con que puerto recibir los datos:

Vale compañero Suky mas que agradecido, mas conocimiento al respecto y menos ignorancia, hice la corrección y funciona perfecto, ya con ésto tengo la base para comunicar los dos dispositivos....gracias! :-/

Ahora siguiendo con este asunto de la comunicación, ¿Alguien ha trabajado con el RTS y CTS aqui en lenguaje C?
Título: Re: Como puedo recibir datos por rs232?
Publicado por: gera en 10 de Junio de 2009, 23:02:43
El stream seria como un descriptor para saber por donde se tienen q recibir o enviar los datos?
Exactamente!

Muchas gracias por aclararme la duda Suky!! :D
Título: Re: Como puedo recibir datos por rs232?
Publicado por: Suky en 11 de Junio de 2009, 01:28:36
El stream seria como un descriptor para saber por donde se tienen q recibir o enviar los datos?
Exactamente!

Muchas gracias por aclararme la duda Suky!! :D
De nada!  :D  :D
Título: Re: Como puedo recibir datos por rs232?
Publicado por: jhozate en 28 de Junio de 2009, 20:13:59
 hola a todos resulta q estoy tratando de probrar un ejemplo de los programas del compañero vszener, pero no me funciona
este es el cogido q tengo, identificas alguna falla?, practicamente no cambie nada del programa q hizo vazener
Código: CSS
  1. #include "C:\Archivos de programa\PICC\Projects\pruebaRS232.h"
  2.  
  3.  
  4. void main()
  5. {
  6.  
  7.    setup_adc_ports(NO_ANALOGS|VSS_VDD);
  8.    setup_adc(ADC_OFF);
  9.    setup_spi(SPI_SS_DISABLED);
  10.    setup_wdt(WDT_OFF);
  11.    setup_timer_0(RTCC_INTERNAL);
  12.    setup_timer_1(T1_DISABLED);
  13.    setup_timer_2(T2_DISABLED,0,1);
  14.    setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
  15.    setup_comparator(NC_NC_NC_NC);
  16.    setup_vref(FALSE);
  17.    setup_oscillator(OSC_4MHZ|OSC_TIMER1|OSC_31250|OSC_PLL_OFF);
  18.    
  19.    SET_TRIS_B(0X00);
  20.    OUTPUT_B(0X00);
  21.    // TODO: USER CODE!!
  22.  
  23. PUTS("PRUEBA DEL PUERTO SERIE  ");
  24. PUTS("MENU");
  25. PUTS("[1]PRENDER LED 1"); // \r PERMITE EL CAMBIO DE LINEA
  26. PUTS("[2]PRENDER LED 2");
  27. PUTS("[3]PRENDER LED 3");
  28. PUTS("[4]PRENDER LED 4");
  29.  
  30.        
  31.  
  32. FOR(;;)
  33. {
  34.    switch(getc())//coge tecla
  35.    {
  36.       case '1':output_high(pin_B0);
  37.       delay_ms(500);
  38.       output_low(PIN_B0);
  39.       break;
  40.      
  41.       case '2': output_high(PIN_B1); //led on verde
  42.       delay_ms(500);
  43.       output_low(PIN_B1);
  44.       break;
  45.      
  46.       case '3': output_high(PIN_B2); //led on rojo
  47.       delay_ms(500);
  48.       output_low(PIN_B2);
  49.       break;
  50.      
  51.       case '4': output_high(PIN_B3); //led on amarillo
  52.       delay_ms(500);
  53.       output_low(PIN_B3);
  54.    }
  55. }//FIN FOR INFINITO
  56.    
  57.  
  58. }//FIN MAIN
Título: Re: Como puedo recibir datos por rs232?
Publicado por: Suky en 28 de Junio de 2009, 22:43:29
En ese código no veo error, muéstranos el código de pruebaRS232.h.
Título: Re: Como puedo recibir datos por rs232?
Publicado por: jhozate en 28 de Junio de 2009, 22:47:56
este?
Código: CSS
  1. #include <18F2550.h>
  2. #device adc=8
  3.  
  4. #FUSES NOWDT                    //No Watch Dog Timer
  5. #FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
  6. #FUSES INTRC_IO                 //Internal RC Osc, no CLKOUT
  7. #FUSES NOPROTECT                //Code not protected from reading
  8. #FUSES BROWNOUT                 //Reset when brownout detected
  9. #FUSES BORV20                   //Brownout reset at 2.0V
  10. #FUSES NOPUT                    //No Power Up Timer
  11. #FUSES NOCPD                    //No EE protection
  12. #FUSES NOSTVREN                 //Stack full/underflow will not cause reset
  13. #FUSES NODEBUG                  //No Debug mode for ICD
  14. #FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
  15. #FUSES NOWRT                    //Program memory not write protected
  16. #FUSES NOWRTD                   //Data EEPROM not write protected
  17. #FUSES NOIESO                   //Internal External Switch Over mode disabled
  18. #FUSES NOFCMEN                  //Fail-safe clock monitor disabled
  19. #FUSES NOPBADEN                 //PORTB pins are configured as digital I/O on RESET
  20. #FUSES NOWRTC                   //configuration not registers write protected
  21. #FUSES NOWRTB                   //Boot block not write protected
  22. #FUSES NOEBTR                   //Memory not protected from table reads
  23. #FUSES NOEBTRB                  //Boot block not protected from table reads
  24. #FUSES NOCPB                    //No Boot Block code protection
  25. #FUSES MCLR                     //Master Clear pin enabled
  26. #FUSES LPT1OSC                  //Timer1 configured for low-power operation
  27. #FUSES NOXINST                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
  28. #FUSES PLL12                    //Divide By 12(48MHz oscillator input)
  29. #FUSES CPUDIV4                  //System Clock by 4
  30. #FUSES USBDIV                   //USB clock source comes from PLL divide by 2
  31. #FUSES VREGEN                   //USB voltage regulator enabled
  32.  
  33. #use delay(clock=4000000)
  34. #use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
Título: Re: Como puedo recibir datos por rs232?
Publicado por: jhozate en 23 de Julio de 2009, 18:05:48
resulta q tengo un problema, estoy ensayando comunicar 2 pic mediante RS232 lei este (http://www.todopic.com.ar/foros/index.php?topic=23222.msg186164#msg186164)post de don Diego para iniciarme, en principio tengo en un PIC dos entradas analogas y mostrando por Lcd el valor del las conversiones y el voltaje, adicionalmente envio el valor de una de las conversiones(valor del ADC) hacia el otro, este PIC debe mostrarse en el Lcd el valor recibido. Pues bien el segundo pic no muestra el valor recibido y siempre muestra un 10.. le pongo el virtual terminal al primer pic y  sale el valor correcto, pero cuando quiero mostrar en el otro ahí esta el problema..entonces no doy con el error,,no se si seran los formatos para las variables.

adjunto el codigo,supongo que lo q no he de utilizar no ha de causar problema.

Codigo primer PIC, convierte AN0 AN1 y muestra en LCD, Envia valor ADC
Código: CSS
  1. #include "flex_lcd.c"
  2.  
  3.  
  4. /* #######################INTERRUPCIONES##########################
  5. #int_RB              //CAMBIO DE NIBBLE
  6. void  RB_isr(void)
  7. {
  8.  
  9. }
  10.  
  11. #int_EXT
  12. void  EXT_isr(void)
  13. {
  14.  
  15. }
  16.  
  17. #int_RDA             //INTERRUPCION POR RECEPCION SERIE
  18. void  RDA_isr(void)
  19. {
  20.  
  21. }
  22.          
  23. #int_TIMER0          //INTERRUCPION DESBORDAMIENTO TMR0
  24. void  TIMER0_isr(void)
  25. {
  26.  
  27. }
  28.  
  29. #####################################################################*/
  30.  
  31. int8 O,Q;
  32. FLOAT P,R;
  33. void main()
  34. {
  35.  
  36.    setup_adc_ports(AN0_AN1_VREF_VREF);
  37.    setup_adc(ADC_CLOCK_DIV_8);
  38.    setup_psp(PSP_DISABLED);
  39.    setup_spi(SPI_SS_DISABLED);
  40.    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
  41.    setup_timer_1(T1_DISABLED);
  42.    setup_timer_2(T2_DISABLED,0,1);
  43.    setup_comparator(NC_NC_NC_NC);
  44.    setup_vref(FALSE);
  45.    enable_interrupts(INT_RB);
  46.    enable_interrupts(INT_EXT);
  47.    enable_interrupts(INT_RDA);
  48.    enable_interrupts(INT_TIMER0);
  49.    //enable_interrupts(GLOBAL);
  50.  
  51.  
  52.    
  53.    LCD_INIT();
  54.    LCD_PUTC("PRUEBA LCD");
  55.    DELAY_MS(1000);
  56.    LCD_PUTC("\f");
  57.    FOR(;;)
  58.    {
  59.    SET_ADC_CHANNEL(0);
  60.    DELAY_US(20);
  61.    Q=READ_ADC();
  62.    SET_ADC_CHANNEL(1);
  63.    DELAY_US(20);
  64.    O=READ_ADC();
  65.    P=(5.0*Q)/255.0;
  66.    R=(5.0*O)/255.0;
  67.    PRINTF(LCD_PUTC,"\fADC'S=%u  %u",Q,O);
  68.    PRINTF(LCD_PUTC,"\nV1=%1.2fV V2=%1.2fV",P,R);
  69.    PRINTF("%u\r\n",Q);
  70.    DELAY_MS(500);
  71.    }//FIN DEL FOR
  72.    
  73.    
  74.  
  75. }//FIN DEL MAIN

Este es el codigo del PIC que deberia recibir y mostrar en LCD el dato del ADC
Código: CSS
  1. #INCLUDE "FLEX_LCD.C"
  2.  
  3. int8 C=0;
  4. /*#int_RB   ####################INTERRUPCIONES#################################
  5. void  RB_isr(void)
  6. {
  7.  
  8. }*/
  9.  
  10. /*#int_EXT
  11. void  EXT_isr(void)
  12. {
  13.  
  14. }*/
  15.  
  16. #int_RDA
  17. void  RDA_isr(void)
  18. {
  19. C=GETC();
  20. }
  21.  
  22. /*#int_TIMER0
  23. void  TIMER0_isr(void)
  24. {
  25.  
  26. }
  27.  #################### #################### #################### ####################*/
  28.  
  29.  
  30. void main()
  31. {
  32.  
  33.    setup_adc_ports(NO_ANALOGS);
  34.    setup_adc(ADC_OFF);
  35.    setup_psp(PSP_DISABLED);
  36.    setup_spi(SPI_SS_DISABLED);
  37.    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
  38.    setup_timer_1(T1_DISABLED);
  39.    setup_timer_2(T2_DISABLED,0,1);
  40.    setup_comparator(NC_NC_NC_NC);
  41.    setup_vref(FALSE);
  42.   // enable_interrupts(INT_RB);
  43.   // enable_interrupts(INT_EXT);
  44.    enable_interrupts(INT_RDA);
  45.   // enable_interrupts(INT_TIMER0);
  46.    
  47.  
  48.    
  49.    LCD_INIT();
  50.    enable_interrupts(GLOBAL);
  51.    FOR(;;)
  52.    {
  53.    PRINTF(LCD_PUTC,"\f%u",C);
  54.    DELAY_MS(500);
  55.    }
  56.    
  57.  
  58. }//FIN DEL MAIN

De antemano gracias por la ayuda
Título: Re: Como puedo recibir datos por rs232?
Publicado por: wbg666 en 25 de Julio de 2009, 22:58:15
hola soy estudiante de electronica
y le comento que si hay una solucion para poder conectar varios elementos que utilicen rs232 al mismo pic.
bueno esto se logra con la utilizacion de and haciendo como un tipo de mux
es muy sencillo y sirve para muchos proyectos y asi no utilizar varios pic para conectar cada dispositivo
las and se conectan al pic haciendolas que actuen como interruptores, y desde el programa se activa la que pertenesca al dispositivo que se quiere resivir o enviar datos
espero sus dudas o comentarios
Título: Re: Como puedo recibir datos por rs232?
Publicado por: MLO__ en 26 de Julio de 2009, 11:00:23
Esta muy interesante la solucion.

Creo que la mejor opcion seria usar varias USAR por soft, de esta manera ahorramos pines.

jhozate:

En el PIC de recepcion, usa la funcion kbhit(); antes de obtener el dato:
Código: [Seleccionar]
if(kbhit())
{
 c = getc();
}

Los baud rate de los dos micros deben ser los mismos para que halla una buena comunicacion.

Saludos
Título: Re: Como puedo recibir datos por rs232?
Publicado por: Suky en 26 de Julio de 2009, 12:20:05
En el PIC de recepcion, usa la funcion kbhit(); antes de obtener el dato:
Código: [Seleccionar]
if(kbhit())
{
 c = getc();
}

MLO_, si se usa interrupción esto no es necesario para un solo dato. Porque si se genera quiere decir que se ha recibido un dato. En cambio si se recibe varios datos consecutivos con la interrupción del primero, en ese si a partir del segundo utilizamos kbhit()

Saludos!
Título: Re: Como puedo recibir datos por rs232?
Publicado por: jhozate en 26 de Julio de 2009, 14:18:11
como asi...la entrada a la interrupcion solo me serviria una vez y luego habria que usar el KBHIT, segun he visto el KBHIT se usa cuando no se quiere recurrir a la interrupcion pero su uso dejaria al programa en un bucle en espera de la llegada de un dato.
Título: Re: Como puedo recibir datos por rs232?
Publicado por: MLO__ en 26 de Julio de 2009, 14:49:01
Pues algo lei que es asi ...

De todas maneras, yo prefiero ponerlo, no esta demas.

Es preferible usar banderas o flags en la interrupcion RDA y reemplazar ese delay_ms(500) por una espera a cambio de flag.
Título: Re: Como puedo recibir datos por rs232?
Publicado por: micronet3 en 28 de Julio de 2009, 10:17:25
amigo suky te refieres a que el kbhit, serviria cuando este recepcionando dato2(en el ejemplo de abajo), de ahi en adelante si se reciben mas datos.?

if (kbhit)
{
dato1=getc();
dato2=getc();
dato3=getc();

}
Título: Re: Como puedo recibir datos por rs232?
Publicado por: micronet3 en 28 de Julio de 2009, 10:19:40
que raro, supongo que te he entendido mal, porque el kbhit se evalua cuando ocurre la primera recepcion de datos
Título: Re: Como puedo recibir datos por rs232?
Publicado por: jhozate en 29 de Julio de 2009, 16:01:55
sigo sin poder mostrar el dato que me envia el otro pic utilizando la USART, no se si el problema es de los formatos de las variables, el lcd siempre me muestra el numero 10. Basicamente lo que trato de enviar es el dato de la conversion AD(8bits).
adjunto mis archivos y tambien la simulacion

saludos
Título: Re: Como puedo recibir datos por rs232?
Publicado por: MLO__ en 29 de Julio de 2009, 16:29:51
Hola.

Le mejor opcion es asignar un flag de recepcion en la rutina de la interrupcion serial y en el main desplegar la variable cuando el flag este en TRUE. Esta espera se haria por medio de un while:

Código: [Seleccionar]
while(!FlagDatoOk);
Saludos
Título: Re: Como puedo recibir datos por rs232?
Publicado por: jhozate en 29 de Julio de 2009, 16:43:28
hice esto en la interrupcion
Código: CSS
  1. #int_RDA
  2. void  RDA_isr(void)
  3. {
  4. if(kbhit())
  5.    {
  6.    FlagDatoOk=1;
  7.    c = getc();
  8.    }
  9.    ELSE
  10.    FlagDatoOk=0;
  11. }

en el main asi:
Código: CSS
  1. DO
  2.    {
  3.    PRINTF(LCD_PUTC,"\f%U",C);
  4.    }
  5.    while(!FlagDatoOk);

sin embargo cuando simulo la simulacion se pausa, pero no muestra error..pero no funciona

tengo una duda conceptual, hacer !FlagDatoOk quiere decir que "haga mientras FlagDatoOk es diferente de cero" o "haga mientras !FlagDatoOk es falso" (¿ "lo mismo" es diferentes palabras? ), ¿es lo mismo que poner FlagDatoOk!=0; ?
Título: Re: Como puedo recibir datos por rs232?
Publicado por: MLO__ en 29 de Julio de 2009, 23:13:35
Hola.

El else dentro de la interrupcion no es necesario. Para poner a ceros el flag, se haria en el main, luego de la espera del while.

El while trabaja mientras lo que este entre sus parentesis sea 1. Como FlagDataOk=0, !FlagDataOk=1, por lo tanto, se mantendra en el ciclo while, el cual no hace si no esperar (por eso esta: while(!FlagDataOk);) hasta que cambia en la interrupcion.

Código: [Seleccionar]
while(true)
{
 printf(lcd_putc,"\f%u",c);//Imprimo el dato en la LCD
 while(!FlagDataOk);//Espero al cambio en la interrupcion
 FlagDataOk=0;//Clareo el flag
}

La interrupcion seria:
Código: [Seleccionar]
#int_RDA
void RDA_isr(void)
{
 if(kbhit())
 {
  c=getc();
  FlagDatoOk=1;
 }
}

Saludos
Título: Re: Como puedo recibir datos por rs232?
Publicado por: RB2000 en 25 de Septiembre de 2009, 04:12:00
Hola Suky:
Estoy probando los ejemplos del foro de todopic.
Iba  bien hasta que intenté interconectar el PIC con la PC a través de
RS232.

Con  el  hyperterminal  de  Windows  XP  va  todo bien. Puedo enviar o
recibir  desde  la  PC  y  el  PIC  recibe  los  comandos, ejecuta las
instrucciones y envía el retorno.

Mi problema es que quiero hacerlo a través de C (en la PC).
Vi algunos ejemplos pero casi todos usan el turbo C de Borland y tiene
una librería (conio) que permite usar el puerto serie en C.

Yo  uso  un compilador DEV -C++ y si bien encontré una emulación de la
librería  conio,  no es completa y casualmente no incluye la emulación
del manejo del puerto serial que sí tiene la conio de Borland.

Si pudieras orientarme cómo empezar te lo agradeceré.

Muchas gracias desde ya.
Título: Re: Como puedo recibir datos por rs232?
Publicado por: Suky en 25 de Septiembre de 2009, 09:33:17
Hola RB2000, no voy a poder ayudarte porque en PC programo con Visual Studio, ya sea en VB o C# o en LabWindows.  :? Puedes buscar en el subforo Lenguaje C para PC y sus variantes (http://www.todopic.com.ar/foros/index.php?board=29.0) y si no encuentras lo necesario crear un tema allí con tu duda especifica.


Saludos!
Título: Re: Como puedo recibir datos por rs232?
Publicado por: RB2000 en 02 de Octubre de 2009, 02:10:23
Muchas gracias Suky, voy para allí.  :lol:
Título: Re: Como puedo recibir datos por rs232?
Publicado por: aiwa_7 en 18 de Febrero de 2010, 18:05:39
Hola... de nuevo por estos lados... estoy realizando comunicacion PC-PIC... utilizo el pic 18F4550 y ya he logrado enviar datos (lo envio mediante un programa realizado en delphi 7) de un digito (0-9) pero al enviar de 2 o mas digitos solo recibo el ultimo... estoy utilizando la int_RDA, con el getch(); y leyendo el tema vi la instruccion gets(string) y al intercambiar el getch por ésta, lo que hace mi programa es que a la hora de enviar el dato desde la PC el pic se inhibe. no muestra nada en la LCD y se queda congelada la imagen... no se si haya que incluir alguna libreria o algo... espero me puedan ayudar... gracias...
Título: Re: Como puedo recibir datos por rs232?
Publicado por: Suky en 18 de Febrero de 2010, 18:19:25
gets necesita un carácter de salto de linea si mal no recuerdo para dar finalizada la recepción, eso está indicado en la ayuda de CCS. Si quieres manejarlo con getc e interrupciones coloca el código para ver donde puede estar el inconveniente.


Saludos!
Título: Re: Como puedo recibir datos por rs232?
Publicado por: aiwa_7 en 18 de Febrero de 2010, 18:51:26
gracias por la pronta respuesta... checare la ayuda para ver la lo comentado... cualquier cosa los mantengo al tanto...
Título: Re: Como puedo recibir datos por rs232?
Publicado por: aiwa_7 en 21 de Febrero de 2010, 19:23:27
Que tal... aqui de nuevo.. ya estuve intentando trabajar con la funcion gets(string) y no entiendo muy bien lo del salto de linea que requiere para funcionar... este es el codigo que realice:

#define LCD_DATA_PORT PORTD
#define LCD_TYPE 2
#include <lcd.c>



char a[8];

#int_RDA
void  RDA_isr(void)
{
   gets(a);
   
}


void main()
{
   lcd_init();



   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);

while (true)
{   
   lcd_gotoxy(1,1);
   printf(lcd_putc,"%s",a);
   delay_ms(3000);
   printf(lcd_putc,"\f");
   delay_ms(1000);
}

}

y el codigo con el que logro recibir datos de un solo digito es el siguiente:

#define LCD_DATA_PORT PORTD
#define LCD_TYPE 2
#include <lcd.c>


int a;

#int_RDA
void  RDA_isr(void)
{
   a=(getch()-48);
   delay_us(500);
}


void main()
{
   lcd_init();



   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);

while (true)
{   
   lcd_gotoxy(1,1);
   printf(lcd_putc,"%u",a);
   delay_ms(3000);
   printf(lcd_putc,"\f");
   delay_ms(1000);
}

}

el segundo codigo funciona bien solo por el detalle argumentado desde el primer mensaje... espero me puedan ayudar con cualquiera de los dos codigos.... gracias de antemano...
Título: Re: Como puedo recibir datos por rs232?
Publicado por: MLO__ en 21 de Febrero de 2010, 21:06:34
Cuando envies los datos desde el PC, asegurate que al final del envio esten '\r', '\n'

Saludos
Título: Re: Como puedo recibir datos por rs232?
Publicado por: ELIMAY en 24 de Febrero de 2010, 17:44:30
Hola. Disculpen es la primera ves que escribo. Debo hacer mediante rs232 escribir un nombre y que me de su apellido. Anteriormente ya lo hice pero al escribir el nombre no se mostraba y cuando daba enter me daba el resultado. Ahora lo que debo hacer es lo mismo pero debe verse lo que estoy escribiendo, comparar letra a letra. Por favor ayuda!!!!
#include <parpa.h>
#include <stdio.h>

void main()
{
   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF|ADC_TAD_MUL_0); 
   setup_spi(SPI_SS_DISABLED);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_64);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DIV_BY_16,255,1);
   setup_timer_4(T4_DISABLED,0,1);
   setup_psp(PSP_DISABLED);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
//!   fprintf(pc,"%s\n\r",cadena1);
//!   printf("%s\n\r",cadena2);
//!   fputs("hola3\r",pc);
//!   puts("hola4");
//!   printf("frase:%s:\n\r",frase);
//!   fputc(var, pc);
//!   fprintf(pc,"%u\n\r",vad);
//!   putc(0x33);
//!   sleep();
//!   delay_ms(1);
//!do  {
//!   delay_ms(100);
//!    }while(true);
//!
//!   do{
//!   delay_ms(1000);
//!   putc(0x30);
//!   delay_ms(1000);
//!   putc(0x31);
//!      }while(true);

do
   {
//!      fprintf(pc2,"\n\rPassword:\r\n ");
     do
     {
     if (kbhit());
       {a++;
        a=getc();
        putc(a);
       }
   }while(true);

      //fgets(string,pc2);
      for (x=1;x<30;x++)
      {
      putc(a);
      putc(13);
      if(strcmp(putc(a), password)==0)
       //Compara con el real con el ingresado
        { fprintf(pc2,"\n\rMaria Gonzales");
//!         break;
        }
      else
         fprintf(pc2,"\n\rError, intente de nuevo\r\n");
          {i++;
            if (i==4)
            {fprintf(pc2,"\n\rUSTED HA SIDO BLOQUEADO\r\n");
   //!            break;
            }
          }
        }
   } while(true);
}