| Details |
Message |
|
Read-Only
Author Mayuri Ghosalkar
Posted 21-May-2012 11:12 GMT
Toolset C251
|
 Reading into SBUF is SLOW
Mayuri Ghosalkar
# 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
|
|
|
Read-Only
Author Per Westermark
Posted 21-May-2012 12:29 GMT
Toolset C251
|
 RE: Reading into SBUF is SLOW
Per Westermark
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?
|
|
|
Read-Only
Author Reluctant Consultant
Posted 21-May-2012 12:31 GMT
Toolset C251
|
 RE: Reading into SBUF is SLOW
Reluctant Consultant
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.
|
|
|
Read-Only
Author Per Westermark
Posted 21-May-2012 12:53 GMT
Toolset C251
|
 RE: Reading into SBUF is SLOW
Per Westermark
if (ucRxChar1 == 0xFA && ucRxChar1 == 0xFA && ucRxChar1 == 0x05 && ucRxChar1 == 0xAA && ucRxChar1 == 0x2F)
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?
|
|
|
Read-Only
Author Dan Henry
Posted 21-May-2012 12:52 GMT
Toolset C251
|
 RE: My code is working ...
Dan Henry
Working? Really?
if (ucRxChar1 == 0xFA && ucRxChar1 == 0xFA && ucRxChar1 == 0x05 && ucRxChar1 == 0xAA && ucRxChar1 == 0x2F)
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().
|
|
|
Read-Only
Author Per Westermark
Posted 21-May-2012 13:36 GMT
Toolset C251
|
 RE: My code is working ...
Per Westermark
Some people define "working" as: tools managed to compile/link to
a binary.
|
|
|
Read-Only
Author Mayuri Ghosalkar
Posted 24-May-2012 12:02 GMT
Toolset C251
|
 RE: My code is working ...
Mayuri Ghosalkar
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?
|
|
|
Read-Only
Author Per Westermark
Posted 24-May-2012 12:35 GMT
Toolset C251
|
 RE: My code is working ...
Per Westermark
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.
|
|
|
Read-Only
Author H Mackie
Posted 24-May-2012 13:13 GMT
Toolset C251
|
 RE: My code is working ...
H Mackie
Same as when you are going to have a party
What a beautiful description of the algorithm :)
|
|
|
Read-Only
Author Mayuri Ghosalkar
Posted 30-May-2012 06:59 GMT
Toolset C251
|
 RE: My code is working ...
Mayuri Ghosalkar
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
|
|
|
Read-Only
Author Per Westermark
Posted 30-May-2012 07:22 GMT
Toolset C251
|
 RE: My code is working ...
Per Westermark
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.
|
|
|
Read-Only
Author Mayuri Ghosalkar
Posted 30-May-2012 08:02 GMT
Toolset C251
|
 RE: My code is working ...
Mayuri Ghosalkar
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
|
|
|
Read-Only
Author Per Westermark
Posted 30-May-2012 09:42 GMT
Toolset C251
|
 RE: My code is working ...
Per Westermark
Are you understanding what I'm writing? At all?
|
|
|
Read-Only
Author Mayuri Ghosalkar
Posted 30-May-2012 09:46 GMT
Toolset C251
|
 RE: My code is working ...
Mayuri Ghosalkar
Actually I am a fresher and there is no one to help me out.
pls help me out
|
|
|
Read-Only
Author Tamir Michael
Posted 30-May-2012 10:20 GMT
Toolset C251
|
 RE: My code is working ...
Tamir Michael
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!
|
|
|
Read-Only
Author Per Westermark
Posted 30-May-2012 10:25 GMT
Toolset C251
|
 RE: My code is working ...
Per Westermark
I am helping you. I am saying that the ISR gets notified if there
exists one (1) received byte. So the ISR should only try to pick up
one (1) character.
It's irrelevant what the protocol looks like - let the main loop
worry about what characters are received - and when.
Next thing - haven't you realized that you can receive one random
character (maybe after insert of cable) and then get your 0xCC as
second character. But your code think it should look at first entry
of array for 0xCC. If you get a spurious character before the 0xCC,
you get into a deadlock until the other side for some reason sends
enough characters to get you out of your 5-character loop.
|
|
|
Read-Only
Author Mayuri Ghosalkar
Posted 30-May-2012 10:31 GMT
Toolset C251
|
 RE: My code is working ...
Mayuri Ghosalkar
thnx a lot every1 for ur help...
My problem is solved..
u ppl wer very supportive...:)
regards
Mayuri
|
|
|
Read-Only
Author Mayuri Ghosalkar
Posted 30-May-2012 10:24 GMT
Toolset C251
|
 RE: My code is working ...
Mayuri Ghosalkar
My problem is solved now.
I have used while loop instead of for loop
|
|
|
Read-Only
Author Tamir Michael
Posted 30-May-2012 10:26 GMT
Toolset C251
|
 RE: My code is working ...
Tamir Michael
Felicitations !
|
|
|
Read-Only
Author Per Westermark
Posted 30-May-2012 10:36 GMT
Toolset C251
|
 RE: My code is working ...
Per Westermark
It doesn't matter if you have do { ... } while (x) or while (x) {
... } or for (;;) { ... }
The ISR should not contain any loop to receive multiple
characters. It should pick up one (1) character if you got there
because of a receive interrupt. It should pick up zero (0) if you got
there because of a transmit interrupt.
Only for processors that have a FIFO functionality in the UART,
should an ISR pick up multiple received characters. But such a UART
can wait with generating the interrupt until the receive FIFO gets
past the configured watermark. For a chip without a receive FIFO - or
with a receive FIFO not activated - the ISR should never ever try to
receive more than one character. Never! Never! Never! And again -
never!
An ISR should be quick. Instant in. Instant out. No loop waiting
an unknown time until there _maybe_ comes more characters for the ISR
to pick up.
Throw away the loop from the ISR.
Google for code for a ring buffer.
Let the ISR insert bytes one-by-one into the ring buffer.
Let the main loop consume bytes one-by-one from the ring
buffer.
Let the main loop consider what bytes that may represent the start
of a packet - and how many more characters you may require based on
how the packet started.
But no: NO LOOP WAITING FOR MORE CHARACTERS IN THE ISR. No
"while". No "for". Instant in. Instant out.
|
|
|
Read-Only
Author erik malund
Posted 30-May-2012 15:30 GMT
Toolset C251
|
 you forgot the quotes
erik malund
My code is working
NO, it is
My code is 'working'
working without quotes means working. 'working' with quotes means
appears to work
no code can be WORKING with wait loops in an ISR
NEVER share routines between mani and ISR
KISS Keep ISRs Short and Simple
Erik
|
|