Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[PIC] UART communication in PIC16F877A

Status
Not open for further replies.

BALKRISHNA TULSYAN

Junior Member level 3
Joined
Apr 19, 2013
Messages
29
Helped
2
Reputation
4
Reaction score
2
Trophy points
1,283
Location
BANGALORE
Activity points
1,522
Hi everyone.. i have written UART code in MPLAB using "xc8" compiler for PIC16F877A Microcontroller..code build was successful but while i am simulation code using proteus i am not getting the output in virtual terminal as expected. Frequency used for 9600 baud rate is 4.9152 MHZ so that baud rate error is ZERO. i have set frequency in proteus as same 4.9152 MHZ and baud rate as 9600 in virtual terminal. can anyone suggest weather i am missing something in the code or code is correct .


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include<xc.h>
#include<stdio.h>
#include<stdlib.h>
 
 
// CONFIG
#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = ON       // Power-up Timer Enable bit (PWRT enabled)
#pragma config BOREN = ON       // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF        // Low-Voltage (Single-Supply) 
#pragma config CPD = OFF        // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF        // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)
 
#define _XTAL_FREQ 4915200
#define baud_rate 9600
 
void serial_init(void);
void serial_char(unsigned char);      
void serial_string(unsigned char *);
char serial_read(void);
 
char data_string[16] ="ENTER ANY VALUE";
unsigned char data_buff = 0,data_read =0;
 
void main() 
{
  unsigned int i=0;
  serial_init();
  serial_char('A');
  serial_string(data_string);
  TRISB =0X00;  
  PORTB = 0X00;
  while(1)
  {
      if(PIR1bits.RCIF)
      {
         
          data_buff = serial_read();
          
          switch(data_buff)
          {
              case 0x31:
              {
                  PORTB = 0X01;
                  break;
              }
              case 0x32:
              {
                  PORTB = 0X02;
                  break;
              }
              case ' ':
              {
                  PORTB = 0X03;
                  break;
              }
              default:
                  PORTB = 0XAA;
          }
      }
  }
}
 
 
void serial_init()
{
      unsigned int speed = (_XTAL_FREQ - (baud_rate*16))/(baud_rate*16);
      TRISCbits.TRISC6 = 0;
      TRISCbits.TRISC7 = 1;
      SPBRG = speed;
      TXSTAbits.BRGH = 1;  //REQUIRED FOR HIGH BAUD RATE 
      TXSTAbits.SYNC = 0;  //for Asynchronous communication
      RCSTAbits.SPEN = 1;  // enable UART
      RCSTAbits.CREN = 1;  // enable continuous receive enable 
      TXSTAbits.TXEN = 1;  // enable transmission
 }
 
void serial_char(unsigned char data)
{
    while(!TXSTAbits.TRMT); //wait for previous transmission to over
    TXREG = data; 
}
 
void serial_string(unsigned char *str)
{
    while(*str != 0)
    {
        serial_char(*str++);
    }
}
 
char serial_read()
{
    while(!PIR1bits.RCIF);  //check weather reception is complete
    data_read = RCREG;      //read the RCREG register
        if(RCSTAbits.OERR == 1)  // check for any over run error
        {
            RCSTAbits.CREN = 0;
            RCSTAbits.CREN = 1;
        }
    return data_read;
    
}

 
Last edited by a moderator:

hello,


Wrong formula for SPBRG calculus
FOSC 4915200
Baud rate 9600
BRGH=1
Baud Rate = FOSC/(16(X+1))
31,99666701 -> 32
 

if we expand the above formula what you mentioned
i.e. Baud rate = FOSC/16(X+1) we will get

X = (FOSC - 16*Baudrate)/(16*Baudrate)
SPBRG = X
This is the same formula i have used to load in SPBRG.
Am i missing something ... please help.
 

What value is it actually using as 'speed'? For exactly 9600 Bauds it should be 4915200/512 so with BRGH = 1 the SPBRG should be set to 31 (decimal).

Possibly there is a calculation error though, I do not have the compiler with me to check but you are loading SPBRG with an unsigned integer value so it may be worth trying a 'char' cast to force it to an 8-bit value.

Brian.
 
Thank you for your help.. i have corrected that part and tried both typecasting and directly using a char variable for speed, but in both the cases problem still persist. As PIC16F877A does NOT have any internal oscillator like other PIC microcontroller(as per my knowledge), do i need to configure some extra SFR bits in order to tell microcontroller that i am using external oscillator or i am lacking with some info.

- - - Updated - - -

Given in data sheet:
shows the formula for computation of the baud rate for different USART modes which only apply in Master mode (internal clock).
BAUD RATE FORMULA:
(Asynchronous) Baud Rate = FOSC/(64 (X + 1))
(Synchronous) Baud Rate = FOSC/(4 (X + 1))
Baud Rate = FOSC/(16 (X + 1))
Legend: X = value in SPBRG (0 to 255)
 

This is wrong.

Code:
#pragma config FOSC = HS

Make it

Code:
#pragma config FOSC = XT

Zip and attach the MPLAB X Project files and I will fix it.

- - - Updated - - -

Edit:

I have compiled the code for 4 MHz and it is working fine. So, the formula I have used to calculate SPBRG value is correct. Try for your FOSC.
 

Attachments

  • uart.X.rar
    81.4 KB · Views: 69
  • uart.png
    uart.png
    37.4 KB · Views: 150

- - - Updated - - -

I got the output.
I used the same formula as X = (4915200 - baudrate*16)/(baudrate*16) where FOSC = 4195200
which comes out to be 31, so i have written directly SPBRG = 31 and it is working absolutely fine. but if i am writing SPBRG = X which is a character type variable ,insted of SPBRG = 31, I am NOT getting the correct output. so what could be the problem behind using variable instead of direct value and what is the problem behind using "HS" and not "XT" in configuration bits.
 

You can use XT or HS modes at that frequency. The mode decides the gain of the internal amplifier between the OSC1 and OSC2 pins to allow a wider range of crystal frequencies but the modes (except RC) overlap and at border frequencies both will work. If you are driving from an external oscillator signal it makes little difference which mode you use.

The SPBRG problem is, I suspect, because (baudrate * 16) exceeds the maximum value an unsigned int can hold. 9600 * 16 = 153,600 but the int can only hold 65,535. You could make the variable a bigger type to fix the math but loading the value directly works just as well if the baud rate and clock frequency will never change.

Brian.
 
Thanks a lot for the explanation and yes you are right i have to take a larger value other then "int".. i will check and get back.
 
Last edited:

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top