how to write/read from USART Rx/Tx

Discussion in 'Embedded Systems and Microcontrollers' started by tuanvoi, Mar 16, 2009.

  1. tuanvoi

    Thread Starter Active Member

    Oct 31, 2008
    56
    0
    Hi all,
    I've read the data sheet for my PIC18F4550. It explains me everything (i.e. how turn on USART, how to set mode "synchronous, a synchronous"...). However, one part that I think is not clearly explained is how to read/write the Tx/Rx pins. Could you please help me with this write/read from the pins Rx/Tx (I prefer MPLAB C compiler)? For example, If I want to write '1' to the Tx, how do I use the method? Or how do I read from pin Rx?
    Thank you!
    Tom
     
    Last edited: Mar 16, 2009
  2. kbupnorth

    New Member

    Sep 8, 2008
    4
    0
    Somebody correct me if I'm wrong, but if I understand what your asking is you want to read/write to the pin as if it is a input/output pin. When the PIC is configured for USART, signals on the TX or RX pins are buffered into the TXREG or RXREG and read/write as a byte.
     
  3. tuanvoi

    Thread Starter Active Member

    Oct 31, 2008
    56
    0
    can somebody please help? Thanks 'kbupnorth'
     
  4. thatoneguy

    AAC Fanatic!

    Feb 19, 2009
    6,357
    718
    Here is a test snippet to test USART Comms on a 16F877A


    Code ( (Unknown Language)):
    1.  
    2. [FONT=Arial][SIZE=2][COLOR=#cccccc] [/COLOR][COLOR=#eeeeee][/COLOR]
    3. [COLOR=#eeeeee] 3: [/COLOR]#include[SIZE=+1][COLOR=BLUE]<[/COLOR][/SIZE]pic[SIZE=+1][COLOR=BLUE][B].[/B][/COLOR][/SIZE]h[SIZE=+1][COLOR=BLUE]>[/COLOR][/SIZE]              [COLOR=GREEN][I]//include MCU head file
    4. [COLOR=#eeeeee] 4: [/COLOR][/I][/COLOR] __CONFIG[SIZE=+1][COLOR=BLUE][B]([/B][/COLOR][/SIZE][COLOR=PINK]0x1832[/COLOR][SIZE=+1][COLOR=BLUE][B])[/B][/COLOR][/SIZE][SIZE=+1][COLOR=BLUE][B];[/B][/COLOR][/SIZE]        
    5. [COLOR=#cccccc] 5: [/COLOR][COLOR=GREEN][I]//THE configure of MCU,watchdog OFF,electrify delay OPEN,power down check OFF,
    6. [COLOR=#eeeeee] 6: [/COLOR][/I][/COLOR][COLOR=GREEN][I]//LOW power programme OFF,encrypt,4M crystal HS surge.
    7. [COLOR=#eeeeee] 7: [/COLOR][/I][/COLOR]
    8. [COLOR=#eeeeee] 8: [/COLOR][COLOR=GREEN][I]//---------------------------------------------
    9. [COLOR=#eeeeee] 9: [/COLOR][/I][/COLOR][COLOR=GREEN][I]//main program
    10. [COLOR=#cccccc]10: [/COLOR][/I][/COLOR][COLOR=RED][B]void[/B][/COLOR] main[SIZE=+1][COLOR=BLUE][B]([/B][/COLOR][/SIZE][SIZE=+1][COLOR=BLUE][B])[/B][/COLOR][/SIZE]
    11. [COLOR=#eeeeee]11: [/COLOR] [SIZE=+1][COLOR=BLUE][B]{[/B][/COLOR][/SIZE]
    12. [COLOR=#eeeeee]12: [/COLOR]  TRISC[SIZE=+1][COLOR=BLUE]=[/COLOR][/SIZE]0XFF[SIZE=+1][COLOR=BLUE][B];[/B][/COLOR][/SIZE]                 [COLOR=GREEN][I]// set C PORT all OUTPUT
    13. [COLOR=#eeeeee]13: [/COLOR][/I][/COLOR]  SPBRG[SIZE=+1][COLOR=BLUE]=[/COLOR][/SIZE]0XC[SIZE=+1][COLOR=BLUE][B];[/B][/COLOR][/SIZE]                  [COLOR=GREEN][I]//set baud rate 19200BPS
    14. [COLOR=#eeeeee]14: [/COLOR][/I][/COLOR]  TXSTA[SIZE=+1][COLOR=BLUE]=[/COLOR][/SIZE][COLOR=PINK]0X24[/COLOR][SIZE=+1][COLOR=BLUE][B];[/B][/COLOR][/SIZE]                 [COLOR=GREEN][I]//enable USART,set band rate is high
    15. [COLOR=#cccccc]15: [/COLOR][/I][/COLOR]  RCSTA[SIZE=+1][COLOR=BLUE]=[/COLOR][/SIZE][COLOR=PINK]0X90[/COLOR][SIZE=+1][COLOR=BLUE][B];[/B][/COLOR][/SIZE]                 [COLOR=GREEN][I]//enable USART continue receive
    16. [COLOR=#eeeeee]16: [/COLOR][/I][/COLOR]  RCIE[SIZE=+1][COLOR=BLUE]=[/COLOR][/SIZE][COLOR=PINK]0X1[/COLOR][SIZE=+1][COLOR=BLUE][B];[/B][/COLOR][/SIZE]                   [COLOR=GREEN][I]//enable receive interrupt
    17. [COLOR=#eeeeee]17: [/COLOR][/I][/COLOR]  GIE[SIZE=+1][COLOR=BLUE]=[/COLOR][/SIZE][COLOR=PINK]0X1[/COLOR][SIZE=+1][COLOR=BLUE][B];[/B][/COLOR][/SIZE]                    [COLOR=GREEN][I]// enable general interrupt
    18. [COLOR=#eeeeee]18: [/COLOR][/I][/COLOR]  PEIE[SIZE=+1][COLOR=BLUE]=[/COLOR][/SIZE][COLOR=PINK]0X1[/COLOR][SIZE=+1][COLOR=BLUE][B];[/B][/COLOR][/SIZE]                   [COLOR=GREEN][I]//enable outside interrupt
    19. [COLOR=#eeeeee]19: [/COLOR][/I][/COLOR]  [COLOR=RED][B]while[/B][/COLOR][SIZE=+1][COLOR=BLUE][B]([/B][/COLOR][/SIZE][COLOR=BROWN]1[/COLOR][SIZE=+1][COLOR=BLUE][B])[/B][/COLOR][/SIZE]                    [COLOR=GREEN][I]// wait for interrupt
    20. [COLOR=#cccccc]20: [/COLOR][/I][/COLOR]   [SIZE=+1][COLOR=BLUE][B]{[/B][/COLOR][/SIZE][SIZE=+1][COLOR=BLUE][B];[/B][/COLOR][/SIZE][SIZE=+1][COLOR=BLUE][B]}[/B][/COLOR][/SIZE]
    21. [COLOR=#eeeeee]21: [/COLOR]  [SIZE=+1][COLOR=BLUE][B]}[/B][/COLOR][/SIZE]
    22. [COLOR=#eeeeee]22: [/COLOR]
    23. [COLOR=#eeeeee]23: [/COLOR][COLOR=GREEN][I]//--------------------------------------------
    24. [COLOR=#eeeeee]24: [/COLOR][/I][/COLOR][COLOR=GREEN][I]//interrupt function
    25. [COLOR=#cccccc]25: [/COLOR][/I][/COLOR][COLOR=RED][B]void[/B][/COLOR] interrupt usart[SIZE=+1][COLOR=BLUE][B]([/B][/COLOR][/SIZE][COLOR=RED][B]void[/B][/COLOR][SIZE=+1][COLOR=BLUE][B])[/B][/COLOR][/SIZE]
    26. [COLOR=#eeeeee]26: [/COLOR]  [SIZE=+1][COLOR=BLUE][B]{[/B][/COLOR][/SIZE]
    27. [COLOR=#eeeeee]27: [/COLOR]   [COLOR=RED][B]if[/B][/COLOR][SIZE=+1][COLOR=BLUE][B]([/B][/COLOR][/SIZE]RCIE[SIZE=+1][COLOR=BLUE][SIZE=+1][COLOR=BLUE]&[/COLOR][/SIZE][SIZE=+1][COLOR=BLUE]&[/COLOR][/SIZE][/COLOR][/SIZE]RCIF[SIZE=+1][COLOR=BLUE][B])[/B][/COLOR][/SIZE]            [COLOR=GREEN][I]//judge if COMM receive interrupt
    28. [COLOR=#eeeeee]28: [/COLOR][/I][/COLOR]     [SIZE=+1][COLOR=BLUE][B]{[/B][/COLOR][/SIZE]
    29. [COLOR=#eeeeee]29: [/COLOR]      TXREG[SIZE=+1][COLOR=BLUE]=[/COLOR][/SIZE]RCREG[SIZE=+1][COLOR=BLUE][B];[/B][/COLOR][/SIZE]           [COLOR=GREEN][I]//send back  the receive data
    30. [COLOR=#cccccc]30: [/COLOR][/I][/COLOR]     [SIZE=+1][COLOR=BLUE][B]}[/B][/COLOR][/SIZE]
    31. [COLOR=#eeeeee]31: [/COLOR]   [SIZE=+1][COLOR=BLUE][B]}[/B][/COLOR][/SIZE]
    32. [/SIZE][/FONT]

     
  5. tuanvoi

    Thread Starter Active Member

    Oct 31, 2008
    56
    0
    When the Rx receives an 8bit data which is saved in register 'RCREG'. How do I read(what method) so that I can convert it back to binary.
    And also how do I write to Tx 'TXREG' register?
    Please correct me if I'm wrong. If I want to write 00000001 to TXREG. I will write TXREG = 00000001?
    And on the receiver side Rx, how to I read the '00000001'? Thank you.
     
  6. thatoneguy

    AAC Fanatic!

    Feb 19, 2009
    6,357
    718
    You need to define a variable to get the contents of the RX Register.

    In the example above, it simply retransmits anything received.

    Look at the datasheet for the IC to determine the serial properties, speed, byte size, buffer size, start/stop bits, parity, etc.

    When data is received, it will create an interrupt, as seen above, at which time you can copy the data to a variable, test it for a value, etc. To send data, you need to simply assign the data to TX Register (as RX is above, you could use a different variable as source). You need to be sure the size of data is correct, which is shown in data sheet, configuration options.
     
  7. tuanvoi

    Thread Starter Active Member

    Oct 31, 2008
    56
    0
    The 'variable' you've mentioned above, is it in 'char' or it depends on what type of data you define for Tx/Rx? If the variable type is only in 'char', how could I convert it to 'int' ?
    I've read my datasheet saying that I can only send 1 byte at a time. When a byte sent, the interupt will occur to indicate a byte received. My problem is how to assign '00000001' (is it just TXREG = 00000001, if I want to send 1 in decimal?) to the Tx register (TXREG) to send. On the receive side, how can I test if 1 in decimal has been sent? Could you please explain to me 'thatoneguy'?
     
  8. thatoneguy

    AAC Fanatic!

    Feb 19, 2009
    6,357
    718
    The PIC won't transmit until the size of transmit buffer is full. It will then send a start bit, data, stop bit typically, depends on your configuration.

    A 0b00000001 wouldn't appear in the receive buffer until a start bit, 7 '0' data, 1 '1' data, then stop bit. Those would have to be received in a complete frame at the baud rate selected.

    If you are only going to be looking for a single bit change, hi/low, then either set up an interrupt on change, or poll that pin for change.

    Use an unsigned char in C for the variable if you are using 8 bit bytes, otherwise unsigned int, and lower speeds so errors can be analyzed. A 20MHz clock has about 1% clock errors in at certain data rates, such as 19,200.
     
    Last edited: Mar 17, 2009
  9. tuanvoi

    Thread Starter Active Member

    Oct 31, 2008
    56
    0
    Here is my code
    Code ( (Unknown Language)):
    1.  
    2. #include <p18f4550.h>
    3. #include <usart.h>
    4. #include <delays.h>
    5. #pragma config WDT=OFF,LVP=OFF,FOSC=HSPLL_HS,PLLDIV=5,CPUDIV=OSC2_PLL3 //run with external oscillator
    6.  
    7. void tryAgain_0(void)
    8. {
    9.    while(1)
    10.    {
    11.     if(!(BusyUSART()))
    12.     {
    13.      
    14.      WriteUSART('1');//transmit char '1'
    15.     }
    16.     if (PIR1bits.RCIF == 1) // check if this bit is set meaning a byte received
    17.      {
    18.       char c = ReadUSART();//return a received byte in buffer, and put in parameter c
    19.       if(c == '1')
    20.        PORTAbits.RA0 = 1;
    21.       else
    22.        PORTAbits.RA0 = 0;
    23.      }
    24.    }
    25. }
    26. void tryAgain_1(void)
    27. {
    28.  while(1)
    29.    {
    30.     if(!(BusyUSART()))
    31.     {
    32.      
    33.      WriteUSART('0');//transmit char '0'
    34.     }
    35.     if (PIR1bits.RCIF == 1) // check if this bit is set, meaning a byte received
    36.      {
    37.       char c = ReadUSART();//return a received byte in buffer, and put in parameter c
    38.       if(c == '1')
    39.        PORTAbits.RA0 = 1;
    40.       else
    41.        PORTAbits.RA0 = 0;
    42.      }
    43.    }
    44. }
    45. void main(void)
    46. {
    47. //USART setup
    48. OpenUSART(USART_TX_INT_OFF & USART_RX_INT_OFF & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_HIGH & USART_ADDEN_OFF, 25);
    49. /*
    50. USART_TX_INT_OFF = 0b00000000  // Transmit interrupt off
    51. USART_RX_INT_OFF = 0b00000000  // Receive interrupt off
    52. USART_ASYNCH_MODE = 0b00000000  // Asynchronous mode
    53. USART_EIGHT_BIT = 0b11111101  // 8-bit data
    54. USART_CONT_RX = 0b00001000  // Continuous reception
    55. USART_BRGH_HIGH = 0b11111111  // High baud rate
    56. USART_ADDEN_OFF = 0b11011111
    57. SPBRG = 25
    58. */
    59. baudUSART(BAUD_IDLE_CLK_HIGH & BAUD_8_BIT_RATE & BAUD_WAKEUP_OFF & BAUD_AUTO_OFF & BAUD_IDLE_RX_PIN_STATE_HIGH & BAUD_IDLE_TX_PIN_STATE_HIGH);
    60. /*
    61. BAUD_IDLE_CLK_HIGH = 0b00010000  // idle state for clock is a high level
    62. BAUD_8_BIT_RATE = 0b00000000  // 8-bit baud generation rate
    63. BAUD_WAKEUP_OFF = 0b00000000  // RX pin not monitored
    64. BAUD_IDLE_RX_PIN_STATE_HIGH = 0b11011111  // idle state for RX pin is high level
    65. BAUD_IDLE_TX_PIN_STATE_HIGH = 0b11101111  // idle state for TX pin is high level
    66. */
    67. ADCON0bits.ADON=0;
    68. ADCON1 = 0x07;
    69. //CMCON = 0x07;
    70. TRISA = 0x00;
    71. /* To set up USART */
    72. RCSTAbits.SPEN = 1;
    73. PORTCbits.RC7 = 1; //input coming from Rx pin
    74. PORTCbits.RC0 = 0; //output meaning write to Tx pin
    75. //TXSTA = 0b01101110; //configurations for transmit register
    76. //RCSTA = 0b00110000; //configurations for receive register
    77. TRISB = 0xFF;
    78.  if(PORTBbits.RB0 == 1)
    79.   {
    80.     while(1)
    81.    {
    82.     if(!(BusyUSART()))
    83.     {
    84.      
    85.      WriteUSART('1');//transmit char '1'
    86.     }
    87.     if (PIR1bits.RCIF == 1) // check if this bit is set meaning a byte received
    88.      {
    89.       char c = ReadUSART();//return a received byte in buffer, and put in parameter c
    90.       if(c == '1')
    91.        PORTAbits.RA0 = 1;
    92.       else
    93.        PORTAbits.RA0 = 0;
    94.      }
    95.        
    96.     else if((BusyUSART()) && PIR1bits.RCIF !=0)
    97.     {
    98.      Delay10KTCYx(100);//delay approximately 1s    
    99.      tryAgain_0();
    100.     }
    101.    }    
    102.   }  
    103.  
    104.  else if (PORTBbits.RB0 == 0)
    105.    while(1)
    106.    {
    107.     if(!(BusyUSART()))
    108.     {
    109.      
    110.      WriteUSART('0');//transmit char '0'
    111.     }
    112.     if (PIR1bits.RCIF == 1) // check if this bit is set, meaning a byte received
    113.      {
    114.       char c = ReadUSART();//return a received byte in buffer, and put in parameter c
    115.       if(c == '1')
    116.        PORTAbits.RA0 = 1;
    117.       else
    118.        PORTAbits.RA0 = 0;
    119.      }
    120.        
    121.     else if((BusyUSART()) && PIR1bits.RCIF !=0)
    122.     {
    123.      Delay10KTCYx(100);//delay approximately 1s    
    124.      tryAgain_1();
    125.     }
    126.    }    
    127.  
    128.    
    129. }
    130.  
    Could you please check if it is correct?
    The purpose of this code is to turn on or off PORTAbits.RA0 depending on what is received on the Rx pin (if char '1' set PORTAbits.RA0 = 1, and if char '0' set PORTAbits.RA0 = 0). Thank you!
     
  10. thatoneguy

    AAC Fanatic!

    Feb 19, 2009
    6,357
    718
    What is the PIC communicating with?

    All serial settings need to match on both devices. When that is set up with the configuration flags you have in your program, and the wiring is correct, it works. If not, try running under ICD to see what is being received, or get data and write to an LCD, etc.
     
  11. tuanvoi

    Thread Starter Active Member

    Oct 31, 2008
    56
    0
    Hi thatoneguy,
    I'll use 2 bluetooth devices to connect to Rx/Tx respectively so that the 2 PIC18F4550 can communicate with each other.
    I have a question please!
    If I send char '1' which means '49' in HEX, do I have to convert '1' to HEX so that I can compare the HEX number? If yes, could you please give me the method of converting char to HEX? Thank you.
     
Loading...