TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: soymoe en 29 de Diciembre de 2016, 19:58:23

Título: Prender una luz con la PC por puerto usb
Publicado por: soymoe en 29 de Diciembre de 2016, 19:58:23
Hola a todos, estoy tratando de hacer un programa para un pic que al recibir un 1 por rs 232 prenda un foco y al recibir un 0 lo apague, pero el problema es que no hace la interrupcion cuando yo pulso una tecla, este es el programa:
Código: [Seleccionar]
#include <16F88.h>

#FUSES NOWDT                    // No Watch Dog Timer
#FUSES INTRC_IO                 // >>> Oscilador interno, no CLKOUT
#FUSES PUT                      // Power Up Timer
#FUSES NOMCLR                   // Master Clear pin used for I/O
#FUSES BROWNOUT                 // Reset when brownout detected
#FUSES PROTECT                // Code protected from reading
#FUSES NOCPD                    // No EE protection
char rcvchar;
#use delay(int=4000000) // Especifica al compilador que hace uso del OSC interno
#use rs232(baud=9600, xmit=PIN_A1,rcv=PIN_A2,bits=8, parity=N))
#int_rda
void serial_isr()
{                    // Interrupción recepción serie USART
   rcvchar=0x00;                       // Inicializo caracter recibido
   if(kbhit())
   {                        // Si hay algo pendiente de recibir ...
      rcvchar=getc();   // lo descargo y ...
      printf("Recibido...!"); // send alive message
   }
   if (rcvchar=='0')output_low(PIN_A0);
   if(rcvchar=='1')output_high(PIN_A0);
   
}
void main()
{
   setup_comparator(NC_NC_NC_NC);   // Todo digital
   set_tris_b(0xFF); 
   set_tris_a(0x04); 
   enable_interrupts(int_rda);
   enable_interrupts(global);
   output_low(PIN_A0);
   while(TRUE){
              printf("Estoy vivo!"); // send alive message
              delay_ms(1000);
   //
              }
}
ojala puedan ayudarme, gracias
Título: Re:Prender una luz con la PC por puerto usb
Publicado por: KILLERJC en 29 de Diciembre de 2016, 20:19:34
¿Por que usarias un UART por sotfware cuando tenes un modulo en hardware?

Es insensato.

Y no pongas nunca un printf en una interrupcion, creo haber visto otros codigos tuyos con el mismo tema, y si no mal recuerdo te lo dije que no debes ponerlo ( a no ser que me confunda de persona). Imagino que lo haces para "comprobar" que llega alli, pero todavia no tenes seguro que funcione lo de la UART entonces evitemoslo.

Si queres ver si recibio desde la UART hace un toggle de alguna salida. Que mejor que un led para indicarte si llego algo, es simple, no depende de nada y solo lleva una resistencia + led
El main seria un while(1); o... un toggle de otro pin con un delay solo para saber si esta funcionando el micro. Nuevamente, un LED.

Debo imaginar que estas usando algun conversor TTL-USB entre medio de esto.

¿Por que un LED y no un printf en el main?
Todavia ni siquiera sabemos si es un problema de la UART, entonces con esto al menos probamos la recepcion del mismo.

Si cambia el estado del led de recepcion indica que llego algo y que entro a la interrupcion (sea lo que sea que llego), sino es un problema con la UART, si envias un valor y no cambia el estado del LED entonces es un problema de recepcion. Luego podes complejizarlo mas, pero primero desde lo basico.
Si no funciona el led del main, entonces seguro que es un problema de conexion o de FUSES.

Y cambia los pines para que concuerden con los de la UART, ya que CCS te crea un UART por software al hacerle eso.
Estas usando set_tris cuando no usas #USE FAST_IO, lo cual no tiene sentido por que el compilador te lo va a cambiar como el quiere. Para eso lo dejamos que lo haga el, por eso lo quite.
no tiene sentido usar kbhit en la interrupcion, por que si entro es por que llego algo, asi que kbhit siempre va a ser true, tampoco tiene sentido ponerlo a 0 si luego se le asigna otro valor a rcvchar.

El programa quedaria:

Código: C
  1. #include <16F88.h>
  2.  
  3. #FUSES NOWDT                    // No Watch Dog Timer
  4. #FUSES INTRC_IO                 // >>> Oscilador interno, no CLKOUT
  5. #FUSES PUT                      // Power Up Timer
  6. #FUSES NOMCLR                   // Master Clear pin used for I/O
  7. #FUSES BROWNOUT                 // Reset when brownout detected
  8. #FUSES PROTECT                // Code protected from reading
  9. #FUSES NOCPD                    // No EE protection
  10.  
  11. #use delay(int=4000000) // Especifica al compilador que hace uso del OSC interno
  12. #use rs232(baud=9600, xmit=PIN_B5,rcv=PIN_B2,bits=8, parity=N)
  13.  
  14.  
  15. char rcvchar;
  16.  
  17. #int_rda
  18. void serial_isr(void)
  19. {
  20.    rcvchar=getc();
  21.    if(rcvchar=='0') output_low(PIN_A0);
  22.    else if(rcvchar=='1') output_high(PIN_A0);
  23.    output_toggle(PIN_B0);
  24. }
  25.  
  26. void main(void)
  27. {
  28.    setup_comparator(NC_NC_NC_NC);   // Todo digital
  29.    output_low(PIN_A0);
  30.    enable_interrupts(int_rda);
  31.    enable_interrupts(global);
  32.  
  33.    while(TRUE)
  34.    {
  35.       output_toggle(PIN_B1);   
  36.       delay_ms(500);
  37.    }
  38. }

y tal ves le tengas que poner un ERRORS en la definicion de RS232, pero por ahora proba asi.
Título: Re:Prender una luz con la PC por puerto usb
Publicado por: soymoe en 29 de Diciembre de 2016, 20:59:08
Gracias por la ayuda ya funciona. Con el tema el use fast io no se como se usa por eso no lo uso y no use la uart del micro porque lo copie de otro programa viejo y lo deje asi para probar. donde consigo informacion de como se usa el "use fastio"?
Título: Re:Prender una luz con la PC por puerto usb
Publicado por: KILLERJC en 29 de Diciembre de 2016, 22:02:39
Del manual de CCS, busca en google "CCS Manual" y la primera direccion es:

https://www.ccsinfo.com/downloads/ccs_c_manual.pdf