Home > Electronics > Programming PIC 18 using XC8 (MPLAB X) : USART (PIC18F Serial)

Programming PIC 18 using XC8 (MPLAB X) : USART (PIC18F Serial)

I was about to start Analog to Digital Converters (ADC), but then how am I going to see the output? We need some type of debug terminal and so decided to start with serial port or say Universal Synchronous/Asynchronous Receiver/Transmitter. Serial communication is one of the best debug tool ever when it comes to embedded systems. In order to know what’s going on inside the controller and how your firmware is behaving, serial port serves as a window to look into.

Read this document for complete PIC (mid range) USART understanding: http://ww1.microchip.com/downloads/en/devicedoc/31018a.pdf

So first we need to set the speed/baud rate and here is the formula

baudrateformula

What’s the difference between Asynchronous and Synchronous?

Asynchronous = Transmit (TX) and Receive (RX) can happen at same time – full duplex

Synchronous = Either TX or RX at a time – half duplex

Ok, so now I’m going to set my UART (asynchronous and high speed – BRGH = 1) to 9600bauds. My controller is running at 8MHz internal oscillator. So according to the formula

16(X+1) = Fosc/Baud Rate

16(X+1) = 8000000/9600

16(X+1) = 833.333

X+ 1 = 833.333/16

X+1 = 52.0833

X = 51.0833

X = 51

 

So my settings is going to be: SPBRG = 51, BRGH = 1, Asynchronous mode

Setting the USART Pins

rxpin

txpin

 

Setting the RX and TX pins according to the table given above (you can find the table in the datasheet of the device you are using).

TRISCbits.RC6 = 0; //TX pin set as output TRISCbits.RC7 = 1; //RX pin set as input

Read the peripheral library for function definitions before blindly copying the code.

Note: If the PIC has more than 1 UART peripheral then you use the following

Open_nUSART()

puts_nUSART()

write_nUSART()

Where n = UART number

E.g.:

Open_1USART()

puts_1USART()

etc.,

#define _XTAL_FREQ 8000000 //The speed of your internal(or)external oscillator #define USE_AND_MASKS #include <xc.h> #include "config.h" #include <plib/usart.h> int i = 0; unsigned char UART1Config = 0, baud = 0; unsigned char MsgFromPIC[] = "PIC Rocks\r"; void SetupClock(void); void Delay1Second(void); void main(int argc, char** argv) { SetupClock(); // Internal Clock to 8MHz TRISCbits.RC6 = 0; //TX pin set as output TRISCbits.RC7 = 1; //RX pin set as input UART1Config = USART_TX_INT_OFF & USART_RX_INT_OFF & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_BRGH_HIGH ; baud = 51; OpenUSART(UART1Config,baud); while(1) //infinite loop { putsUSART(MsgFromPIC); Delay1Second(); } } void SetupClock() { OSCCONbits.IRCF0 = 1; OSCCONbits.IRCF1 = 1; OSCCONbits.IRCF2 = 1; } void Delay1Second() { for(i=0;i<100;i++) { __delay_ms(10); } }

The code above will print “PIC Rocks” every one second. Now, that is the communication from PIC to outside. Next will be to make PIC receive what you send in. Please read the peripheral library document located at “C:\Program Files (x86)\Microchip\xc8\<version>\docs\pic18_plib.pdf”

Now to receive from serial pin you can do it 2 ways.

  • Polling
  • Interrupts

Polling is something you will find everywhere so I’m not going to show here. But interrupts on the other way is the most efficient way to handle serial incoming data by a controller.

To enable interrupt change USART_RX_INT_OFF to USART_RX_INT_ON and then  enable the peripheral interrupt. In the data sheet you’ll find this table from which you can set the interrupt bits

image

 

UART receive in PIC might not receive [OR] RX pin might not work if you don’t read the note below

Note: Most RX pins are shared with ADC. Please disable the ADC using ANSELC (or corresponding ANSEL)

eg: ANSELC = 0x00 will make all pins as DIO in port C.

 

Here is the code for 1 character echo program

#define _XTAL_FREQ 8000000 //The speed of your internal(or)external oscillator #define USE_AND_MASKS #include <xc.h> #include "config.h" #include <plib/usart.h> unsigned char UART1Config = 0, baud = 0; unsigned char MsgFromPIC[] = "\r\nYou typed :"; char rx; void SetupClock(void); void Delay1Second(void); void main(int argc, char** argv) { SetupClock(); // Internal Clock to 8MHz TRISCbits.RC6 = 0; //TX pin set as output TRISCbits.RC7 = 1; //RX pin set as input UART1Config = USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_BRGH_HIGH ; baud = 51; OpenUSART(UART1Config,baud); //compare with the table above RCIF = 0; //reset RX pin flag RCIP = 0; //Not high priority RCIE = 1; //Enable RX interrupt PEIE = 1; //Enable pheripheral interrupt (serial port is a pheripheral) ei(); //remember the master switch for interrupt? while(1) //infinite loop { } } void SetupClock() { OSCCONbits.IRCF0 = 1; OSCCONbits.IRCF1 = 1; OSCCONbits.IRCF2 = 1; } void interrupt SerialRxPinInterrupt() { //check if the interrupt is caused by RX pin if(PIR1bits.RCIF == 1) { rx = ReadUSART(); //read the byte from rx register putsUSART(MsgFromPIC); WriteUSART(rx); PIR1bits.RCIF = 0; // clear rx flag } }

 

Here is a program that will repeat what you typed when you hit the return (enter) key. The way the program works is, it will receive all the characters you type in. As it stores into an array, it will also look for return key / carriage return (which is 0x0D in hex).

/* * File: main.c * Author: Singular Engineer * * Created on May 22, 2013, 8:31 AM */ #define _XTAL_FREQ 8000000 //The speed of your internal(or)external oscillator #define USE_AND_MASKS #include <xc.h> #include "config.h" #include <plib/usart.h> unsigned char UART1Config = 0, baud = 0; unsigned char MsgFromPIC[] = "\r\nYou typed :"; unsigned char MessageBuffer[200]; int i=0; void SetupClock(void); void Delay1Second(void); void main(int argc, char** argv) { SetupClock(); // Internal Clock to 8MHz TRISCbits.RC6 = 0; //TX pin set as output TRISCbits.RC7 = 1; //RX pin set as input UART1Config = USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_BRGH_HIGH ; baud = 51; OpenUSART(UART1Config,baud); //Compare with the table above RCIF = 0; //reset RX pin flag RCIP = 0; //Not high priority RCIE = 1; //Enable RX interrupt PEIE = 1; //Enable pheripheral interrupt (serial port is a pheripheral) ei(); //remember the master switch for interrupt? while(1) //infinite loop { } } void SetupClock() { OSCCONbits.IRCF0 = 1; OSCCONbits.IRCF1 = 1; OSCCONbits.IRCF2 = 1; } void interrupt SerialRxPinInterrupt() { //check if the interrupt is caused by RX pin if(PIR1bits.RCIF == 1) { if(i<200) //our buffer size { MessageBuffer[i] = ReadUSART(); //read the byte from rx register if(MessageBuffer[i] == 0x0D) //check for return key { putsUSART(MessageBuffer); for(;i>0;i--) MessageBuffer[i] = 0x00; //clear the array i=0; //for sanity return; } i++; PIR1bits.RCIF = 0; // clear rx flag } else { putsUSART(MessageBuffer); for(;i>0;i--) MessageBuffer[i] = 0x00; //clear the array i=0; //for sanity return; } } }

And here is the output

serialout

  1. Erik
    January 27th, 2017 at 00:05 | #1

    I am confused so .. please bear with me.

    I have a PIC18 chip and a PICKKit3 … I am trying your PICK Rocks demo, but the compiler is complaining… it sounds like the example you gave is for a previous compiler? Did you ever get a chance to port this to XC8 ?

  2. Paul E. Schoen
    October 22nd, 2016 at 02:53 | #2

    Thanks for the code examples. I needed to add serial comm to an existing project using a PIC18F242 (and its successor, PIC18F2420). Here is code for the ADC which differs between the two devices:

    void SetupADC()
    {
    #ifdef _18F2420
    ADCON0 = 0b00000001; // N/A; CHSEL 0=AN0; GO/Done; ON/off
    ADCON1 = 0b00001011; // N/A; VCFG1 0=Vss; VCFG0 0=Vdd; Config 1011=AN0-3
    ADCON2 = 0b10010101; // ADFM 1=Right, TACQ 010=4; <2:0: CS 101=fOsc/16
    #else // 18F242
    // ADCS0:1 (10=FOsc/32), CHS0:2 (000=AN0, 001=AN1, 010=AN2, 011=AN3)
    // (1 = GO, 0 = DONE), N/A, (1 = ADC Powered up)
    ADCON0 = 0b00000001;
    // ADFM 1=Right; ADCS2 (0=2/8/32, 1 = 4/16/64);
    // PCFG0:3 (0100 = AN0, AN1, DIO2, AN3, Ref+ = VCC, Ref- = VSS)
    ADCON1 = 0b10000100;

    #endif
    PIE1bits.ADIE = 1; // Enable ADC interrupt
    }

  3. pic18fuart
    July 6th, 2016 at 05:40 | #3

    Hi,

    I’m trying to implement the echo code to work with my pic18f4550, I use 8mhz crystal and I’ve setup the configuration bits, but when I try to compile it gives me this error which I can’t figure out or relate to the issue. This is the error
    …Microchip\xc8\v1.37\include\pic18f4550.h:4426: error: (1098) conflicting declarations for variable “_TRISCbits” (…\Microchip\xc8\v1.37\include\pic18f4550.h:4224) —- which leads me to this line:
    #define _TRISD_RD0_LENGTH 0x1

    Do you have any idea why is this conflicting.

    Thanks

  4. albhee
    June 30th, 2016 at 19:50 | #4

    @singularengineer
    i’ve tried by including stdio.h and then printf, but didn’t work..
    and plib/uart.h doesn’t have any fucntion like that.
    so, i solved the problem like below:

    int data = 10;
    char buf[8];
    sprintf(buf,”%d”,data);
    putsUSART(buf);

    it works, but i don’t know whether it is wrong way to do or is it ok.. please let me know.

  5. albhee
    June 30th, 2016 at 17:50 | #5

    hi,
    Is there any way to print in UART from PIC MCUs like below: ?

    printf(“value: %d %c”, temp, deg);

    i mean i want to print formated data using xc8 uart peripheral lib. is it possible ?

    • June 30th, 2016 at 18:11 | #6

      Yes you can.
      add stdio.h and you should be able to print. The program size will increase using printf(). Not efficient.

  6. April 21st, 2016 at 15:46 | #7

    Hello,

    How due i get the library functions to work, i want to set up an usart system?
    Using MPLAB X V3.26 XC8 V1.37. I tried to install PIC18-V2.00 for windows it says it can`t find the XC8 FOULDER. The alarm i get when i compile the program is shown below.

    #include “p18f46k20.h”
    #include
    #include
    #include
    #include

    newmain.c:76: error: (141) can’t open include file “plib/usart.h”: No such file or directory

  7. Nico
    January 13th, 2016 at 13:06 | #9

    Hi, is the author of this topic always there ? I really need to ask him a question.

    Thx 🙂

  8. Ace
    December 7th, 2015 at 04:12 | #10

    I’d recommend that you change baud to be an unsigned int. Otherwise it’ll bite you in certain circumstances.

    Thanks for the nice examples! 🙂

  9. james
    October 29th, 2015 at 13:44 | #11

    Thanks for your great post, I have a little problem which i just cant seem to fix,
    Using the third example it works fine for me with soime changes on the timing and baud calculation, but only once, after it returns the buffer the interupt doesnt work again. If i put in some ports going high and low into the interup code it slows things down and i get a garbled response when the buffer is output, however it does work more than once.
    the chip is a 18F45K20.
    thanks again for you help.

    • October 31st, 2015 at 14:58 | #12

      Sorry about the delayed response. Hope you would have fixed your problem by now. If not, please use the microchip forums. Lot of readers/viewers there. Your solution will also help a wider audience.

  10. Supreeth Anil
    May 15th, 2015 at 00:18 | #13

    If 9600 baud rate is possible in high speed(BRGH=0) and low speed(BRGH=1) then what is the effect of selecting BRGH=1 over BRGH=0, given the same baud rate error. Your tutorials are helping me very much . If you can share some tutorials on simple LCD then it will be very useful.

    • May 15th, 2015 at 01:00 | #14

      No specific reason for BRGH bits for 9600 baud rate. Regarding the LCD, you got to read the datasheet and try it. Tutorials here are just a warm up for users to get used to PIC. Regarding LCD, you got to read the datasheet and try it. If you search you can find library for the controller hd44780. I think XLCD.h in xc8/c18 is for hd44780.

      Also use microchip forums (http://www.microchip.com/forums/) for questions regarding lcd library.

  11. Daniel
    February 18th, 2015 at 13:22 | #15

    Hi!! I’m working with the pic18f4550 i have a problem with the communication in simulation it works but when i try it in protoboard it does not work, i’m using also the protocol SPI do you think that it will be problem?? I’m not using RX so will i dishability it??
    Sorry about my english. Thanks

    • February 18th, 2015 at 19:24 | #16

      If the pin is being shared with other peripherals like PWM or ADC then you have to disable those peripherals on that pin. Make sure the pin is set as IO. Usually in simulation they don’t look into the constraints of shared peripherals. So its up to the user to check for. Read the datasheet and you should be able to disable the particular peripherals (like ADC channel). If you have more question, please use http://microchip.com/forums.

  12. January 14th, 2015 at 15:10 | #17

    @MotoMike
    Check Table 10-8 of 18F46k22 (the chip you are using). In order to set as RX pin you need to disable Analog input.

    Try this next to TRIS settings

    ANSELC = 0x00;

  13. MotoMike
    January 14th, 2015 at 13:37 | #18

    @singularengineer

    I have switched to 18F46K22 now. Got PIC Rocks working, but can’t get interrupts to work in the second and third programs.

    In the 3rd program, I never see where you put “You typed in” to the serial port?

    You maybe have missed something???

    I am using ICD3 in MPLABX (XC8) as debug. I get no break point action if I set a break point
    at the entry of the interrupt? I am not sure if ICD3 works with Interrupts, but I think it does?

    Thanks again, I have learned a lot in the last few days!
    Mike

  14. January 13th, 2015 at 16:07 | #19

    @MotoMike
    Thanks Mike!

  15. MotoMike
    January 13th, 2015 at 15:57 | #20

    Thanks, I have “PIC Rocks” working on a 18F452 on 2 Prototype PCB’s I made.
    20 Mhz at 19.2 KB, so I change Baud Rate to 64D.
    It even runs in Debug with the ICD3. I am using XC8 and IDE.
    Your example helped me very much. I was having troubles with finding out how to use the functions. The Peripheral Manual need examples for each function?

    I still don’t what #define USE_AND_MASKS is for?

    I will try your other examples! I have done this asy but not in C!
    I just loaded XC8 yesterday, so I have made lots of progress.

    I got some newer Pics coming today too to play with.

    So, thanks again, I can imagine you spent a lot of time doing these examples!

    Mike

  16. Felipe
    November 2nd, 2014 at 22:42 | #21

    Add: ANSELC = 0;

    Disable the analog inputs (ADC) so you get the RX pin to work.

  17. albhee
    August 29th, 2014 at 14:23 | #22

    Thanks for the tutorial. i appreciate your effort. But by using those Peripheral Library we are keeping ourselves away from learning how the code works behind those functions specified in the header file. i think you understood what i meant. i need to know what’s going on in register level. It will be so helpful if you make another tutorial on adc,usart,timer without using those library but by specifying the values of individual registers. Thanks again 🙂

    • August 29th, 2014 at 21:27 | #23

      I do agree with you, but the whole reason for using Peripheral Library (plib) is because there are enough tutorials on the internet that do not use plib. If you search for programming PIC with assembly, you will get everything you need to know at register level. In fact microchip website has sample codes for PIC18 in assembly and non plib based C code. You can also go through the header and source files of the plib to know what’s going on in the register level. Search microchip website and you find all the things you need to know. This blog/site is mostly for my own reference. So when I do a project I just pick code from here and save time. Just made it public so people can use it if they need to. Thanks for taking time to make a comment.

  18. Leandro
    August 13th, 2014 at 07:38 | #24

    According to the datasheet both TRIS should be set to 1. Even though TX will definetively be a digital output it will be managed by the USART peripheral not by the I/O Ports peripheral.

  19. Supreeth
    June 4th, 2014 at 02:12 | #25

    I was not able to perform software uart using c18 library. Can you share a tutorial or example projects about software uart.

  20. AJ
    April 16th, 2014 at 17:59 | #26

    Great tutorial! However, you should note that USE_AND_MASKS should be defined above the line “#include . Otherwise the compiler won’t know which format to use during preprocessing.

    I found this out by trying your code with USE_OR_MASKS defined instead. It doesn’t work unless you apply the fix. Your code works because the default is to use USE_AND_MASKS.

    Cheers,
    AJ

  21. Jes
    February 14th, 2014 at 11:14 | #27

    tnx for your reply ok I will give it a try 🙂@singularengineer

  22. Jes
    February 14th, 2014 at 05:57 | #28

    Hi good day I’m been doing a project of sms light system using SIM900D and pic18f4550, my problem is it won’t send sms in my phone, and in WriteUSART() where I coded the AT commands it says suspicious pointer conversion, I’m using MPLAB X and compiler C18, hmm I hope u can help me pls reply 🙁

  23. Richard Johnson
    January 11th, 2014 at 02:25 | #30

    I was using code above for pic16LF721. When I compile, I get an error of undefined symbol. Any idea’s?

  24. Nickolas Heckman
    December 30th, 2013 at 00:58 | #32

    Thanks for the above examples Singular Engineer, I found them very helpful when looking for an example implementation of usart.h.

    Just a tip for anybody who is working on getting their USART working with PIC18F.

    Be 100% SURE you disable analog inputs on your RX pins!

    TX will work fine if you don’t, but you will be scratching your head trying to figure out why you never seem to interrupt on RX bytes. I know I was…

    • December 30th, 2013 at 08:02 | #33

      Nickolas, thank you for taking time to write a comment. RX pin multiplexing with A/D is something I should tell in the post, good thing you made a comment about it. That actually applies to all peripheral where pins are shared with A/D, it should be disabled. There have been days when I spent hours figuring out. But once a person gets comfortable its a flow!
      Have a happy PIC Programming!

  25. Harman
    November 13th, 2013 at 09:13 | #34

    Hii singular

    i am trying to implement this procedure with PIC16f84a. Do you think it will work??

    Following is the code that i am using:

    #include
    #include
    #include “plib/usart.h”
    #include “plib.h”
    #include
    #include
    #include
    #include

    #define _XTAL_FREQ 4000000 //The speed of your internal(or)external oscillator
    #define USE_AND_MASKS

    int i = 0;
    unsigned char UART1Config = 0, baud = 0;
    unsigned char MsgFromPIC[] = “Harman\r”;

    void SetupClock(void);
    void Delay1Second(void);

    void main(int argc, char** argv) {

    SetupClock(); // Internal Clock to 8MHz

    TRISA4 = 0; //TX pin set as output
    TRISA3 = 1; //RX pin set as input

    UART1Config = USART_TX_INT_OFF & USART_RX_INT_OFF & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_BRGH_HIGH ;
    baud = 81;
    Open1USART(UART1Config,baud);

    while(1) //infinite loop
    {
    puts1USART(MsgFromPIC);
    Delay1Second();
    }
    }

    void SetupClock()
    {
    OSCCONbits.IRCF0 = 1;
    OSCCONbits.IRCF1 = 1;
    OSCCONbits.IRCF2 = 1;
    }

    void Delay1Second()
    {
    for(i=0;i<100;i++)
    {
    _delay(10);
    }
    }

    The problem is that OpenUART, closeUART , osconn and putsUART are showing an error. (unable to resolve identifier). I tried using Open1UART , puts1UART and so on. still i have the same problem.

    Can you please help me with this???
    Thanx

    • November 13th, 2013 at 10:30 | #35

      plib is only for 18F parts. So you may not be able to use those functions. If you still want something that easy, try the free version of mikroe. They got a nice library with examples.

  26. Milani
    September 21st, 2013 at 16:07 | #36

    I just don’t understood what is “void main(int argc, char** argv)” this was mentioned in “#include “config.h””? can you post or send me your code config.h?
    Another thing that I make some confuse is: “ei(); //remember the master switch for interrupt?”
    What is it, what this do?
    Thanks for helping me.

  27. Erik
    August 15th, 2013 at 03:24 | #37

    Okay so after some arduous trouble shooting, I decided to start over and just create a new project. I guess I must have messed up some default setting because in the new project it compiles fine. Thank you though, and thanks again for posting this tutorial!
    Erik

  28. Erik
    August 14th, 2013 at 03:51 | #38

    SingularEngineer,
    Thank you so much for posting this tutorial. I have a USART interface set up using none of the microchip APIs, and I’m trying to move to an API based program. I’ve included , and I’ve defined my chip type in my configuration. Nevertheless, my program refuses to recognize functions such as Open1USART. Upon investigation, I discovered it was the result of a constant __18F27J13 never being defined. What do I need to change or include to have this constant defined? Please help.
    Thanks again,
    Erik

    • August 14th, 2013 at 12:08 | #39

      so you include plib/usart.h and still its not working? hmm.. can I your code? If you don’t mind

  29. Jordan
    July 14th, 2013 at 22:42 | #40

    So it seems the problem was that I was incorrectly adding the xc8’s include directory in the mplab project properties. I pointed it at “PathToXC8/include/plib” rather than just the “PathToXC8/include”. On top of that it did fail to resolve according to the IDE but did compile right (after changing include path correctly) and I got my USART bluetooth module to speak to my computer, so all is now good. Thanks for the help!@singularengineer

    • July 14th, 2013 at 23:02 | #41

      Ha ha.. great! Usually the path’s are already included during installation of the compiler and you no need to add them specifically. Are you using Windows? Anyways good to know it works. Jordan, do you document your project? If so please share the link here so that people might know your project. If not, then please start documenting and put it in a blog.

  30. Jordan
    July 13th, 2013 at 14:37 | #42

    Did you mean include usart.h? If so I have that already, and if I look through that file in the project all of the code is greyed out. There doesn’t seem to be any EAUSART_VX’s defined at all. So I seem to be missing what ever include would define the usart version. I tried to include the pic18f2620.h file but that did nothing. Any other suggestions?@singularengineer

    • July 13th, 2013 at 14:59 | #43

      It is plib/usart.h. I think I might be getting what you are saying. If the code is compiling but still underlining with a red line and exclamation saying “Unable to resolve identifier…”. Is that what it is saying but still compiling? Its bug that is still being worked upon I agree it is annoying. You can fix that by

      Tools –> Options –> C/C++ –> Highlighting –> uncheck “Highlight Unresolved Identifiers” also uncheck “Highlight Unresolved Include Files” (will be helpful later).

    • July 14th, 2013 at 19:45 | #44

      My bad. It should be Open1USART(UART1Config,baud) (1 for 1st USART) puts1USART();

  31. Jordan
    July 13th, 2013 at 14:08 | #45

    Hello Singular Engineer, thank you for the code examples. Reading your posts helps get things working much faster than if I were to go at it alone. However, I am still having some issues. Mainly, I can’t seem to get the compiler to recognize any of the Open_usart() functions. I am using xc8 compiler for a pic18f2620 micro. Maybe I am missing some sort of includes? What is in your config.h include, I imagine that is something you wrote because it is “config.h” rather than .

    I’m very excited to use the usart library but I can’t get the IDE to even recognize it. It does however recognize the bit masks used to set the USART1Config variable.

    • July 13th, 2013 at 14:28 | #46

      #include plib/usart.h (use angular brackets)

      and you should be able to use OpenUSART() (not Open_usart()). Open usart.h file and try to go through to get a better grasp.

      config.h is the configuration bits like setting up my internal oscillator, turning of WDT, PBADEN, LVP and so on… The reason why I don’t put it is each controller has its own config and i’m sure people will just copy and say its throwing error. But if you follow the setting configuration bits post () you will be able to make one for your controller.

      Glad it helps you!

  32. Terrence
    July 12th, 2013 at 05:30 | #47

    Hi Singular Engineer

    I am very impressed with and grateful for the quality of your posts and concise explanations. Your website is really a gem to people like me who has just started learning PIC programming. Knowing C Programming is one thing but knowing how to properly set and configure and make the PIC work is totally a different level of knowledge. Thank you very much for your goodwill to teach people online.

    Best Regards.

    • July 13th, 2013 at 10:44 | #48

      Thank you!
      I started this site as a self reference for me. But then thought why not make it public? Still now I use my own posts for my references and glad it helped you too! You are absolutely right, a lot of people work on the programming aspect without knowing the working of a microcontroller. Sad thing, but for a hobby its ok. When it comes to making products, that’s a whole different story. I’m still trying to write USB and Ethernet tutorials, can’t find time. Microchip has done awesome job in giving template applications for complex peripherals. So its just a matter of how to use it will be the post. Thanks Terrence, its more encouraging to keep writing. You have a nice day!

  33. etb
    July 12th, 2013 at 02:06 | #49

    Hi,

    I can’t seem to get any response from USART2 using the modified code from above.

    Any help is greatly appreciated.

    #include
    #include “config.h”
    #include

    #define _XTAL_FREQ 16000000 //The speed of your internal(or)external oscillator
    #define USE_AND_MASKS

    unsigned char UART2Config = 0, baud = 0;
    unsigned char MsgFromPIC[] = “\r\nYou typed :”;
    unsigned char MessageBuffer[200];

    int i = 0;
    void SetupClock(void);
    void Delay1Second(void);
    void Open2USART(unsigned char config, unsigned int spbrg);
    void Write2USART(char data);
    void puts2USART( char *data);
    char Read2USART(void);

    void main(int argc, char** argv) {
    SetupClock();
    TRISBbits.RB6 = 0; //TX pin set as output
    TRISBbits.RB7 = 1; //RX pin set as input

    UART2Config = USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_BRGH_HIGH;
    baud = 51;
    Open2USART(UART2Config, baud);
    //Compare with the table above
    RCIF = 0; //reset RX pin flag
    RCIP = 0; //Not high priority
    RCIE = 1; //Enable RX interrupt
    PEIE = 1; //Enable pheripheral interrupt (serial port is a pheripheral)

    ei(); //remember the master switch for interrupt?

    while (1) //infinite loop
    {

    }

    }

    void SetupClock() {
    OSCCONbits.IRCF0 = 1;
    OSCCONbits.IRCF1 = 1;
    OSCCONbits.IRCF2 = 1;
    }

    void interrupt SerialRxPinInterrupt() {
    //check if the interrupt is caused by RX pin
    if (PIR1bits.RCIF == 1) {
    if (i 0; i–)
    MessageBuffer[i] = 0x00; //clear the array
    i = 0; //for sanity
    return;
    }
    i++;
    PIR1bits.RCIF = 0; // clear rx flag
    } else {
    puts2USART(MessageBuffer);
    for (; i > 0; i–)
    MessageBuffer[i] = 0x00; //clear the array
    i = 0; //for sanity
    return;
    }
    }
    }

    @singularengineer

    • July 13th, 2013 at 10:35 | #50

      Is it 46K22?. You say crystal/OSC speed is 16MHz, then what are the things inside setupclock() function is doing? are the RX pin and TX pin the same as 4550? If so are they UART1 pins or UART2 pins? In the interrupt part, how do you know the interrupt is from 1st UART or 2nd UART?

      Reading a datasheet takes time, I agree. But without reading datasheet you won’t understand anything I said above. I am not going to write/complete the code. I am sure microchip forum will be very helpful. Have a nice day and happy programming!

  34. etb
    July 10th, 2013 at 02:25 | #51

    Hi,

    I am working on PIC18F24K22, I wanted to make a USART to I2C interface. Any help will be greatly appreciated.

    Thanks in advance!

    • July 10th, 2013 at 09:54 | #52

      Reg hardware, make sure you have the pullup resistor (check datasheet for the value)

      Reg firmware

      1) Set the pin as digital IO (sometimes it might be sharing with ADC channel, so you have to disable ADC for those pins)
      3) Read every page of I2C of the device datasheet and understand (tells everything)
      2) Read under the title Inter Integrated Circuit Communication somewhere around page 1113 of peripheral library document (located at C:\Program Files (x86)\Microchip\xc8\\docs\pic18_plib.pdf) – They also have sample code!

      Hope that helps
      ~SE

  35. Fabian
    July 7th, 2013 at 05:35 | #53

    Hello, Thank you for your examples, have you an example of use of USB with the 18F ?

    • July 7th, 2013 at 13:24 | #54

      Micorchip is working on porting the libraries to XC8. Right now they have C18 working well which you can download from http://www.microchip.com/mla‎. I am working on PIC18 with Ethernet for which i’ll be giving an application template. After that i’ll be working on USB. Things can change not sure how I am going to get time.

  1. No trackbacks yet.