i tried to send data, through serial data communication, from one Microcontroller[Atmel 8052 - AT89c52] to another Microcontroller[Atmel 8052 - AT89c52] and back to the source Microcontroller and then display the data on a LCD[16x2]. both the Microcontrollers have 12Mhz crystal and the baud rate is 2,400, and i have calculated the reload value for TH1 in mode 2[auto-reload mode] as, 256-[12E6/(32 x 12 x 2400)]=242.98, which is rounded off to the nearest integer 243. By doing this i am not getting the expected result. the output on the LCD is some junk value[looks v.weird]. what could b the problem???
what could be the problem??? That the wind was blowing from the west. as good a guess as any based on the information you are NOT giving. Erik
"what could be the problem???" 1. The 1st microcontroller is not transmitting the original data properly; 2. The 2nd microcontroller is not receiving the original data properly; 3. The 2nd microcontroller is not transmitting the "echo" data properly; 4. The 1st microcontroller is not receiving the "echo" data properly; 5. Your LCD code and/or hardware doesn't work. So now you should see an obvious step-by-step process for you to get your system working...
8051 Baud rate calculator: http://www.keil.com/support/docs/1905.htm
The code on the 1st Microcontroller:
/*AT80c52 connected to OD-DM1602-f LCD P0 = Data P2.0 = RS P2.1 = R/W P2.2 = E */ #include<reg51.h> sbit p20=P2^0; sbit p21=P2^1; sbit p22=P2^2; sbit f=P0^7; data char i _at_ 0x30; data char val _at_ 0x31; void ready() { f=1; p20=0; p21=1; do { p22=0; p22=1; }while(f); return; } void comm(int n) { ready(); P0=n; p20=0; p21=0; p22=1; p22=0; return; } void dat(int n) { ready(); P0=n; p20=1; p21=0; p22=1; p22=0; return; } void intr(void) interrupt 4 using 3 { if(RI==1) { RI=0; for(i;i<=0x5a;i++) { SBUF=i; if(i==0x5a) i=0x40; } } if(TI==1) { TI=0; val=SBUF; dat(val); } } void main() { comm(0x38); comm(0x0e); comm(0x01); PCON=0x00; TMOD=0x20; TH1=0xf3; TR1=1; SCON=0x50; IE=0x90; i=0x42; SBUF='A'; while(1); }
#include<reg51.h> data char val _at_ 0x30; void intr(void) interrupt 4 using 3 { if(TI==1) { TI=0; val=SBUF; SBUF=val; } if(RI==1) RI=0; } void main() { PCON=0x00; TMOD=0x20; TH1=0xf3; TR1=1; SCON=0x50; IE=0x90; while(1); }
Hi, You say 'a. The data is going out of the 1st Microcontroller.' All I can see is that 'A' is transmitted to the slave and nothing else - is this what you intended?. In the intr routine, for processing if(TI ==1), you should NOT (and cannot) read SBUF to determine what has just been transmitted as you are reading what SBUF has received (if anything) and thus it may be completly different data to that that you have transmitted! You say 'b. The data is being recived by the 2nd Microcontroller.', from above only one character the 'A' is received by the slave but when you process if (RI ==1) you dont bother reading what you have received to transmit it back out, so move the 'val=SBUF; SBUF=val;' from if(TI==1) to the if(RI==1) section of the code. From the problems detailed in 'a.' and 'b.' above, 'c.' and 'd.' are not true! There are other things that are wrong with your code but if you correct these points above then you should be much further along with your program, but if you still need further help once you have made any revisions then post the revised code and i will try to offer further help. Hope this helps, Mark. P.S. An after thought, is the h/w also correct and is TX linked to RX on the opposite micro?
The nugget of wisdom here is Mr, Neil's dissection of the problem. You need to slice this loaf of bread into edible portions, and it is a sizeable loaf. That being said, let me get to your question. You wonder if there is a baudrate mismatch between the two micros because of the rounding error. That error is the same between the two devices so it really comes down to the two crystals, usually a tight tolerance so your problem probably lies elsewhere but ... If a man's best friend is his dog, an EEs best friend is his scope, so get out yours and connect the TX line of micro #1 to the scope channel #1 and trigger on it. Set up your code to periodically ( timer # whatever ) transmit 0xAA or 0x55. Measure the pulse width of an individual bit. Do the same for micro #2. Compare the widths. They WILL be within the % tolerance specified in the micro datasheet. If not set the timer 1 value for double ( or half ) the baudrate and remeasure, is the measured value double or half? If the error is here( which it probably isn't) double check the crystal, timer setup, capacitors, etc. That said, have you compared the timing specs of the LCD display to your routines above? those device are typically quite slow. Have you tried a loopback connection on micro #1? How do you REALLY know a micro is transmitting or receiving the right byte? Have you used a scope or a port bit as a TX-RX comparison flag?
"IS the problem because of the using the 12Mhz crystal [insted of 11.0592], as the reload value is being rounded off to 243 from 242.98???????" Just look at the Keil baudrate calculator - it tells you what the error is. Anyhow, if both micros are using the same clock frequency and the same baudrate generator setup, it's irrelevant!
hai, thanks Mark. And the h/w connection is properly made, i.e, the Tx and Rx of the 1st Microcontroller are connected to the Rx and Tx pin, respectively, of the 2nd Microcontroler.
Upon receipt of its first byte, 1st MCU will begin writing to SBUF without any pacing, sequential values from 0x42 through 0x5A and then loop forever writing to SBUF without any pacing, sequential values 0x41 through 0x5A. That doesn't seem good, does it? As a side note, your code has a distinct look of your trying use C as if it were assembly language. It's probably not a concern in this very constrained case, but I would be asking myself "how do I know the compiler is not using locations 0x30-31 itself? Where is the compiler locating the stack?" In other cases, you should be very concerned about your style of program design.
Thank you Dan, dat probably is the dummest thing i have done in a program till date.
"Thank you Dan, dat probably is the dummest thing i have done in a program till date." I'm glad that I am not the only one who does dumb things now and then. I have to admit that on Friday just last week, I had a moment of weakness worthy of slapping my forehead (or worse having someone else slap it for me)! :-)
"I'm glad that I am not the only one who does dumb things now and then. I have to admit that on Friday just last week, I had a moment of weakness worthy of slapping my forehead (or worse having someone else slap it for me)! :-) " Lol, n now i am glad to know dat i am not the only 1 who dose dum thinks. Thanks any ways Dan. I'll post the entire code of my project, once completed, on this thread. Bye for now.