# PIC16F876 sends corrupt rs232 data

Status
Not open for further replies.

#### webtype

##### Newbie level 2
rs232 data end character

Hi,

i made my serial cable and i saw the first lines that my PIC was printing
=> how beatiful :flasingsmile:
i then added longer text messages and i saw that my PIC had big problems to send them ... at the other end of the rs232 connection these sentences can relly be called corrupt... the lines were never complete and at the end they had wrong characters. I am using CCS PCW C Compiler and i changed my rs232 definition line from:
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8 )
to:
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,BRGH1OK)
They say that BRGH1OK is there to get pics with baudrate problems to work. After adding that i could send long lines also, But when i wrote this little program:
Code:
while(1){
c = getc();
printf("%c",c);
}
and i press a character on my keyboard and don't release it, every about then characters it send a wrong character back. That looks like that:
Code:
dddddddddddddddddddddddddddddddddddûþ²ÿÿôddüdddddddddddddddddddddddddddddddddddd
ddddddddddddddddddddddddddddddÿüäöôdddäddddddddödddÿdddddddd

What could that be?
My Configuration:
PIC16F876-20/IP
running with 20 Mhz.
I don't know how to get out of that deep valley with so cliffy walls 8)

webtype

#### cube007

##### Full Member level 6
preprocessor spbrg

Hello,

it you are using a interrupt routine for RS-232 try to disable the ICD option. A friend of mine had problems like this. And without ICD it was working.

by,
cube007

#### neuralc

##### Full Member level 4
ccs and application and maestro

Hi,

Yes cube007, we need to set off ICD on FUSES

NeuralC

##### Member level 1
uart+code+pic16f876

perhaps a problem with cable
...
parasiting or something like this

#### abb652

##### Member level 1
baut rate 9600 pic 16f876

Are you sure that the CCS compiler is using the UART of the F876??

Some C compilers, when you use the RS232 definition line, emulates the UART by software, instead of using the hardware UART.
Be careful with that.

Dont use the printf() instruction, is better to write you own function, you only need to check that the TRMT bit of the TXSTA register is clear and write to the TXREG.

For example:

void SendChar (char ch)
{
char TxEmpty;

asm bsf STATUS,RP0;//Bank 1
TxEmpty = TXSTA; // Save TXSTA
asm bcf STATUS,RP0;//Bank 0

while ( (TxEmpty & 0x02)==0) // Wait for TX Empty
{
asm bsf STATUS,RP0;
TxEmpty = TXSTA;
asm bcf STATUS,RP0;
}

TXREG = ch; //Write the TXREG register
}

I hope this helps.

#### hakan

##### Member level 2
uart and pic16f876

don't forget to check buffer if u use usart!
before sent your data u can check buffer empty or not like this

// while sending

void putch(char c)
{
UsartErrorControl();
while(!TXIF); // wait if buffer is full
TXREG = c;
}

// while reciving

char getch(void)
{
UsartErrorControl();
while (!RCIF); // wait if buffer is empty
return RCREG;
}

void UsartErrorControl(void)
{
unsigned char d;
if (OERR) // overrun error
{
TXEN = 0;
TXEN = 1;
CREN = 0;
CREN = 1;
}
if (FERR) // frame error
{
d = RCREG;
TXEN = 0;
TXEN = 1;
}
}

#### hakan

##### Member level 2
corrupt rs232

and if u use putch() instead of printf your complied code will be smaler.

#### volta

##### Junior Member level 3
usart pic16f876 ccs c

Dear ... You need to go through the data sheet and the Application Note from Microship entitled "Using the UART". There is no problem. And if you really want help then mail me the code that you are using with some detail of what you are trying to do.

I've interfaced PIC 126F87x with every kind of thing and it works beatuifully.

#### dperez79

##### Member level 1
rs232 pic 16f876 uart c

I need to communicate a Camerra with the micro PIC. The camera receives the characters sent via RS232 by the micro, but when the camera answers then the micro only can receive one answer, the next answer it doesn't can be read by tha micro.
I'm using the CCSC compiler and the function gets() and getc().
How can I solve this problem?

#### gam

trmt rs232

The PIC error might be related to the error or overflow registers in the hardware UART. I don't remember the exact register names, so go to the Datasheet, the part describing the UART. These registers must be cleared by SW.

Regards,

#### raticus

##### Member level 4
pic16 usart interrupt corrupt

There are so many excellent application-notes,and software for using the uart on microchip's website.
Why dont you look there.
There is an application called "maestro" which they give you for free,to automatically generate code that works for most pic peripherals,including the uart.

Pics do not have baud-rate problems.The BRGH bit in the TXSTA register decides which formula the pic uses to get the baud-rate as close as possible,depending on the freq. of your crystal.
If you want 100% accurate uart baud,use the correct xtal.
5.068Mhz will give you 100% baud at 9600.
For synchronous uart SPBRG val should be d'131'
For asynchronous uart SPBRG val should be d'32' with BRGH=1

Basically,you have a framing-error.
The human who wrote your compiler was not as good as he thought he was.

#### gam

getch cren

I had a similar problem when trying the UART on PIC16F628, I then wrote the RX/TX code parts in assembly (embedded in C source) and it worked. I f you do this you can trace back the problem (compiler, intilaization,..?)

If you want it I can send you the assembly parts for testing your code.

Regards,

GAM

#### MyRDS

##### Newbie level 6
pic16f876 interrupt c compiler

May your RX buffer is full ?

#### Humber555

##### Member level 2
ccs kbhit rcif

Code:
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,BRGH1OK)
You do not need the parameters parity and bits, by default this compiler assume the format 8N1
(data: 8 bits, No Parity, 1 StopBit)

Use the following:
Code:
#use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7,ERRORS,BRGH1OK)
In your case, it´s very important to include the parameter ERRORS to handle framming errors.
The ERRORS parameter directs the compiler to handle UART errors and update a variable with the error status.

You didn't post your interrupt handler, so I assume you are catching characters on the fly, in that case prior to receive the stream, disable all interrupts except the following:

Code:
           enable_interrupst(INT_RDA);
enable_interrupts(GLOBAL);

void main()
{

while(1)
{
if(kbhit())
{
c = getc();
}

printf("%c",c);
}
}

Some C compilers, when you use the RS232 definition line, emulates the UART by software, instead of using the hardware UART.
Be careful with that.

Not true in this case, the included preprocessor directive xmit=PIN_C6,rcv=PIN_C7 tell the compiler to use the internal UART

humber555

Status
Not open for further replies.