# include <stdio.h> # include <aduc842.h> #pragma registerbank(2) void sendmoduleinit(void); void InitByte_Char (volatile unsigned long); void print2uart_hex(int); void displaytemp1(void); void displaycal(void); void sendremaining(void); volatile unsigned char moduleinit; int ucRxChar1; int check_sum; int check_sum_tx; void main() { EA = 1; ES = 1; T3CON = 0x83; T3FD = 0x2D; SCON = 0x50; if(ucRxChar1 == 0xCC) { sendmoduleinit(); } if (ucRxChar1 == 0xFA && ucRxChar1 == 0xFA && ucRxChar1 == 0x05 && ucRxChar1 == 0xAA && ucRxChar1 == 0x2F) {displaytemp1(); } if (ucRxChar1 == 0x05 && ucRxChar1 == 0xAB) {displaycal(); } } void ISR_sc(void) interrupt 4 using 2 { if (TI==1) { TI=0; //clear interrupt } else { ucRxChar1 = SBUF; //put value on pins RI=0; //clear interrupt } /*REN = 1; while(RI == 0) {} ucRxChar1 = SBUF; RI = 0; */ } void sendmoduleinit(void) { check_sum = (0xF5 ^ 0xF5 ^ 0x06 ^ 0xFF ^ 0xFF); check_sum_tx = (check_sum & 0x7F); InitByte_Char(0xF5); InitByte_Char(0xF5); InitByte_Char(0x06); InitByte_Char(0xFF); InitByte_Char(0xFF); print2uart_hex(check_sum_tx); } void InitByte_Char (volatile unsigned long result) { REN = 0; SBUF = result; while (TI == 0) { } TI = 0; REN = 1; } void print2uart_hex(int chksum) { REN = 0; SBUF = chksum; while (TI == 0) { } TI = 0; REN = 1; } void displaytemp1(void) { check_sum =(0xA0 ^ 0xE2 ^ 0x07 ^ 0x00 ^ 0x62 ^ 0x00); check_sum_tx = (check_sum & 0x7F); InitByte_Char(0xA0); InitByte_Char(0xE2); InitByte_Char(0x07); InitByte_Char(0x00); sendremaining(); //InitByte_Char(0x62); // InitByte_Char(0x00); // print2uart_hex(check_sum_tx); } void sendremaining(void) { InitByte_Char(0x62); InitByte_Char(0x00); print2uart_hex(check_sum_tx); } void displaycal(void) { check_sum =(0xA0 ^ 0xE2 ^ 0x07 ^ 0x00 ^ 0x25 ^ 0x00); check_sum_tx = (check_sum & 0x7F); InitByte_Char(0xA0); InitByte_Char(0xE2); InitByte_Char(0x07); InitByte_Char(0x00); InitByte_Char(0x25); InitByte_Char(0x00); print2uart_hex(check_sum_tx); }
This is my code. Over here I am trying to read bytes into SBUF and depending upon bytes received I am trying to send some packets. My code is working but reading into SBUF is taking time... Reading a single byte is not taking time but reading an entire packet takes time can u suggest some alternative soln regards Mayuri
The speed of the UART is controlled by the baudrate.
If you want to be able to send data quicker, you must select a higher baudrate.
If you want to receive data quicker, you must select a higher baudrate.
Note, that a higher baudrate just means that a single character gets transmitted faster. The other side can still decide to wait before it sends the next character.
When transmitting, you can add a ring-buffer. This allows your program to just enqueue the outgoing data and have your interrupt handler pick up the next enqueued character when you get an interrupt that the UART is ready for more.
This allows "instant" transmission, as seen by your main program loop, unless it tries to send so much data that the ringbuffer gets full - then the speed will slow down to the speed decided by the UART baudrate.
Your code is almost impossible to read because of the indentation issues. You should switch your editor to indent with spaces, and then clean up all indentations and post again.
But unless I have missed counting { and } in your code, it seems like your UART interrupt handler have a busy-loop for receiving data. You do not (!) want any busy-loop in the interrupt handler. Let the UART generate an interrupt when it has data. Don't try to get data when none is there. Remember that it can take hours, or even years, until a character arrives.
Another interesting thing is that you let the main loop use polling for sending data. But your UART ISR makes use of both RI and TI in a rather interesting way. Do you really think you can look at TI to decide if there is data to read?
My code is working but reading into SBUF is taking time...
It's not the reading into SBUF that is taking time. It's the way your grabbing it and then checking for a specific sequence of characters.
if (ucRxChar1 == 0xFA && ucRxChar1 == 0xFA && ucRxChar1 == 0x05 && ucRxChar1 == 0xAA && ucRxChar1 == 0x2F)
You need to revisit this code and consider how characters are received by the processor.
Working? Really?
How can ucRxChar1 equal 0xFA, 0x05, 0xAA, and 0x2F all that the same time?
Also there's that little problem of running off the end of main().
Some better compilers would notice that above expression can never be true, and warn about unreachable code.
But there are lots of interesting things with this code - for example why it constantly turns on/off the UART receiver. Is RX and TX of the UART connected together, so you need to stop the UART from hearing its own transmission?
Some people define "working" as: tools managed to compile/link to a binary.
My protocol is like that. I should receive entire packet.. Packet consists of many bytes..
Thats the reason I am checking by if condition whether SBUF has received those bytes or not.
Is there any other way to check the received packet?
The receive side of SBUF has room for one (1) character.
And when you read from SBUF once (1 time), you "consume" that character.
Don't see SBUF as a memory variable. See it as a door. If someone rings on the door bell, you know someone is there. So you can open the door, reach in and invite one person through the door. Then the door closes, and you wait for another person to arrive and press the door bell.
So you need a buffer - for example a standard C array - where you store the received characters one-by-one until you either detects a complete packet, or your buffer gets full, in case you probably have a protocol error, transfer error or just too small receive buffer.
Same as when you are going to have a party - you let in people and then needs a sofa or chairs for the visitors to sit down as they arrive.
Same as when you are going to have a party
What a beautiful description of the algorithm :)
As per your advice I am using array for getting the entire packet. My ISR is as follows:
void ISR_sc(void) interrupt 4 using 2 { if (TI==1) { TI=0; //clear interrupt } else { for (i=0;i<5;i++) { while (RI == 0) {} ucRxChar1[i] = SBUF; //put value on pins RI=0; //clear interrupt } } }
Thnx for ur advice ..The code is working too..I am able to receive entire packet..
I have 1 more issue.My protocol is such that i may get a single byte(0xCC) or entire packet of 5 bytes.
so i tried to modified my code.
void ISR_sc(void) interrupt 4 using 2 { if (TI==1) { TI=0; //clear interrupt } else { for (i=0;i<5;i++) { while (RI == 0) {} ucRxChar1[i] = SBUF; //put value on pins RI=0; //clear interrupt if (ucRxChar1[0] == 0xCC) { break; } if (ucRxChar1[0] != 0xCC) { continue; } } } }
This seems to be working too..reading packet is fast but reading a single byte 0xCC is taking time... wht may be the reason??
Regards Mayuri
The reason?
The reason is that you haven't spent time reading previous answers.
You just should not have an interrupt routine that stays, waiting for multiple characters to arrive. If next character does not arrive, the ISR will continue to wait while your main program is locked up.
So the ISR checks if there is a character available, and adds it to the receive buffer. Then exists.
And the main loop check what contents there are in the receive buffer - if there is one byte, the main loop checks if that byte is a one-byte message, or if more data needs to be received before the complete message can be processed. And if more data is expected, then the main loop keeps track of a timeout counter - if more data doesn't arrive within reasonable time (maybe someone disconnected the serial cable) then the main loop have to clear the receive buffer.
And since the ISR is "producer" and main loop is "consumer", you should look at a circular buffer - also known as a round-robin buffer. It has the advantage that the producer (ISR) is owner of the write/insertion position. And the consumer (main loop) is owner if the read/delete position. So it doesn't matter what the main loop is busy doing - the ISR may kick in at any time and can modify the insertion position without creating any timing issues.
My protocol is as follows:
Initially Host sends 0xCC to my module.
It means that my module should receive CC and send some packet X.
When Host receives packet X, it will send packet Y of 5 bytes to the module.
CC byte will come only once . I may get packet Y any time...
I am able to read packet Y Y does reading CC takes time?
since I dont have host (mother board) ready, I am checking this handshaking in doclight. I am using doclight as my host over there I have to continuously send CC to my module to get packet X.
TX - CC TX - CC TX - CC TX - CC TX - CC TX - CC TX - CC RX - F5 F5 06 FF FF TX - FA FA 05 AA 2F RX - A0 E2 07 63 D3
Are you understanding what I'm writing? At all?
Actually I am a fresher and there is no one to help me out.
pls help me out
So, have you read the answer above? They contain all the help you need!
My problem is solved now.
I have used while loop instead of for loop