Usart communication with pic16f877a

Status
Not open for further replies.

NIALA

Junior Member level 1
Joined
Jun 9, 2010
Messages
19
Helped
2
Reputation
4
Reaction score
2
Trophy points
1,283
Location
Minneapolis
Visit site
Activity points
1,408
Hi , seeking a little help

My goal : establish serial communication between an hyper terminal and a PIC16F877A using a C code.
Tools : MPLAB X IDE V1.80 and the c compiler is XC8 Compiler.

I define a init file InitUART() to initialise the register
An infinite loop where I received and transmit a character through registers when they are full.

I wasnt able to establish communication so far and open for some suggestions.

thanks!!!


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
#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include <usart.h>
#pragma config "FOSC=XT" 
#pragma config "WDTE=OFF"
#pragma config "BOREN=OFF"
#pragma config "LVP=OFF"
#pragma config "DEBUG=OFF"
 
#ifndef _XTAL_FREQ
#define _XTAL_FREQ  4000000
#endif
#define BAUDRATE 9600
void InitUART (void);
/*
 * 
 */
int main(int argc, char** argv)
{
    unsigned char ReceiveChar;
    //
    InitUART();
    //
    while(1)
    {
       if(RCIF==1)
       {
           ReceiveChar=RCREG;
 
           if(TXIF==1)
          {
           TXREG=ReceiveChar+0x01;
          }
       }
 
       
 
    }
    return (EXIT_SUCCESS);
}
 
 
void InitUART (void)
{
    SPBRG = ((_XTAL_FREQ/16)/BAUDRATE) -1;
    BRGH  = 1; //Baud Rate Generator High Speed 1
    SYNC  = 0; //Asynchronous mode 0
    SPEN  = 1; //Serial Port Enable Bit  1
    CREN  = 1; //Continuous Receive Enable Bit Enable continuous receive 1
    SREN  = 0; //dont care in asynchronous mode
    TXIE  = 1; //USART Transmit Interrupt Enable Bit , disable the USART transmit interrupt
    RCIE  = 1; //USART Receive Interrupt Enable Bit , Enable the USART receive interrupt
    TX9   = 0; // 9bit transmit enable bit 0 select 8bit tran
    RX9   = 0; // 9bit receive enable bit 0 select 8bit recep
    TXEN  = 0; // Transmit Enable Bit  Transmit disabled 0
    TXEN  = 1; // Transmit Enable Bit  Transmit enable 1
    TRISCbits.TRISC6 = 0; // This sets pin RC6 to output (USART asynchronous transmit or synchronous clock)
    TRISCbits.TRISC7 = 1; // This sets pin RC7 to input  (USART asynchronous receive or synchronous data)
    GIE   = 1 ;//Global Interrupt Enable Bit: 1 Enables all unmasked interrupts
    PEIE  = 1 ;//Peripheral Interrupt Enable Bit : 1 Enables all unmasked peripherals interrupts
}

 
Last edited by a moderator:

One issue I have noticed, after glancing over your code, is you have the interrupts enabled however you have implemented no interrupt service routines (ISR).

You are instead polling the interrupt flags.

Try disabling the interrupts by setting the TXIE, RCIE, GIE and PEIE to 0, the TX and RX flags will still be set regardless.

Doing so should allow the flags to be polled in your SuperLoop, while(1).

Meanwhile I'll examine your code more thoroughly.


BigDog
 

I disabled TXIE RCIE GIE and PEIE.
I have a warning sign on the Tx AND Rx pins , "unable to resolve identifier"
I configure RC6 in input and RC7 in output. Do i need to add a specific header for these lines to be identifies


Code:
void InitUART (void)
{
   TRISCbits.TRISC6 = 0;
   TRISCbits.TRISC7 = 1;
   
}
 

I received those warnings as well, but only within the IDE code edit window. After reviewing the PIC16F877A.h header file, I can confirm that those symbols are defined.

The code did compile without warnings or errors and functioned as expected, receiving the ASCII code, incrementing it by one and then transmit it back.

Perhaps the warnings are a MPLABX bug, I'm just getting acquainted with MPLABX myself.

Also noticed I removed the:

Code:
#include <usart.h>

It's clearly not need, you also should be able to remove the stdio.h and stdlib.h.

Current Version

Code:
#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#pragma config "FOSC=XT"
#pragma config "WDTE=OFF"
#pragma config "BOREN=OFF"
#pragma config "LVP=OFF"
#pragma config "DEBUG=OFF"

#ifndef _XTAL_FREQ
#define _XTAL_FREQ  4000000
#endif
#define BAUDRATE 9600
void InitUART (void);
/*
 *
 */
int main(int argc, char** argv)
{
    unsigned char ReceiveChar;
    //
    InitUART();
    //
    while(1)
    {
       if(RCIF==1)
       {
           ReceiveChar=RCREG;

           if(TXIF==1)
          {
           TXREG=ReceiveChar+0x01;
          }
       }



    }
    return (EXIT_SUCCESS);
}


void InitUART (void)
{
    SPBRG = ((_XTAL_FREQ/16)/BAUDRATE) -1;
    BRGH  = 1; //Baud Rate Generator High Speed 1
    SYNC  = 0; //Asynchronous mode 0
    SPEN  = 1; //Serial Port Enable Bit  1
    CREN  = 1; //Continuous Receive Enable Bit Enable continuous receive 1
    SREN  = 0; //dont care in asynchronous mode
    TXIE  = 0; //USART Transmit Interrupt Enable Bit , disable the USART transmit interrupt
    RCIE  = 0; //USART Receive Interrupt Enable Bit , Enable the USART receive interrupt
    TX9   = 0; // 9bit transmit enable bit 0 select 8bit tran
    RX9   = 0; // 9bit receive enable bit 0 select 8bit recep
    TXEN  = 0; // Transmit Enable Bit  Transmit disabled 0
    TXEN  = 1; // Transmit Enable Bit  Transmit enable 1
    TRISCbits.TRISC6 = 0; // This sets pin RC6 to output (USART asynchronous transmit or synchronous clock)
    TRISCbits.TRISC7 = 1; // This sets pin RC7 to input  (USART asynchronous receive or synchronous data)
    GIE   = 0 ;//Global Interrupt Enable Bit: 1 Enables all unmasked interrupts
    PEIE  = 0 ;//Peripheral Interrupt Enable Bit : 1 Enables all unmasked peripherals interrupts
}




BigDog
 

When you enter g from the keyboard , i was expecting h because we increasing by 0x01. Or am i mistaken?
 

Yes, that is correct.

Each character entered on the keyboard is incremented by one and transmitted back to the terminal emulation window.

I can tell you have experience coding for systems with an OS, like Windows or Linux.

Typically in embedded system without an OS, the main() routine is define as follows:

Code:
int main(void)

Rather than with the argument list parameters as there is no OS from which to receive them. :lol:

Also technically there should be no return from main() as there is no OS to which to return.

BigDog

- - - Updated - - -

I've attached an image showing the terminal window with ECHO forced on, therefore the first character is the key which was pressed followed by the incremented character transmitted by to the terminal window.

I pressed asdfghjkl and of course received bteghiklm back.

 

I see!!!
I tried the code and for any character i enter from the keyboard i am receiving a set of four characters.
when i enter a i get bcd
b i get cde
etc.....
It has to be related to the code . but that weird that we dont get the same response . Which baude rate did you set your hyper terminal?

- - - Updated - - -

I forgot to add a screenshot of my screen


 

I have my terminal set for 9600 8-N-1 with Echo forced on.

I noticed you have numerous projects open in MPLABX, close all the projects except the current one.

Other than the possibility of loading the PIC with the incorrect firmware, I doubt it is the code.

Are you using a development board? If so, which one?

If you are developing on a homebrew system, double check your MAX232 connections.

Also confirm you are using a 4MHz crystal to drive the PIC.

BigDog
 

Big Thanks you BigDog I restart my board and the code is working how its suppose to. I send a charater and i receive back the next character..
thanks for your help!!!
 

I'm glad to hear it.

Although, I would still close some of those projects open in the project window.

You must have a dozen of them open. :lol:

Good Luck with your endeavors.

BigDog
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…