EmbeddedRelated.com
Forums

It is possible for 89C51 to receive 7-bit RS232 data?

Started by jusmansulaiman November 14, 2008
I am building a Remote Large Display for a weighing machine. The weighing
machine continuously send out readout data of the weight it measures via an
RS-232 port, which I intend to connect to my 89C51-controlled 5 digit
7-segment display.

Unfortunately, the weighing machine can only communicate in 2400Bps 7-bit
even parity format. I have tested my display successfully with
Hyperterminal program at 2400Bps, 8bit, even parity format. I connected the
display to the weighing machine, and no wonder that it only displayed
garbage because of the frame error. The Atmel Datasheet does not mention
about 7-bit format.

Is there any solution for my problem? Please help...!


jusmansulaiman wrote:

> Unfortunately, the weighing machine can only communicate in 2400Bps 7-bit > even parity format.
7 bit even parity: so set it for 8 bit, no parity, and strip the MSB of the characters that come in. You can use it to check the parity (by lookup table) if you're anal or the boss is standing over you. If you have to transmit to it, calculate the parity (by lookup table) and OR it with the transmitted character. JS
"jusmansulaiman" <jusmansulaiman@yahoo.com> wrote in message 
news:WrqdnVzw2eSW7oDUnZ2dnUVZ_r3inZ2d@giganews.com...
>I am building a Remote Large Display for a weighing machine. The weighing > machine continuously send out readout data of the weight it measures via > an > RS-232 port, which I intend to connect to my 89C51-controlled 5 digit > 7-segment display. > > Unfortunately, the weighing machine can only communicate in 2400Bps 7-bit > even parity format. I have tested my display successfully with > Hyperterminal program at 2400Bps, 8bit, even parity format. I connected > the > display to the weighing machine, and no wonder that it only displayed > garbage because of the frame error. The Atmel Datasheet does not mention > about 7-bit format. > > Is there any solution for my problem? Please help...! > >
Yes, implement the comms in software.... instead of using the on board UART. You can still use the RXD pin.
>jusmansulaiman wrote: > >> Unfortunately, the weighing machine can only communicate in 2400Bps
7-bit
>> even parity format. > >7 bit even parity: so set it for 8 bit, no parity, and strip the MSB of >the characters that come in. You can use it to check the parity (by >lookup table) if you're anal or the boss is standing over you. > >If you have to transmit to it, calculate the parity (by lookup table) >and OR it with the transmitted character. > >JS >
JS, Thank you very much for your suggestion. I am surprised that the solution is very simple. Furthermore I don't need to transmit to the machine, and don't use the parity bit. My working code with 2400,8,n (using PC as terminal) was : mov a,87h orl a,#10000000b mov 87h,a mov SCON,#50h mov TMOD,#20h mov TH1,#E8h setb TR1 I understand that the databits are received with LSB first, then the parity bit, so that when the character is received in SBUF, the parity is the MSB. So I use the above code and just AND the SBUF with 7Fh. However, when I set the terminal at 2400,7,e and sent characters to the display, it still didn't work. Please advice if you have any other idea, and thanks for your help.
jusmansulaiman wrote:
> I am building a Remote Large Display for a weighing machine. The weighing > machine continuously send out readout data of the weight it measures via an > RS-232 port, which I intend to connect to my 89C51-controlled 5 digit > 7-segment display. > > Unfortunately, the weighing machine can only communicate in 2400Bps 7-bit > even parity format.
Has this been verified? You connected hyperterminal to the weighing machine at 7-bit, even parity and hyperterminal prints the chars out to the PC screen OK? By the way, you may want to try another terminal program. I've had issues in the past with hyperterminal. Try Docklight(this is my favorite, not free but eval mode will work for you) or TeraTerm (free). > I have tested my display successfully with
> Hyperterminal program at 2400Bps, 8bit, even parity format.
Here, you state that Hyperterminal has been set to 8bit, even parity. This seems to be contradict what you were saying as to the weighing machine being 7bit/even. Are you saying that when Hyperterminal is 'sending' data to your display, all is OK? If this is true, it appears that your display is set for 9 bit mode. As I understand things, 8bit/even parity implies 9 bits being sent. Your code shows that SCON is set to 8 bit mode (0x50), so I am confused here. >I connected the
> display to the weighing machine, and no wonder that it only displayed > garbage because of the frame error. The Atmel Datasheet does not mention > about 7-bit format.
The 8051 uarts are not as sophisticated as the PC uarts (8250,etc). All parity processing is done in your firmware. The 8051 can only rcv/xmt either 8 or 9 data bits. How you 'deal' with these bits are up to you.
> > Is there any solution for my problem? Please help...! > >
It looks like we are missing something fundamental here... If your weighing machine is indeed 7bits, even parity, then it would be sending: Start bit / 7 data bits / 1 parity bit / Stop bit So, you would set up your 8051 to 8 bit mode, which it appears you do. You would receive the data and 'strip' off the MSB (and with 7fh). Leaving the 7bit ascii char for you to process. Good luck and email with other questions if you want. Jim
jusmansulaiman wrote:
> I am building a Remote Large Display for a weighing machine. The
weighing
> machine continuously send out readout data of the weight it measures via
an
> RS-232 port, which I intend to connect to my 89C51-controlled 5 digit > 7-segment display. > > Unfortunately, the weighing machine can only communicate in 2400Bps
7-bit
> even parity format.
Has this been verified? You connected hyperterminal to the weighing machine at 7-bit, even parity and hyperterminal prints the chars out to the PC screen OK? By the way, you may want to try another terminal program. I've had issues in the past with hyperterminal. Try Docklight(this is my favorite, not free but eval mode will work for you) or TeraTerm (free). > I have tested my display successfully with
> Hyperterminal program at 2400Bps, 8bit, even parity format.
Here, you state that Hyperterminal has been set to 8bit, even parity. This seems to be contradict what you were saying as to the weighing machine being 7bit/even. Are you saying that when Hyperterminal is 'sending' data to your display, all is OK? If this is true, it appears that your display is set for 9 bit mode. As I understand things, 8bit/even parity implies 9 bits being sent. Your code shows that SCON is set to 8 bit mode (0x50), so I am confused here. >I connected the
> display to the weighing machine, and no wonder that it only displayed > garbage because of the frame error. The Atmel Datasheet does not
mention
> about 7-bit format.
The 8051 uarts are not as sophisticated as the PC uarts (8250,etc). All parity processing is done in your firmware. The 8051 can only rcv/xmt either 8 or 9 data bits. How you 'deal' with these bits are up to you.
> > Is there any solution for my problem? Please help...! > >
It looks like we are missing something fundamental here... If your weighing machine is indeed 7bits, even parity, then it would be sending: Start bit / 7 data bits / 1 parity bit / Stop bit So, you would set up your 8051 to 8 bit mode, which it appears you do. You would receive the data and 'strip' off the MSB (and with 7fh). Leaving the 7bit ascii char for you to process. Good luck and email with other questions if you want. Jim jusmansulaiman wrote:
> I am building a Remote Large Display for a weighing machine. The
weighing
> machine continuously send out readout data of the weight it measures via
an
> RS-232 port, which I intend to connect to my 89C51-controlled 5 digit > 7-segment display. > > Unfortunately, the weighing machine can only communicate in 2400Bps
7-bit
> even parity format.
Jim Flanagan wrote:
> Has this been verified? You connected hyperterminal to the weighing > machine at 7-bit, even parity and hyperterminal prints the chars > out to the PC screen OK?
The Weighing Machine (WM) can only sending characters which resembling the weight of thing put on it, with the format ST,NT,+NNNNNN when weighing is stable and US,NT,+NNNNNN where NNNNNN is 6 digit numeric, and the plus sign can also negative. I set Hyper Terminal (HT) at 2400,7,e and yes the HT prints the characters at the PC screen. Jim Flanagan wrote:
> By the way, you may want to try another terminal program. I've had > issues in the past with hyperterminal. Try Docklight(this is my > favorite, not free but eval mode will work for you) or TeraTerm (free).
Thanks, I will look for the Docklight and Teraterm and see if I could enrich my tools with it. In fact, I also often use DOS-based terminal program which I took from the excellent book Advanced MSDOS by Ray Duncan (Microsoft Press, 1986). I typed the source code and assembled to yield a fast and flexibel terminal program.
> I have tested my display successfully with > Hyperterminal program at 2400Bps, 8bit, even parity format.
Jim Flanagan wrote:
> Here, you state that Hyperterminal has been set to 8bit, even > parity. This seems to be contradict what you were saying as to the > weighing machine being 7bit/even.
> Are you saying that when Hyperterminal is 'sending' data > to your display, all is OK? If this is true, it appears that your > display is set for 9 bit mode. As I understand things, 8bit/even > parity implies 9 bits being sent. Your code shows that SCON is set > to 8 bit mode (0x50), so I am confused here.
I meant, I previously program my 89C51 based display at 2400,8,e to be tested with HT. If I had successfully tested my receive-only display with HT at 2400,8,e I wanted to say that I was just one step away from successfully testing it with HT at 2400,7,e, with reprogramming and doing trial and error. In turn, by itself it will talk to the WM, (my goal). Yes, I configured my display for 8 bit mode, and it can display numeric characters sent by the PC at 2400,8,n or at 2400,8,e. Both displayed correctly. Jim Flanagan wrote:
> So, you would set up your 8051 to 8 bit mode, which it appears you do. > You would receive the data and 'strip' off the MSB (and with 7fh). > Leaving the 7bit ascii char for you to process.
Yes, to the lines : FetchCharacter: jnb RI,FetchCharacter clr RI mov A,SBUF ret I added anl A,#7Fh before the ret, so as to strip off the parity bit appeared at 7th bit at the data. Then I substracted it with 30h and used it as a pointer to a lookup table. call FetchCharacter subb A,#30h mov DPTR,#Table1 movc A,@A+DPTR . . But it didnt work. Valid data are prefixed by the signature ST, and first I took only the character S for the program to process the 6 byte numeric data began at 7th byte. When I left the S unstripped, the program acknowledge the S character and went to the 7th byte. Later, I realized that the S character had parity bit "0" so it is the same whether you strip it or not. I found that the "ANL A,#7Fh" could not work at all. For the numeric data I tried with : ANL A,#00001111b and delete the useless sub A,#30h. It worked OK !! Later I realized that I had to take both characters ST for the signature, otherwise if only the S, my program would regard the S of the unstable US,NT,+NNNNNN as prefix to valid data. The S could be left unstripped, but the T had parity bit "1". Again, "ANL A,#7Fh" could not work for stripping the T. So I tried changing the line CJNE A,#54h,WaitForChar ; T signature? No, wait again for character to: CJNE A,#0D4h,WaitForChar and my program worked!!! I had no time to think about why the "ANL A,#7Fh" could not work, so I simply change it to "ANL A,#7Fh" which worked OK because I had to quickly finish my display. More over I had to further enable my program to suppress leading 0 for the 5 digit display. Thanks Jim for your suggestion and attention.
>jusmansulaiman wrote: > >> Unfortunately, the weighing machine can only communicate in 2400Bps
7-bit
>> even parity format. > >7 bit even parity: so set it for 8 bit, no parity, and strip the MSB of >the characters that come in. You can use it to check the parity (by >lookup table) if you're anal or the boss is standing over you. > >If you have to transmit to it, calculate the parity (by lookup table) >and OR it with the transmitted character. > >JS >
At last I can finish my program for 89C51 based Remote Display. Yes, the solution to my problem is only to strip the parity bit appeared as the 7th bit before the 7bit data. But strangely the : ANL A,#7Fh didn't work, so since I only wanted the pointer to a lookup table, I stripped the high 4 bits altogether : ANL A,#0Fh and the program now worked OK. Thanks for your suggestion and attention.
> >"jusmansulaiman" <jusmansulaiman@yahoo.com> wrote in message >news:WrqdnVzw2eSW7oDUnZ2dnUVZ_r3inZ2d@giganews.com... >>I am building a Remote Large Display for a weighing machine. The
weighing
>> machine continuously send out readout data of the weight it measures
via
>> an >> RS-232 port, which I intend to connect to my 89C51-controlled 5 digit >> 7-segment display. >> >> Unfortunately, the weighing machine can only communicate in 2400Bps
7-bit
>> even parity format. I have tested my display successfully with >> Hyperterminal program at 2400Bps, 8bit, even parity format. I connected
>> the >> display to the weighing machine, and no wonder that it only displayed >> garbage because of the frame error. The Atmel Datasheet does not
mention
>> about 7-bit format. >> >> Is there any solution for my problem? Please help...! >> >> >Yes, implement the comms in software.... instead of using the on board
UART.
>You can still use the RXD pin. > >TTMan, >I did intend to implement software solution for connecting my 89C51 based
Remote Display to a Weighing Machine running at 2400,7,e, if employing the UART of the 89C51 all failed. Previously I did building Remote Display with software driven RS-232, with the PIC1684. I took the code from the Internet and it worked OK although the baud-rate was determined only by R and C instead of crystal. So then hopefully I could migrate the code to 89C51. However, now I had finished my 89C51 program successfully, and the Remote Display now works OK. Thank you for your suggestion and attention. Jusman
> > Jim Flanagan wrote: >> So, you would set up your 8051 to 8 bit mode, which it appears you do. >> You would receive the data and 'strip' off the MSB (and with 7fh). >> Leaving the 7bit ascii char for you to process. > > Yes, to the lines : > FetchCharacter: > jnb RI,FetchCharacter > clr RI > mov A,SBUF > ret > I added > anl A,#7Fh > > before the ret, > > so as to strip off the parity bit appeared at 7th bit at the data. Then I > substracted it with 30h and used it as a pointer to a lookup table. > call FetchCharacter
YOU NEED TO CLEAR THE CARRY HERE AS THE SUBB INSTRUCTION IS - SUBTRACT WITH BORROW. >>> clr c <<<
> subb A,#30h > mov DPTR,#Table1 > movc A,@A+DPTR > . > . > But it didnt work. > > Valid data are prefixed by the signature ST, and first I took only the > character S for the program to process the 6 byte numeric data began at 7th > byte. When I left the S unstripped, the program acknowledge the S character > and went to the 7th byte. Later, I realized that the S character had parity > bit "0" so it is the same whether you strip it or not. > > I found that the "ANL A,#7Fh" could not work at all. For the numeric data > I tried with : > > ANL A,#00001111b >
If this worked and the subb didn't that tells me the 'carry' not being cleared probably caused your subb to not work correctly
> and delete the useless sub A,#30h. It worked OK !!
You mean subb?
> Later I realized that I had to take both characters ST for the signature, > otherwise if only the S, my program would regard the S of the unstable > US,NT,+NNNNNN as prefix to valid data. The S could be left unstripped, but > the T had parity bit "1". > > Again, "ANL A,#7Fh" could not work for stripping the T. So I tried > changing the line
You DO need to strip the bit off here. You are only interested in the lower 7 bits. 'S' = 0x53 'T' = 0x54
> > CJNE A,#54h,WaitForChar ; T signature? No, wait again for character > to: > CJNE A,#0D4h,WaitForChar
This should work - Waitfor_ST: call FetchCharacter cjne A,#'S',Waitfor_ST call FetchCharacter cjne A,#'T',Waitfor_ST
> > and my program worked!!! > > I had no time to think about why the "ANL A,#7Fh" could not work, so I > simply change it to "ANL A,#7Fh" which worked OK because I had to quickly > finish my display. More over I had to further enable my program to suppress > leading 0 for the 5 digit display. > > Thanks Jim for your suggestion and attention. >
> >> >> Jim Flanagan wrote: >>> So, you would set up your 8051 to 8 bit mode, which it appears you
do.
>>> You would receive the data and 'strip' off the MSB (and with 7fh). >>> Leaving the 7bit ascii char for you to process. >> >> Yes, to the lines : >> FetchCharacter: >> jnb RI,FetchCharacter >> clr RI >> mov A,SBUF >> ret >> I added >> anl A,#7Fh >> >> before the ret, >> >> so as to strip off the parity bit appeared at 7th bit at the data. Then
I
>> substracted it with 30h and used it as a pointer to a lookup table. >> call FetchCharacter > > YOU NEED TO CLEAR THE CARRY HERE AS THE SUBB INSTRUCTION > IS - SUBTRACT WITH BORROW. > > > >>> clr c <<< > >> subb A,#30h >> mov DPTR,#Table1 >> movc A,@A+DPTR >> . >> . >> But it didnt work. >> >> Valid data are prefixed by the signature ST, and first I took only the >> character S for the program to process the 6 byte numeric data began at
7th
>> byte. When I left the S unstripped, the program acknowledge the S
character
>> and went to the 7th byte. Later, I realized that the S character had
parity
>> bit "0" so it is the same whether you strip it or not. >> >> I found that the "ANL A,#7Fh" could not work at all. For the numeric
data
>> I tried with : >> >> ANL A,#00001111b >> > If this worked and the subb didn't that tells me the 'carry' not >being cleared probably caused your subb to not work correctly > >> and delete the useless sub A,#30h. It worked OK !! > You mean subb? > > >> Later I realized that I had to take both characters ST for the
signature,
>> otherwise if only the S, my program would regard the S of the unstable >> US,NT,+NNNNNN as prefix to valid data. The S could be left unstripped,
but
>> the T had parity bit "1". >> >> Again, "ANL A,#7Fh" could not work for stripping the T. So I tried >> changing the line > You DO need to strip the bit off here. > You are only interested in the lower 7 bits. > 'S' = 0x53 > 'T' = 0x54 >> >> CJNE A,#54h,WaitForChar ; T signature? No, wait again for character >> to: >> CJNE A,#0D4h,WaitForChar > > This should work - > Waitfor_ST: > call FetchCharacter > cjne A,#'S',Waitfor_ST > call FetchCharacter > cjne A,#'T',Waitfor_ST >> >> and my program worked!!! >> >> I had no time to think about why the "ANL A,#7Fh" could not work, so I >> simply change it to "ANL A,#7Fh" which worked OK because I had to
quickly
>> finish my display. More over I had to further enable my program to
suppress
>> leading 0 for the 5 digit display. >> >> Thanks Jim for your suggestion and attention. >> > >> call FetchCharacter
YOU NEED TO CLEAR THE CARRY HERE AS THE SUBB INSTRUCTION IS - SUBTRACT WITH BORROW. >>> clr c <<< Yes Jim, you are right. I have carefully read again the 89C51 instruction set, and realize that my mistake was ignoring the Carry Flag in the SUBB instruction. The datasheet says that : Subb A,#54h where A is 0C9h, actually leave the value 074h in the Accumulator and Carry and AC flag cleared but OV set. 0C9h minus 54h is 75h, and the difference is due to the Carry Flag being set before the operation. So, in my code : FetchCharacter: jnb RI,FetchCharacter clr RI mov A,SBUF anl A,#7Fh ret call FetchCharacter subb A,#30h mov DPTR,#Table1 movc A,@A+DPTR . . I should insert "CLR C" before the line "SUBB A,#30h". I want to modify my program and test it on the display, but unfortunately yesterday I had sent the display to my customer. My last program with "ANL A,0Fh" worked because I didn't need to employ the SUBB instruction. Thank you very much Jim, I guess I have to learn and practice a lot more. Jusman