Discussion in "8051 Discussion Forum" started by    Suilied    Apr 18, 2014.
Fri Apr 18 2014, 08:45 pm
#1
Hello,

I'm having trouble getting rs232 communication working with my AT89C51cc03.
The baudrate seems to be working just fine because I can see the rx LEDs light up whenever I send something. However I need to send the data as follows: 1 start bit, 7 data bits, 1 even parity bit and 1 stop bit.

Here is a small snippet that shows part of the implementation I copied from a colleague, it shows the tx function with uneven parity.

<cant seem to format the code in a readable fassion so here's a screenshot instead>

Wed Apr 23 2014, 10:28 am
#2
the RX LED will lit up even if you have wrong baudrate setup. I would prefer to see the uart initialization code instead as I do not see any issue in this sending loop.
Wed Apr 23 2014, 10:29 am
#3
[Topic moved to 8051 Discussion Forum]
Wed Apr 23 2014, 04:12 pm
#4

the RX LED will lit up even if you have wrong baudrate setup. I would prefer to see the uart initialization code instead as I do not see any issue in this sending loop. - See more at: http://www.8051projects.net/plugins/forum/forum_post.php?rp.63403#sthash.3I6QE0pe.dpuf



This code sits in a big assembly initialisation routine, and it works, because I managed to get sending messages in 7e1 format working!

Turns out that all I had to do was "format" my output stream.
Normally I'd send my data like this:

void ReadParameter() {

	uint i=0;

	com_buf[i++] = 0x04; // end of text
	com_buf[i++] = 0x30; // node address hi
	com_buf[i++] = 0x30; // node address lo
	com_buf[i++] = 0x30; // parameter address 0
	com_buf[i++] = 0x32; // parameter address 1
	com_buf[i++] = 0x30; // parameter address 2
	com_buf[i++] = 0x30; // parameter address 3
	com_buf[i++] = 0x05; // enquiry
	
	com_tx_start(i);
}

( "com_buf" is a global variable. )

I was thinking I'd need to do something low level in assembly in order to get communication working. When monitoring my outgoing data stream with "Realterm" ( highly recommend this program to debug any rs232 applications ) I found out that only some data would be received if I set it to 7e1 mode. Turns out that only the data with even parity got accepted. (duh)
So I made a little subroutine to parse my "com_buf" to be even parity.

void TxCalcParity( uint aSize ) {

	bit parity;
	uint i;
	for( i=0; i < aSize; i++ ) {
		parity = 0; // start out even
		parity = com_buf[i] & 0x40 ? !parity: parity;
		parity = com_buf[i] & 0x20 ? !parity: parity;
		parity = com_buf[i] & 0x10 ? !parity: parity;
		parity = com_buf[i] & 0x08 ? !parity: parity;
		parity = com_buf[i] & 0x04 ? !parity: parity;
		parity = com_buf[i] & 0x02 ? !parity: parity;
		parity = com_buf[i] & 0x01 ? !parity: parity;
		if( parity ) {
			com_buf[i] += 0x80;
		}
	}
}

Parity is checked on the MSB, so if it is uneven we add 0x80 ( 0b10000000 ) in order to make it's parity even.

Because you are now getting data back from the other machine you must not forget to also parse the incomming messages in order to filter out the parity bit. Luckily this is much easier to do:

void RxCalcParity( uint aSize ) {
	uint i;
	for( i=0; i < aSize; i++ ) {
		com_buf[i] = com_buf[i] & 0x7f; //remove parity bit
	}
}


I'm sure there is some sort of way to do this in the assembly part that I posted originally, but for now this yields statisfying results.

<edit: fixed image.>


[ Edited Wed Apr 23 2014, 04:16 pm ]
Fri Apr 25 2014, 09:52 am
#5
Now I understand the problem, Usually when you configure your UART to enable parity (even or odd) Uart controller generates parity bit according to data being sent. You do not have manually add parity bit to your data. But in case of 8051 as 7-bit mode is not there so you need to add the parity bit in your last bit to be sent.
To generate even parity, you need to count number of 1 bits in 7-bit data. if count is even, partiy is 1 else parity is 0.

	clr c		;we will check for bits in here
	mov r0, #0	;store 1 bits count
	mov r1, #8	;Loop for only 7 bits
	mov r2, #data	;keep copy of data
Loop:
	DJNZ r1, end_loop
	mov A, r2	;move data to acc
	RRC A		;shift LSB to carry
	JNC Loop	;skip if bit is not 1
	inc r0		;found 1, increment bit counter
	sjmp Loop
end_loop:
	; Now check for even or odd
	mov A, r0
	anl A, #1	;if LSB is 1 then its an odd number
	JNZ finish
	mov A, r2	;store parity
	anl A, #80H
finish:
	;end of parity calculate

Get Social

Information

Powered by e107 Forum System

Downloads

Comments

SamuelSmise
Thu Apr 25 2024, 09:56 am
DustinErele
Thu Apr 25 2024, 08:44 am
ztaletpzca
Wed Apr 24 2024, 11:19 pm
IrardlPex
Wed Apr 24 2024, 08:42 pm
Charlestehed
Wed Apr 24 2024, 05:20 pm
Robertgurse
Wed Apr 24 2024, 02:43 pm
Richardedils
Wed Apr 24 2024, 04:07 am
Malcolmaccek
Wed Apr 24 2024, 01:21 am