TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: PICYO en 13 de Octubre de 2010, 15:00:06

Título: RS232 Pic16F874A. Envio de dato al pic desde puerto serie
Publicado por: PICYO en 13 de Octubre de 2010, 15:00:06
Hola! estoy tratando de migrar un programa en ASM ( no importa lcómo esté hecho) a CCS, y cuando lo consiga lo trataré de hacer en C18.

* Tengo un programa en VisualC++ que manda por puerto serie, al COM1, información ( una letra, para ser exactos).
* Mediante un programa en ASM, y con el simulador ISIS, el pic reconoce la información mandada y efectua la operación ( encender un led en puerto B).

              - Puedo comprobar que desde mi aplicación VisualC++, el dato es transferido correctamente por el puerto serie, gracias a Hyperterminal.
              - Al ejecutar el programa ASM ( no hecho por mi) y ver resultado por ISIS, también veo lo mismo por el "Hyperterminal" virtual que trae consigo.

* Al querer migrar ese programa en ASM, a una aplicación hecha en C asumo,  de momento, que el programa encenderá un led ( el mismo) sea cual sea la letra que hayamos pulsado.

PROBLEMAS:

1) Antes de ver si enciend o no el led, tengo un problema ( y de aqui supongo que parte todo) con el "Hyperterminal" Virtual del ISIS. Si pongo esta línea:
Código: C
  1. #use rs232(baud=9600,stream=COM2,BITS=8,PARITY=N)

el "Hyperterminal" Virtual del ISIS reconoce lo mismo que el Hyperterminal de Windows, aunque no hace caso del dato mandado ( no le pongo que pines son Tx y Rx...)

2) Si lo hago como desde el principio lo hacia, o sea, así :
Código: C
  1. #use rs232(baud=9600, xmit=PIN_A3,rcv=PIN_A4,stream=COM2,BITS=8,PARITY=N,FORCE_SW)
El "Hyperterminal" Virtual del ISIS, nisiquiera lee lo que hay realmente en el COM2.
cabe decir que la aplicación VisualC++ transmite dato desde COM1, y el COM del ISIS, es COM2.
Y aqui os pongo el programa:
Código: C
  1. #include <16F84A.h>
  2. #fuses HS,NOWDT,NOPROTECT
  3. #use delay(clock=4000000)
  4. #include <stdio.h>
  5.  
  6.  
  7.  
  8. #use rs232(baud=9600, xmit=PIN_A3,rcv=PIN_A4,stream=COM2,BITS=8,PARITY=N,FORCE_SW)
  9. //#use rs232(baud=9600,stream=COM2,BITS=8,PARITY=N)
  10. #use fast_io(A)
  11. #use fast_io(B)
  12.  
  13. #byte porta=0x05
  14. #byte trisa=0x85
  15. #byte portb=0x06
  16. #byte trisb=0x86
  17.  
  18. #byte OptionRegister=0x81
  19. #bit RBPU=0x81.7
  20. #bit TOCS=0x81.5
  21.  
  22.  
  23. /*#define LCD_ENABLE_PIN PIN_A2
  24. #define LCD_RS_PIN PIN_A0
  25. #define LCD_TYPE 2*/
  26. void main()
  27. {
  28. char letra;
  29.  
  30.  
  31. output_low(pin_B0);
  32. output_low(pin_B1);
  33. output_low(pin_B2);
  34. output_low(pin_B3);
  35.  
  36.  
  37.  
  38. while(1){
  39. RBPU=1;
  40. TOCS=0 ;//no usa el pin A4 como clk
  41.  
  42.  
  43. trisb=0x00;
  44. //trisa=0b00010000;
  45.  
  46.    while(kbhit()){
  47.    //output_high(pin_B3);
  48.  
  49.      letra=getc();
  50.     }
  51.  
  52.    switch(letra){
  53.          case 'a': output_high(pin_B0);delay_ms(500);
  54.          case 'b': output_high(pin_B0);delay_ms(500);
  55.          case 'l': output_high(pin_B0);delay_ms(500);
  56.          case 't': output_high(pin_B0);delay_ms(500);
  57.        }
  58.  
  59.  }//while(1)
  60. }//main

Problemas que he creido ver:

1) El PortA tiene en PIN_A4 que es Input/output o clock externo para input del Timer0. Como no quiero usar timer0, sólo quiero que sea un simple I/O, y quieria deshabilitar los pullups en el puerto B, he hecho esto :
Código: C
  1. #byte OptionRegister=0x81
  2. #bit RBPU=0x81.7
  3. #bit TOCS=0x81.5
donde dentro del main pongo los valores:
Código: C
  1. RBPU=1;
  2. TOCS=0
, que significan ( leyendo datasheet) :

Código: C
  1. bit 7 RBPU: PORTB Pull-up Enable bit
  2. 1 = PORTB pull-ups are disabled
  3. 0 = PORTB pull-ups are enabled by individual port latch values
  4.  
  5.  
  6. bit 5 T0CS: TMR0 Clock Source Select bit
  7. 1 = Transition on RA4/T0CKI pin
  8. 0 = Internal instruction cycle clock (CLKOUT)

Después de efectuar estos cambios, sigo sin ver resultado con mi programa en CCS... ¿ Alguien reconoce el error ?
Gracias!
Título: Re: RS232 Pic16F874A. Envio de dato al pic desde puerto serie
Publicado por: PICYO en 14 de Octubre de 2010, 11:11:33
Una pregunta adicional... ess posible hacer debug en CCS ( sin hardware) como en MpLab ??
Título: Re: RS232 Pic16F874A. Envio de dato al pic desde puerto serie
Publicado por: Nocturno en 14 de Octubre de 2010, 11:53:46
Se puede hacer con Proteus por ejemplo. Allí dibujas tu circuito con tu microcontrolador, insertas en el PIC el código compilado por CCS en formato COF y podrás hacer debug paso a paso y examinar los valores de todas las variables.
Título: Re: RS232 Pic16F874A. Envio de dato al pic desde puerto serie
Publicado por: Diego E. en 14 de Octubre de 2010, 15:36:02
Hola amigos, otra alternativa es trabajar C directamente en Mplab, sólo se configura el compilador PICC a través de "Proyect - select - lenguage - toolsuite", de este modo puedes trabajar igual que si estuvieras trabajando en ASM, el depurador, programador, etc. Además desde el mplab se puede elegir como simulador el proteus y así depuras paso a paso el programa en Mplab y vas viendo lo que ocurre en proteus.

saludos.
Título: Re: RS232 Pic16F874A. Envio de dato al pic desde puerto serie
Publicado por: PICYO en 15 de Octubre de 2010, 11:28:18
Uhm, claro, integrar CCS en MpLab, y desde ahí puedo debuggar en ASM..increíble...no se me había ocurrido ! Gracias!! Nocturno: Si, uso Proteus, pero tengo la mala mania de nunca usar debugger de ahí...encima tengo esas dos opciones.

Pues veré cómo estan las variables a ver si averiguo por qué hay conflictos con "Hyper Terminal de Proteus ( Virtual terminal??)" y mi envio de datos por EL COM1. NO se si lo comenté, pero con el programa de Visual C++ envio desde el COM1, y conecto físicamente al COM2 ( en proteus está el terminal COM2)
Título: Re: RS232 Pic16F874A. Envio de dato al pic desde puerto serie
Publicado por: PICYO en 15 de Octubre de 2010, 14:05:40
Hola!
Bueno, ya he descubierto que pasaba. Estaba usando una variable char para guardar lo que venia del COM1 ( lo que entraba al COM2). Al final ( y esto si que no se que ha sido..) veía por el Hyperterminal de Proteus lo que mandaba desde el Visual C++, pero y e aqui el problema: Lo guardaba erróneamente. El programa se quedaba "estancado" en una zona de la libreria string.h, esperando un caracter ( bueno, eso lo sé ahora). Cuando digo que lo guardaba erróneamente, es que lo guardaba en un char, y lo que hay que hacer es una cadena de caracteres:

Declarar una cadena de caracteres, de 2 posiciones: - una para el valor enviado por RS232
                                                                             - la otra para poner el caracter nulo  '\0' para indicar fin de string

Ahora me queda hacer que pulsando una nueva tecla, cambie los leds ( sin tener que resetear claro). Pero eso es ya menos problematico ( espero :D)
Aqui pongo el código, aunque solo esta hecho para ver el cambio de led por cada boton apretado RESETEANDO, es decir, aun habre de subir un arreglo :

Código: C
  1. #include <16F84A.h>
  2. #fuses HS,NOWDT,NOPROTECT
  3. #use delay(clock=4000000)
  4. #include <stdio.h>
  5.  
  6. #use rs232(baud=9600, xmit=PIN_A4,rcv=PIN_A3,stream=COM2,BITS=8,PARITY=N,FORCE_SW)
  7. //#use rs232(baud=9600,stream=COM2,BITS=8,PARITY=N)
  8. #use fast_io(A)
  9. #use fast_io(B)
  10.  
  11. #byte porta=0x05
  12. #byte trisa=0x85
  13. #byte portb=0x06
  14. #byte trisb=0x86
  15.  
  16. #byte OptionRegister=0x81
  17. #bit RBPU=0x81.7
  18. #bit TOCS=0x81.5
  19.  
  20. void main()
  21. {
  22. char letra;
  23. char *letras[2];
  24.  
  25.  
  26. output_low(pin_B0);
  27. output_low(pin_B1);
  28. output_low(pin_B2);
  29. output_low(pin_B3);
  30.  
  31.  
  32. while(1){
  33. //RBPU=1;
  34. //TOCS=0 ;//no usa el pin A4 como clk
  35.  
  36.  
  37. trisb=0x00;
  38. //trisa=0b00010000;
  39.  
  40.    if(kbhit()){
  41.      letras[0]=getchar();
  42.      letras[1]='\0';
  43.      delay_ms(500);
  44.      putc(letra);
  45.    }
  46.  
  47.    switch(letras[0]){
  48.          case 'a': output_high(pin_B0);delay_ms(500);break;
  49.          case 'b': output_high(pin_B1);delay_ms(500);break;
  50.          case 'l': output_high(pin_B2);delay_ms(500);break;
  51.          case 't': output_high(pin_B3);delay_ms(500);break;
  52.          case ' ':output_low(pin_B0);
  53.                    output_low(pin_B1);
  54.                    output_low(pin_B2);
  55.                    output_low(pin_B3);break;  // deberia hacer una variable donde guardase el estado de los pines y cambiarlo
  56.        }
  57.  }//while(1)
  58. }//main