Autor Tema: Cominicacion SERIAL RS232 con PC y iPad  (Leído 1695 veces)

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

Desconectado freshdesing

  • Colaborador
  • PIC12
  • *****
  • Mensajes: 88
Cominicacion SERIAL RS232 con PC y iPad
« en: 06 de Febrero de 2014, 07:35:38 »
Buenas, tengo el siguiente programa para madar un caracter a un pc y aun ipad por puerto serie RS232. Una comunicación por harware y otra por software.  Pero tengo algunos proglemas, adjunto el codigo:

Código: C
  1. ////////////////////////////////////////////////////////////////////////////////
  2. //
  3. //    -Se usan dos puertos serie, uno por Hardware RC6-RC7, y otro por
  4. //    por software RB0-RB1.
  5. //
  6. //   Dispositivo: PIC 16F877         Compilador:    CCS vs4.049
  7. //
  8. //    FUNCIONAMIENTO:
  9. //       COMUNICACION DE UN PIC CON DOS iPAD. LA COMUNICACION ES SERIE,
  10. //       UNO POR  HARDWARE Y OTRO POR SOFTWARE. EL PIC SOLO RECIBE SEÑALES DE
  11. //       CADA iPAD  Y LAS MUESTRA POR PANTALLA.
  12. //      
  13. //
  14. ////////////////////////////////////////////////////////////////////////////////
  15.  
  16.  
  17.  
  18. #include <16f877A.h>            //pic a utilizar
  19.  
  20.  
  21. #fuses XT,NOWDT,NOPROTECT,PUT,NOLVP,NOBROWNOUT, NOWRT   //ordenes para el programador
  22. #use delay(clock=4000000,RESTART_WDT)   //Fosc=4Mhz
  23.  
  24.  
  25. #include<lcd_D.c>
  26. #include<stdlib.h>
  27.  
  28. #use fast_io(A)
  29. #use fast_io(B)
  30. #use fast_io(C)
  31. #use fast_io(D)
  32.  
  33. #byte port_a = 0x05
  34. #byte port_b = 0x06
  35. #byte port_c = 0x07
  36. #byte port_d = 0x08
  37.  
  38. int i;
  39. char cadena[]="Recibido correctamente";
  40. char dato1=0x20; //un espacio
  41. char datoTEMP1=0x20; //un espacio
  42. char dato2=0x20; //un espacio
  43. char datoTEMP2=0x20; //un espacio
  44.  
  45.  
  46. //!//Subrutina para refrescar el display
  47. void display (void)
  48.    {
  49.          
  50.                printf(lcd_putc,"\f");
  51.                printf(lcd_putc,"COM RS232 v2.0\n");
  52.                printf(lcd_putc,"TRANSMITER");
  53.  
  54.   }
  55.  
  56.  
  57. //encencer y apagar led
  58. #INT_TIMER1
  59. void control_timer1(void)
  60.    {
  61.    output_bit(pin_b3,!input(pin_b3));
  62.    set_timer1(3036);
  63.    }
  64.  
  65.  
  66. //***   PORT 1   ***
  67. //ERRORES:  CON EL IPAD NO FUNCIONA, EL PIC RECIBE SOLO EL PRIMER CARACTER Y SE QUEDA BLOQUEADO.
  68. //                 CON EL PC SI FUNCIONA CORRECTAMENTE.
  69.  
  70.  
  71.  
  72. #use rs232(baud=9600,xmit=PIN_C6, rcv=PIN_C7,PARITY=N,BITS=8) //***PORT 1***
  73. ///////////////////////////////////////////////////////////////// Serial1
  74. #int_RDA             //Interrupción por recepción de datos en UART
  75.  
  76.  
  77.    void RDA_isr()
  78.    {
  79.    datoTEMP1=getc();
  80.    if ((96<=datoTEMP1)&&(datoTEMP1<=123))//Omitimos los caracteres que no son
  81.       {                                   //letras de la a-z
  82.       dato1=datoTEMP1;
  83.       }
  84.    printf(lcd_putc, "\fRv Dato1 %c %d", dato1,dato1);
  85.    printf(lcd_putc, "\nRv Dato2 %c %d", dato2,dato2);
  86.    
  87.    delay_ms(100);
  88.    }
  89.    
  90.  
  91.    
  92. //***   PORT 2   ***
  93. //ERRORES: AL RECIBIR EL PRIMER CARACTER NO HACE NADA. Y MUESTRA CUANDO LE LLEGA EL SEGUNDO.TANTO EN PC COMO CON EL IPAD
  94.  
  95.  
  96. #use rs232(baud=9600,xmit=PIN_B1, rcv=PIN_B0,PARITY=N,BITS=8)
  97. ///////////////////////////////////////////////////////////////// Serial2
  98. #int_ext          //Interrupción por recepción de datos en RB0
  99.  
  100.    void serial_isr2()
  101.    {
  102.    datoTEMP2=getc();
  103.    if ((96<=datoTEMP2)&&(datoTEMP2<=123)) //Omitimos los caracteres que no son
  104.       {                                   //letras de la a-z
  105.     dato2=datoTEMP2;
  106.      }
  107.     printf(lcd_putc, "\fRv Dato1 %c %d", dato1,dato1);
  108.    printf(lcd_putc, "\nRv Dato2 %c %d", dato2,dato2);
  109.    delay_ms(100);
  110.    }
  111.  
  112.  
  113.  
  114. ///PROGRAMA
  115. void main(void)
  116. {
  117.  
  118.    disable_interrupts(GLOBAL);
  119.    set_tris_a(0x00);       //    RA0   -->  
  120.                            //    RA1   -->  
  121.                            //    RA2   -->  
  122.                            //    RA3   -->  
  123.                            //    RA4   -->  
  124.                            //    RA5   -->  
  125.  
  126.    port_b_pullups(false);   // Resistencias de polarización del puerto B
  127.  
  128.    set_tris_b(0x01);       //    RB7   -->
  129.                            //    RB6   -->
  130.                            //    RB5   -->
  131.                            //    RB4   -->
  132.                            //    RB3   -->  
  133.                            //    RB2   -->
  134.                            //    RB1   -->   TX2
  135.                            //    RB0   -->   RX2
  136.  
  137.                            
  138.      set_tris_c(0x80);     //    RC0   -->  
  139.                            //    RC1   -->  
  140.                            //    RC2   -->  
  141.                            //    RC3   -->  
  142.                            //    RC4   -->  
  143.                            //    RC5   -->                  
  144.                            //    RC6   -->   TX1
  145.                            //    RC7   -->   RX1  
  146.                            
  147.     set_tris_d(0x00);      //    RD0   -->  OUT E
  148.                            //    RD1   -->  OUT RS
  149.                            //    RD2   -->  OUT RW
  150.                            //    RD3   -->  
  151.                            //    RD4   --> OUT D4  
  152.                            //    RD5   --> OUT D5                
  153.                            //    RD6   --> OUT D6  
  154.                            //    RD7   --> OUT D7                        
  155.                            
  156.                            
  157.  
  158.    lcd_init();         //inicializa lcd
  159.    delay_ms(200);
  160.    printf(lcd_putc,"\fLCDInicializado");
  161.    delay_ms(500);
  162.    display();
  163.    delay_ms(1000);
  164.    
  165.    
  166.    setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
  167.    enable_interrupts(INT_TIMER1);
  168.    disable_interrupts(INT_RB);
  169.    enable_interrupts(int_ext);
  170.    ext_int_edge (H_TO_L);
  171.    enable_interrupts(int_rda);
  172.    enable_interrupts(GLOBAL);
  173.    
  174.    
  175.    delay_ms(500);
  176.    display();
  177.    delay_ms(1000);
  178.    printf(lcd_putc, "\fRv Dato1");
  179.    printf(lcd_putc, "\nRv Dato2");
  180.      
  181.    while(1)
  182.    {
  183.  
  184.    }
  185.  
  186.      
  187.  
  188.          
  189. }



Los errores qeu me da son los siguentes:


//***   PORT 1   ***
//ERRORES:  CON EL IPAD NO FUNCIONA, EL PIC RECIBE SOLO EL PRIMER CARACTER Y SE QUEDA BLOQUEADO.
//                 CON EL PC SI FUNCIONA CORRECTAMENTE.
Código: C
  1. #use rs232(baud=9600,xmit=PIN_C6, rcv=PIN_C7,PARITY=N,BITS=8) //***PORT 1***
  2. #int_ext          //Interrupción por recepción de datos en RB0


//***   PORT 2   ***
//ERRORES: AL RECIBIR EL PRIMER CARACTER NO HACE NADA. Y MUESTRA CUANDO LE LLEGA EL SEGUNDO.TANTO EN PC COMO CON EL IPAD
Código: C
  1. #use rs232(baud=9600,xmit=PIN_B1, rcv=PIN_B0,PARITY=N,BITS=8)
  2. #int_ext          //Interrupción por recepción de datos en RB0


Gracias por adelantado.

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Cominicacion SERIAL RS232 con PC y iPad
« Respuesta #1 en: 06 de Febrero de 2014, 09:42:11 »
  En la rutinas de interrupción no es conveniente tener delays y tampoco pirntf ya que consume muchos ciclos de instrucción. Podrías poner alguna variable que funcione como flag (indicando que se recibió algún dato) y luego en el ciclo principal utilizar printf.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: Cominicacion SERIAL RS232 con PC y iPad
« Respuesta #2 en: 06 de Febrero de 2014, 11:31:24 »
Además de lo que te comenta AngelGris, Tal vez esto te ayude, ponle nombre a tus puertos, de la siguiente manera

Código: C
  1. #use rs232(baud=9600,xmit=PIN_C6, rcv=PIN_C7,PARITY=N,BITS=8,stream=puerto1)

en stream le asignas un nombre, y en lugar de usar getc usa un fgetc(stream), en lugar de stream pones el nombre del puerto que desees leer
esto porque cuando tienes mas de un puerto la funcion getc se queda con el último puerto que se leyo, entonces asi le especificas cual quieres leer

"Nada es imposible, no si puedes imaginarlo"

Desconectado freshdesing

  • Colaborador
  • PIC12
  • *****
  • Mensajes: 88
Re: Cominicacion SERIAL RS232 con PC y iPad
« Respuesta #3 en: 06 de Febrero de 2014, 12:25:19 »
Además de lo que te comenta AngelGris, Tal vez esto te ayude, ponle nombre a tus puertos, de la siguiente manera

Código: C
  1. #use rs232(baud=9600,xmit=PIN_C6, rcv=PIN_C7,PARITY=N,BITS=8,stream=puerto1)

en stream le asignas un nombre, y en lugar de usar getc usa un fgetc(stream), en lugar de stream pones el nombre del puerto que desees leer
esto porque cuando tienes mas de un puerto la funcion getc se queda con el último puerto que se leyo, entonces asi le especificas cual quieres leer



 En la rutinas de interrupción no es conveniente tener delays y tampoco pirntf ya que consume muchos ciclos de instrucción. Podrías poner alguna variable que funcione como flag (indicando que se recibió algún dato) y luego en el ciclo principal utilizar printf.


Muchas gracias a los dos, ya funciona... adjunto el codigo modificado por si le sirve a alguien.


Código: C
  1. #include <16f877A.h>            //pic a utilizar
  2.  
  3.  
  4. #fuses XT,NOWDT,NOPROTECT,PUT,NOLVP,NOBROWNOUT, NOWRT   //ordenes para el programador
  5. #use delay(clock=4000000,RESTART_WDT)   //Fosc=4Mhz
  6.  
  7.  
  8. #include<lcd_D.c>
  9. #include<stdlib.h>
  10.  
  11. #use fast_io(A)
  12. #use fast_io(B)
  13. #use fast_io(C)
  14. #use fast_io(D)
  15.  
  16. #byte port_a = 0x05
  17. #byte port_b = 0x06
  18. #byte port_c = 0x07
  19. #byte port_d = 0x08
  20.  
  21. int i;
  22. char cadena[]="Recibido correctamente";
  23. char dato1=0x20; //un espacio
  24. char datoTEMP1=0x20; //un espacio
  25. char dato2=0x20; //un espacio
  26. char datoTEMP2=0x20; //un espacio
  27.  
  28. int1 actualiza=0;// actualiza==1 si hay que refrescar el display
  29.  
  30. //!//Subrutina para refrescar el display
  31. void display (void)
  32.    {
  33.          
  34.                printf(lcd_putc,"\f");
  35.                printf(lcd_putc,"COM RS232 v5.0\n");
  36.                printf(lcd_putc,"TRANSMITER");
  37.  
  38.   }
  39.  
  40.  
  41.  
  42. #INT_TIMER1
  43. void control_timer1(void)
  44.    {
  45.    output_bit(pin_b3,!input(pin_b3));
  46.    set_timer1(3036);
  47.    }
  48.  
  49.  
  50. //***   PORT 1   ***
  51. #use rs232(baud=9600,xmit=PIN_C6, rcv=PIN_C7,PARITY=N,BITS=8,stream=puerto1)
  52. ///////////////////////////////////////////////////////////////// Serial1
  53. #int_RDA             //Interrupción por recepción de datos en UART
  54.  
  55.  
  56.    void RDA_isr()
  57.    {
  58.    datoTEMP1=fgetc(puerto1);
  59.    if((96<=datoTEMP1)&&(datoTEMP1<=123))//Omitimos los caracteres que no son
  60.       {                                   //letras de la a-z
  61.       dato1=datoTEMP1;
  62.       actualiza=1;
  63.       }
  64.    }
  65.    
  66.  
  67.    
  68.  
  69. //***   PORT 2   ***
  70. #use rs232(baud=9600,xmit=PIN_B1, rcv=PIN_B0,PARITY=N,BITS=8,stream=puerto2)
  71. ///////////////////////////////////////////////////////////////// Serial2
  72. #int_ext          //Interrupción por recepción de datos en RB0
  73.  
  74.    void serial_isr2()
  75.       {
  76.    datoTEMP2=fgetc(puerto2);
  77.    if((96<=datoTEMP2)&&(datoTEMP2<=123))//Omitimos los caracteres que no son
  78.       {                                   //letras de la a-z
  79.       dato2=datoTEMP2;
  80.       actualiza=1;
  81.       }
  82.    }
  83.  
  84.  
  85. ///PROGRAMA
  86. void main(void)
  87. {
  88.  
  89.    disable_interrupts(GLOBAL);
  90.    set_tris_a(0x00);       //    RA0   -->  
  91.                            //    RA1   -->  
  92.                            //    RA2   -->  
  93.                            //    RA3   -->  
  94.                            //    RA4   -->  
  95.                            //    RA5   -->  
  96.  
  97.    port_b_pullups(false);   // Resistencias de polarización del puerto B
  98.  
  99.    set_tris_b(0x01);       //    RB7   -->
  100.                            //    RB6   -->
  101.                            //    RB5   -->
  102.                            //    RB4   -->
  103.                            //    RB3   -->  
  104.                            //    RB2   -->
  105.                            //    RB1   -->   TX2
  106.                            //    RB0   -->   RX2
  107.  
  108.                            
  109.      set_tris_c(0x80);     //    RC0   -->  
  110.                            //    RC1   -->  
  111.                            //    RC2   -->  
  112.                            //    RC3   -->  
  113.                            //    RC4   -->  
  114.                            //    RC5   -->                  
  115.                            //    RC6   -->   TX1
  116.                            //    RC7   -->   RX1  
  117.                            
  118.     set_tris_d(0x00);      //    RD0   -->  OUT E
  119.                            //    RD1   -->  OUT RS
  120.                            //    RD2   -->  OUT RW
  121.                            //    RD3   -->  
  122.                            //    RD4   --> OUT D4  
  123.                            //    RD5   --> OUT D5                
  124.                            //    RD6   --> OUT D6  
  125.                            //    RD7   --> OUT D7                        
  126.                            
  127.                            
  128.  
  129.    lcd_init();         //inicializa lcd
  130.    delay_ms(200);
  131.    printf(lcd_putc,"\fLCDInicializado");
  132.    delay_ms(500);
  133.    display();
  134.    delay_ms(1000);
  135.    
  136.    
  137.    setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
  138.    enable_interrupts(INT_TIMER1);
  139.    disable_interrupts(INT_RB);
  140.    enable_interrupts(int_ext);
  141.    ext_int_edge (H_TO_L);
  142.    enable_interrupts(int_rda);
  143.    enable_interrupts(GLOBAL);
  144.    
  145.    
  146.    delay_ms(500);
  147.    display();
  148.    delay_ms(1000);
  149.    printf(lcd_putc, "\fRv Dato1");
  150.    printf(lcd_putc, "\nRv Dato2");
  151.      
  152.    while(1)
  153.    {
  154.    if(actualiza==1)
  155.       {
  156.       printf(lcd_putc, "\fRv Dato1 %c %d", dato1,dato1);
  157.       printf(lcd_putc, "\nRv Dato2 %c %d", dato2,dato2);
  158.       actualiza=0;
  159.       }
  160.    }
  161.    
  162.    
  163. }




El fichero #include<lcd_D.c>






Código: C
  1. ///////////////////////////////////////////////////////////////////////////
  2. ////                             LCDD.C                                ////
  3. ////                 Driver for common LCD modules                     ////
  4. ////                                                                   ////
  5. ////  lcd_init()   Must be called before any other function.           ////
  6. ////                                                                   ////
  7. ////  lcd_putc(c)  Will display c on the next position of the LCD.     ////
  8. ////                     The following have special meaning:           ////
  9. ////                      \f  Clear display                            ////
  10. ////                      \n  Go to start of second line               ////
  11. ////                      \b  Move back one position                   ////
  12. ////                                                                   ////
  13. ////  lcd_gotoxy(x,y) Set write position on LCD (upper left is 1,1)    ////
  14. ////                                                                   ////
  15. ////  lcd_getc(x,y)   Returns character at position x,y on LCD         ////
  16. ////                                                                   ////
  17. ///////////////////////////////////////////////////////////////////////////
  18. ////        (C) Copyright 1996,2003 Custom Computer Services           ////
  19. //// This source code may only be used by licensed users of the CCS C  ////
  20. //// compiler.  This source code may only be distributed to other      ////
  21. //// licensed users of the CCS C compiler.  No other use, reproduction ////
  22. //// or distribution is permitted without written permission.          ////
  23. //// Derivative programs created using this software in object code    ////
  24. //// form are not restricted in any way.                               ////
  25. ///////////////////////////////////////////////////////////////////////////
  26.  
  27. // As defined in the following structure the pin connection is as follows:
  28. //     D0  enable
  29. //     D1  rs
  30. //     D2  rw
  31. //     D4  D4
  32. //     D5  D5
  33. //     D6  D6
  34. //     D7  D7
  35. //
  36. //   LCD pins D0-D3 are not used and PIC D3 is not used.
  37.  
  38. // Un-comment the following define to use port B
  39. //#define use_portb_lcd TRUE
  40. //#include <16f876.h>
  41. #use delay (clock=4000000)
  42. struct lcd_pin_map {                 // This structure is overlayed
  43.            BOOLEAN enable;           // on to an I/O port to gain
  44.            BOOLEAN rs;               // access to the LCD pins.
  45.            BOOLEAN rw;               // The bits are allocated from
  46.            BOOLEAN unused;           // low order up.  ENABLE will
  47.            int     data : 4;         // be pin B0.
  48.         } lcd;
  49.  
  50.  
  51. #if defined(__PCH__)
  52. #if defined use_portb_lcd
  53.    #byte lcd = 0xF82                  // 0xF81-->b  0xF82->c??  This puts the entire structure
  54. #else
  55.    #byte lcd = 0xF83                   // This puts the entire structure
  56. #endif
  57. #else
  58. #if defined use_portb_lcd
  59.   #byte lcd = 7                  // on to port c (at address 7)   on to port B (at address 6)
  60. #else
  61.  #byte lcd = 8                 // on to port D (at address 8)
  62. #endif
  63. #endif
  64.  
  65. #if defined use_portb_lcd
  66.    #define set_tris_lcd(x) set_tris_c(x)
  67. #else
  68.   #define set_tris_lcd(x) set_tris_d(x)
  69. #endif
  70.  
  71.  
  72. #define lcd_type 2           // 0=5x7, 1=5x10, 2=2 lines
  73. #define lcd_line_two 0x40    // LCD RAM address for the second line
  74.  
  75.  
  76. BYTE const LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2), 0xc, 1, 6};
  77.                              // These bytes need to be sent to the LCD
  78.                              // to start it up.
  79.  
  80.  
  81.                              // The following are used for setting
  82.                              // the I/O port direction register.
  83.  
  84. struct lcd_pin_map const LCD_WRITE = {0,0,0,0,0}; // For write mode all pins are out
  85. struct lcd_pin_map const LCD_READ = {0,0,0,0,15}; // For read mode data pins are in
  86.  
  87.  
  88.  
  89. BYTE lcd_read_byte() {
  90.       BYTE low,high;
  91.       set_tris_lcd(LCD_READ);
  92.       lcd.rw = 1;
  93.       delay_cycles(1);
  94.       lcd.enable = 1;
  95.       delay_cycles(1);
  96.       high = lcd.data;
  97.       lcd.enable = 0;
  98.       delay_cycles(1);
  99.       lcd.enable = 1;
  100.       delay_us(1);
  101.       low = lcd.data;
  102.       lcd.enable = 0;
  103.       set_tris_lcd(LCD_WRITE);
  104.       return( (high<<4) | low);
  105. }
  106.  
  107.  
  108. void lcd_send_nibble( BYTE n ) {
  109.       lcd.data = n;
  110.       delay_cycles(1);
  111.       lcd.enable = 1;
  112.       delay_us(2);
  113.       lcd.enable = 0;
  114. }
  115.  
  116.  
  117. void lcd_send_byte( BYTE address, BYTE n ) {
  118.  
  119.       lcd.rs = 0;
  120.       while ( bit_test(lcd_read_byte(),7) ) ;
  121.       lcd.rs = address;
  122.       delay_cycles(1);
  123.       lcd.rw = 0;
  124.       delay_cycles(1);
  125.       lcd.enable = 0;
  126.       lcd_send_nibble(n >> 4);
  127.       lcd_send_nibble(n & 0xf);
  128. }
  129.  
  130.  
  131. void lcd_init() {
  132.     BYTE i;
  133.     set_tris_lcd(LCD_WRITE);
  134.     lcd.rs = 0;
  135.     lcd.rw = 0;
  136.     lcd.enable = 0;
  137.     delay_ms(15);
  138.     for(i=1;i<=3;++i) {
  139.        lcd_send_nibble(3);
  140.        delay_ms(5);
  141.     }
  142.     lcd_send_nibble(2);
  143.     for(i=0;i<=3;++i)
  144.        lcd_send_byte(0,LCD_INIT_STRING[i]);
  145. }
  146.  
  147.  
  148. void lcd_gotoxy( BYTE x, BYTE y) {
  149.    BYTE address;
  150.  
  151.    if(y!=1)
  152.      address=lcd_line_two;
  153.    else
  154.      address=0;
  155.    address+=x-1;
  156.    lcd_send_byte(0,0x80|address);
  157. }
  158.  
  159. void lcd_putc( char c) {
  160.    switch (c) {
  161.      case '\f'   : lcd_send_byte(0,1);
  162.                    delay_ms(2);
  163.                                            break;
  164.      case '\n'   : lcd_gotoxy(1,2);        break;
  165.      case '\b'   : lcd_send_byte(0,0x10);  break;
  166.      default     : lcd_send_byte(1,c);     break;
  167.    }
  168. }
  169.  
  170. char lcd_getc( BYTE x, BYTE y) {
  171.    char value;
  172.  
  173.     lcd_gotoxy(x,y);
  174.     while ( bit_test(lcd_read_byte(),7) ); // wait until busy flag is low
  175.     lcd.rs=1;
  176.     value = lcd_read_byte();
  177.     lcd.rs=0;
  178.     return(value);
  179. }



Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: Cominicacion SERIAL RS232 con PC y iPad
« Respuesta #4 en: 06 de Febrero de 2014, 13:13:35 »
que bueno que funcionó :-/ :-/
"Nada es imposible, no si puedes imaginarlo"