UART

Discussion in 'General Electronics Chat' started by Dritech, Oct 27, 2013.

  1. Dritech

    Thread Starter Well-Known Member

    Sep 21, 2011
    756
    5
    Hi all,

    I am using the following code for UART communication between the PC and the 18f microcontroller (on 20MHz). Can someone please tell me why not all characters are being echoed correctly when tested using PuTTY??

    Code ( (Unknown Language)):
    1.  
    2.  
    3. void main(void)
    4. {
    5.     unsigned char dat;
    6.  
    7.     TXSTA = 0X24;
    8.     RCSTA = 0X90;
    9.     SPBRG = 0X81;
    10.  
    11. while(1)
    12.  
    13. {
    14.  
    15. while(PIR1bits.RCIF == 0);
    16.  
    17. dat = RCREG;          
    18.  
    19. TXREG = dat;          
    20.  
    21. while(PIR1bits.TXIF == 0);
    22. }
    23.  
    24. }
     
  2. JohnInTX

    Moderator

    Jun 26, 2012
    2,338
    1,017
    I read your setup for a generic 18F as 9600 baud. Is that correct?
    You do not show that TRISC has been configured. Per the datasheet:
    The SPEN (RCSTA register) and the TRISC<7> bits
    have to be set and the TRISC<6> bit must be cleared
    in order to configure pins RC6/TX/CK and RC7/RX/DT
    as the Universal Synchronous Asynchronous Receiver
    Transmitter.


    Are you setting ALL of the CONFIG bits for the processor AND initializing ALL of the I/O??

    If it echoes single characters but fails on longer strings consider pacing the transmitter i.e. a little delay between characters.

    A subtle problem here is that you have a required 1:1 correspondence between receive time and transmit time due to polling the registers. The added processing time of getting / putting / looping will eventually eat your sack lunch unless there is some delay between transmitted characters.
     
    Last edited: Oct 27, 2013
  3. Dritech

    Thread Starter Well-Known Member

    Sep 21, 2011
    756
    5
    Hi,
    I included the TRIS part but it is still not working. I tested the MAX232 using a multimeter and it is ok. I also shorted pins 2 and 3 of the USB to serial cable and it is also working in order.

    When testing the voltage on the TX and RX pins of the PIC, I am getting 5V on both of them. Is this normal?

    I also tried the code below to test the TX, but it is not working:

    Code ( (Unknown Language)):
    1.  
    2.  
    3. dat = 'm';
    4.  
    5. TXREG = dat;           //dat value is given to TXREG for transmit
    6.  
    7. while(PIR1bits.TXIF == 0); //keep looping till TXIF is high. When it is high it indicated data have been transmitted
    8.  
    9. while(1);
    10.  
    Below are the config settings for a 20MHz Xtal:

    Code ( (Unknown Language)):
    1. #pragma config FOSC  = HSPLL_HS
    2. #pragma config PLLDIV = 5        
    3. #pragma config CPUDIV = OSC1_PLL2
    4. #pragma config USBDIV = 2        
    5. #pragma config FCMEN  = OFF      
    6. #pragma config IESO  = OFF      
    7. #pragma config PWRT  = OFF    
    8. #pragma config BOR    = ON        
    9. #pragma config VREGEN = ON    
    10. #pragma config WDT    = OFF    
    11. #pragma config MCLRE  = ON      
    12. #pragma config LVP    = OFF      
    13. #pragma config ICPRT  = OFF    
    14. #pragma config CP0    = OFF  
    Is the configuration correct please?
     
  4. Dritech

    Thread Starter Well-Known Member

    Sep 21, 2011
    756
    5
    Code ( (Unknown Language)):
    1.   TRISCbits.TRISC6 = 1;
    2.   TRISCbits.TRISC7 = 1;
    Is this how to set TRIS please?
     
  5. JohnInTX

    Moderator

    Jun 26, 2012
    2,338
    1,017
    No. RC6 (TX) must be an output. TRISC6=0.

    I don't know. What is the PIC part number and what kind of oscillator are you using? On first glance, if you are using a 20MHz oscillator, you probably don't want the PLL as the system speed will no longer be 20MHz and your baud rate will be off.

    You can further test your serial link by pulling the PIC and jumpering RC7 and RC6.. If characters are echoed, you know that the MAX232/USB serial cable are working as far as PIC UART.
     
  6. MaxHeadRoom

    Expert

    Jul 18, 2013
    10,493
    2,363
    The Pic micro USART App sheet and the various examples for the 16F, 17F and 18F posted by Microchip's Dave Garbutt specify that although one is input the other an output they are both set for input.
    SetupSerial:
    movlw 0xc0 ; = b'11000000' set tris bits for TX and RX
    iorwf TRISC, F

    I only program in assembly hence the above code.
    I designed around the examples and they work fine?
    Max.
     
  7. Dritech

    Thread Starter Well-Known Member

    Sep 21, 2011
    756
    5
    Thanks for the reply.

    I set them both high since it is stated in the PIC18F4550 datasheet (pg 243).

    I am using the PIC18F4550 with 20MHz.

    So I remove "#pragma config PLLDIV = 5" or "#pragma config CPUDIV = OSC1_PLL2" ?


    Regarding TXSTA.BRGH, shell I set it to high or low speed when using a baud rate of 9600? From the research I did, it shows that setting it to high speed reduces errors.
     
  8. JohnInTX

    Moderator

    Jun 26, 2012
    2,338
    1,017
    Some do and some don't. The paste in blue above was from the 18F452. This is from the 16F887:
    OP: ANSEL.. Check it out.
    Looking at the 18F4550:
    Different again.
    I'm not sure I've used the latter one or why setting the unidirectional TX pin to output would be a problem but.. Moral, read that datasheet.
     
    Dritech likes this.
  9. Dritech

    Thread Starter Well-Known Member

    Sep 21, 2011
    756
    5
    Thanks for replying. Regarding the PLL and the TXSTA.BRGH, how shell I set them please?
     
  10. JohnInTX

    Moderator

    Jun 26, 2012
    2,338
    1,017
    Ahh... for this one HS_PLL with CPU_DIV1:0 = 00 should generate a 20MHz clock. (Ref TABLE2-3, line 1) I don't know what value OSC1_PLL2 sets. Build your code and look at the configuration bits in MPLAB to see or check the compiler documentation. PLL_DIV drives the USB so should not be an issue here. I haven't used the 4550 so just reading the datasheet.. BRGH=1 is better (fewer errors).

    BTW, if you are going to use the USB, uCHIP says the system XTAL must be 6MHz or 48MHz with the processor clock derived from that. DISREGARD. They say an internal clock of 6MHz or 48MHz for the USB.., presumably derived from the external clock.

    Looking at the pin descriptions for RC6/7 in Table 10-5, we see the requirement that the 'User must configure as an output'. This is at odds with my earlier blue paste from section 20.0 which says that it should be an input. Go figure. I'd clear TRISC.6 for now.

    A good test would be to
    1) verify the RS232 link as described above (remove PIC, jumper TX/RX, verify echo)
    2) Verify the system speed by toggling an I/O pin and looking at a scope, or use some long delay that you can see and time with a stopwatch (clock setup errors are liable to be gross and the time way off)
    3) Write a simple routine to initialize the USART, send 'U' once and halt while(1) until reset. 'U' is nice because it toggles each bit in the data and if you have a scope makes it easy to determine the baud rate (104us/bit for 9600). If you don't get 'U', try other baud rates on the receive. If you have some clock divider off by a factor of 2/4 etc, you'll be running at some other but legitimate baudrate i.e. clock off by *2, baud will be 19200 etc.

    EDIT: Use MCLR/ to reset/resend the 'U' so that the MAX232 stays powered up.

    How's that?
     
    Last edited: Oct 27, 2013
    Dritech likes this.
  11. Dritech

    Thread Starter Well-Known Member

    Sep 21, 2011
    756
    5
    Thanks for the detailed description. I will do the testing and will let you know if it works.
     
  12. Dritech

    Thread Starter Well-Known Member

    Sep 21, 2011
    756
    5
    It worked :) It was form the PIC configuration setting. Thanks again for your help.
     
  13. JohnInTX

    Moderator

    Jun 26, 2012
    2,338
    1,017
    Cool! I actually found a PIC-DEM FS USB Demo Board in my cabinet. It uses a 4550 and 20MHz external xtal so looks like you are on the right path.

    BTW: what did you finally arrive at re: TRISC.6?
     
    Last edited: Oct 27, 2013
  14. Dritech

    Thread Starter Well-Known Member

    Sep 21, 2011
    756
    5
    Hi again,

    I wanted to use UART to interface Visual Studio with the PIC microcontroller. Now, lets assume that there are twenty buttons on the Visual Studio. Does that mean that I have to do twenty IF conditions (as below)?

    Is there another method which is more neat and efficient?

    Code ( (Unknown Language)):
    1. If(data == 'a')
    2. {
    3. Turn motor 1 clockwise
    4. }
    5. If(data == 'b')
    6. {
    7. Turn motor 1 counter clockwise
    8. }
    9. If(data == 'c')
    10. {
    11. Turn LED on
    12. }
    13. ............................
    14. ............................
     
  15. JohnInTX

    Moderator

    Jun 26, 2012
    2,338
    1,017
    Couldn't you use a switch statement with 20 cases?
     
  16. Dritech

    Thread Starter Well-Known Member

    Sep 21, 2011
    756
    5
    Hi,

    Never heard of switch statements. I did some research, but what are the main advantage of using switch statements in this case?
     
  17. JohnInTX

    Moderator

    Jun 26, 2012
    2,338
    1,017
    The advantage is just what you were asking about.. cleaner code.

    Code ( (Unknown Language)):
    1.  switch(data){
    2.   case 'a': Turn motor clockwise;
    3.    break;
    4.  case 'b': Turn motor counterclockwise;
    5.    break;
    6.  case 'c': Turn LED on;
    7.    break;
    8.  .... and so on
    9.  default: Stop everything;
    10. } // switch
    The switch statement compares the argument (data) with each case and executes code from there to a break; or the end of the switch. default is optional and executes code when none of the cases match the argument.
    I am presuming you are using C or some variant of it..
     
    Dritech likes this.
  18. Dritech

    Thread Starter Well-Known Member

    Sep 21, 2011
    756
    5
    Can you have long instructions when using switch statements?

    For example:

    Code ( (Unknown Language)):
    1. case 'a':
    2.  
    3. Turn motor clockwise;
    4. Call delay;
    5. Go to check sensor function;
    6. Display on LCD;
    7.  
    8. Break;
     
  19. JohnInTX

    Moderator

    Jun 26, 2012
    2,338
    1,017
    Yup. Just like you've written. Everything from the case match to the next break gets executed, as many statements as you want. It will also flow into the next case without a break - which has its uses too:

    Code ( (Unknown Language)):
    1. switch (data){
    2.  case 'a':
    3.  case 'A': do as much as you want... on upper or lower case A until break..
    4.  break; // end of a/A processing
    5.  
    6.  case 'b': perform this only on 'b' then flow to 'B'
    7.  case 'B': do this on 'B' or 'b' (lower case 'b' code flows into it (no break)
    8.  break; // end of b/B processing
    9. }// switch
     
  20. Dritech

    Thread Starter Well-Known Member

    Sep 21, 2011
    756
    5
    Thanks for the reply JohnInTX. For such application, is there the need to enable TXIE and RCIE ?
     
Loading...