UART Transmitting Problem

Discussion in 'Embedded Systems and Microcontrollers' started by winson, Dec 3, 2008.

  1. winson

    Thread Starter Member

    Dec 3, 2008
    23
    0
    Hello everybody,

    I was trying to write a UART program to send out few bytes of data by using PIC16F877A, CCS C compiler, MPLAB IDE, MPLAB SIM. The problem of my program is the code fail to transmit out the data to pin RC6 of Port C. So far i am just use MPLAB SIM to simulate my program and using Watch window to monitor all the register and symbol. To simulate the program i was pressing the "step into" button, and the first 2 bytes of data was load to TXREG and TSR but after that not able to load the third bytes of data beacuse TXIF flag is not set, this showing that TXREG was still full and the data look like "jam" already. from the Watch window the Port C does not show any value(0x00), i also try to press "animate" and let the program run for few minutes but still no data was show on Port C. Anybody can help to solve the problem or give some suggestion?

    Below is my program,

    #include <16F877A.h>

    //***** Function prototype ******//
    void init(void);
    void transmit (void);
    void transmit_empty (void);

    //*****variable declaration******//
    unsigned char TXSTA,RCSTA,SPBRG,INTCON,PIR1,PIE1,TXREG,PORTC,TRISC;
    int count;

    //****** define sfr address *****//
    #byte TXSTA = 0x98
    #byte RCSTA = 0x18
    #byte SPBRG = 0x99
    #byte PIE1 = 0x8c
    #byte INTCON = 0x8b
    #byte TXREG = 0x19
    #byte RCREG = 0x1A
    #byte PIR1 = 0x0c
    #byte PORTC = 0x07
    #byte TRISC = 0x87



    char ucIPOD_packet_origin[2][7]={
    {0xff,0x55,0x03,0x02,0x00,0x01,0xfa}, /* " play/pause " */
    {0xff,0x55,0x03,0x02,0x00,0x08,0xf3} /* " fwd " */
    };


    /********************************************************************
    FUNCTION : main()
    DESCRIPTION : main loop
    INPUT : Null
    OUTPUT : Null
    CREATE :
    DATE : 07/10/08
    ********************************************************************/
    void main()
    {
    init ();
    transmit ();
    while (1)
    {
    }
    }


    /********************************************************************
    FUNCTION : init()
    DESCRIPTION : sfr initialization
    INPUT : Null
    OUTPUT : Null
    CREATE :
    DATE : 07/10/08
    ********************************************************************/
    void init ()
    {
    PORTC = 0x00; //0b 0000 0000 //Clear Port C

    TRISC = 0xFF; //0b 1111 1111 //Enable USART Transmitter

    TXSTA = 0x24; //0b 0010 0100 //Transmit Enable //SYNC = 0, Asynchronous Mode

    RCSTA = 0x90; //0b 1001 0000 //Receive Enable //Serial Port Enable

    SPBRG = 0x40; //0b 0100 0000 //SPBRG = 64, Baudrate = 19.231KBAUD, High Baud Rate

    INTCON = 0x00; //0b 0000 0000 //Disable Global and Peripheral Interrupt

    PIR1 = 0x10; //0b 0001 0000 //USART transmit/Receive Interrupt Flag bit

    PIE1 = 0x00; //0b 0000 0000; //Individual enable bits for the peripheral interrupts.

    count = 0;
    }


    /********************************************************************
    FUNCTION : transmit()
    DESCRIPTION : uart transmission
    INPUT : Null
    OUTPUT : Null
    CREATE :
    DATE : 07/10/08
    ********************************************************************/
    void transmit ()
    {
    while (1) //Keep on looping
    {
    if (PIR1 == 0x10) //Check TXIF flag
    { //If TXREG is empty

    TXREG = ucIPOD_packet_origin[0][count]; //Load data

    count++; //Counter increment
    }
    }
    }

    [/code]

    I am really no idea why such condition happen, everything look like set properly but it is not run.
    Is it my simualtion methods is wrong or my code was having problem?

    Any suggestion is appreciate.

    Thanks
     
  2. winson

    Thread Starter Member

    Dec 3, 2008
    23
    0
    I already successfully simulate my UART program by using Uart1 IO tab in MPLAB SIM. It is under Debugger > Settings > Uart1 IO. In Uart1 IO tab just click "Enable Uart IO" and select "Window" as output then press ok. After back to MPLAB main screen a "SIM Uart1" tab will exist in the output window. Press "run" to simulate the UART program and the transmitted data will show in output window as ASCII character, just have to refer ASCII table and verify the transmitted data.

    Thanks everybody!
     
  3. winson

    Thread Starter Member

    Dec 3, 2008
    23
    0
    Hi everybody.

    I already try my UART transmiting program on the real hardware with a breadboard but the result is not successful. I was using an oscilloscope to trace the signal that send out from the USART Tx pin of 16F877A but the scope does not show any pulses and just maintain at 0V. This program is run well in MPLAB Simulation.

    The peripheral circuitry of the 877A is simple, i was put the 20MHz crystal's leg to OSC1 and OSC2 with a 22pF capacitor from each crystal leg to ground. I connect 5V(3A) supply to the two VDD pin of 877A and 0V to the two VSS pin finally i also connect 5V supply to the MCLR pin for the reset purpose and i also try to put a 20k resistor to the VDD to limit the current but the result is still the same. This is all the thing that i do, but the scope does not show any digital pulses. Anybody can give me some suggestion or alert me some of the error that i done?
    My latest version of code is show below, Thanks...

    Code ( (Unknown Language)):
    1.  
    2. #include <16F877A.h>
    3.  
    4. //***** Function prototype ******//
    5. void init(void);
    6. void transmit (void);
    7. void transmit_empty (void);
    8.  
    9. //*****variable declaration******//
    10. unsigned char TXSTA,RCSTA,SPBRG,INTCON,PIR1,PIE1,TXREG,PORTC,TRISC;
    11. int count, next;
    12.  
    13. //****** define sfr address *****//
    14. #byte TXSTA        =      0x98
    15. #byte RCSTA        =    0x18
    16. #byte SPBRG        =    0x99
    17. #byte PIE1        =    0x8c
    18. #byte INTCON        =    0x8b
    19. #byte TXREG        =    0x19
    20. #byte RCREG        =    0x1A
    21. #byte PIR1        =    0x0c
    22. #byte PORTC        =    0x07
    23. #byte TRISC        =     0x87
    24. #bit  TXIF        =    PIR1.4
    25. #bit  TRMT        =    TXSTA.1
    26.  
    27.  
    28.  
    29.  
    30. char remote_command_basic[3][10]=
    31. {
    32.     {0xff,0x55,0x06,0x02,0x00,0x01,0x00,0x00,0x00,0xf7},    //0 Play/Pause
    33.     {0xff,0x55,0x06,0x02,0x00,0x01,0x00,0x00,0x00,0xf7},    //1 Play/Pause
    34.     {0xff,0x55,0x06,0x02,0x00,0x00,0x00,0x00,0x00,0xf8}        //2 Release
    35. };
    36.  
    37.    
    38. /********************************************************************
    39. FUNCTION       : main()
    40. DESCRIPTION : main loop
    41. ********************************************************************/
    42. void main()
    43. {
    44.     init ();
    45.     transmit ();
    46.     while (1)
    47.     {
    48.     }
    49. }
    50.  
    51.  
    52. /********************************************************************
    53. FUNCTION       : init()
    54. DESCRIPTION : sfr initialization
    55. ********************************************************************/
    56. void init ()
    57. {
    58.    
    59.     PORTC = 0x00;    //0b 0000 0000        //Clear Port C
    60.    
    61.     TRISC = 0xFF;    //0b 1111 1111        //Enable USART Transmitter and Receiver
    62.    
    63.     TXSTA = 0x24;    //0b 0010 0100        //Transmit Enable    //SYNC = 0, Asynchronous Mode
    64.     RCSTA = 0x90;    //0b 1001 0000        //Receive Enable    //Serial Port Enable
    65.    
    66.     SPBRG = 0x40;    //0b 0100 0000        //SPBRG = 64, Baudrate = 19.231KBAUD, High Baud Rate
    67.                                                                                    
    68.     INTCON = 0x00;    //0b 0000 0000        //Global and Peripheral Interrupt Disable
    69.  
    70.     PIR1 = 0x10;    //0b 0001 0000        //USART transmit/Receive Interrupt Flag bit
    71.  
    72.     PIE1 = 0x00;    //0b 0000 0000;        //Individual enable bits for the peripheral interrupts.
    73.                    
    74.     count = 0;
    75.     next = 0;
    76. }
    77.  
    78.  
    79. /********************************************************************
    80. FUNCTION       : transmit()
    81. DESCRIPTION : uart transmission
    82. ********************************************************************/
    83. void transmit ()
    84. {
    85.     while (1)                                //Keep on looping
    86.     {
    87.         if (TXIF == 1)                    //Check TXIF flag            
    88.         {                                    //If TXREG is empty
    89.            
    90.             TXREG = remote_command_basic[next][count];    //Load data
    91.             delay_cycles( 1 );                //NOP
    92.             delay_cycles( 1 );        
    93.             delay_cycles( 1 );
    94.            
    95.             if (count > 8)                    //After 10th byte
    96.             {
    97.                 next++;                        //Next packet
    98.                 if (next > 2)                //After 3rd packet
    99.                 {
    100.                     return;                    //Return to main()
    101.                 }
    102.             }
    103.             count++;                        //Counter increment
    104.             if (count > 9)                    //After 10th byte
    105.             {
    106.                 count = 0;                    //Reset counter
    107.             }
    108.         }        //End first if loop
    109.     }        //End while loop
    110. }
    111.  
    112.  
    113.  
     
  4. Alberto

    Active Member

    Nov 7, 2008
    169
    36
    You must initialise the uart registers before using it.
    Code ( (Unknown Language)):
    1. RCSTA = $90 ' Enable serial port & continuous receive
    2. TXSTA = $24 ' Enable transmit, BRGH = 1
    3. SPBRG = 129 ' 9600 Baud @ 20MHz, 0,16%
    4.  
    ($ sign=Hex)

    Sorry but I don't know how to use them in C.

    Alberto
     
  5. winson

    Thread Starter Member

    Dec 3, 2008
    23
    0
    Thanks for your reply!:)

    Yup, i did do the thing that you mention like below:

    Code ( (Unknown Language)):
    1.  
    2. //****** define sfr address *****//
    3. #byte TXSTA        =      0x98
    4. #byte RCSTA        =    0x18
    5. #byte SPBRG        =    0x99
    6. #byte PIE1        =    0x8c
    7. #byte INTCON        =    0x8b
    8. #byte TXREG        =    0x19
    9. #byte RCREG        =    0x1A
    10. #byte PIR1        =    0x0c
    11. #byte PORTC        =    0x07
    12. #byte TRISC        =     0x87
    13. #bit  TXIF        =    PIR1.4
    14. #bit  TRMT        =    TXSTA.1
    15.  
    Code ( (Unknown Language)):
    1.  
    2. SPBRG = 0x40;    //0b 0100 0000        //SPBRG = 64, Baudrate = 19.231KBAUD, High Baud Rate
    3.  
    4.  
    Anyway thanks for your attention!
    Anybody can give me some suggestion? I'm really no idea about this project.

    Any comments will be appreciate.
    Thank you
     
  6. winson

    Thread Starter Member

    Dec 3, 2008
    23
    0
    The program is able to work!

    After i added "#fuses hs, nowdt, nolvp, noprotect" to my code, and by a digital oscilloscope i can see the data send out nicely.
     
  7. vk4tec

    New Member

    Feb 19, 2009
    4
    0
    Yes you need to tell the system that

    You have a HS oscillator
    <this stops the MCU from being clocked>

    Dont' use the watch dog timer
    <this can just keep reseting and the program wont run>

    Dont' use the low voltage programming
    <can stop the program from even being loaded>

    and no code protect
    <thats your choice>

    It is also as i found, needed that you watch you don't fill up the receive buffer.

    Turn off the receiver when you are done.

    Get your baud rate correct for your OSC, and be sure the pin is configured.

    Otherwise the buffer will fill after 3 characters and the USART will stall if you don't manage it.

    Andrew
     
    Last edited: Feb 19, 2009
  8. winson

    Thread Starter Member

    Dec 3, 2008
    23
    0
    Hi Andrew,:)

    Thanks for your opinions, so is it mean that the receive buffer will automatic fill up with data when i did not use it?
     
Loading...