|
|
View previous topic :: View next topic |
Author |
Message |
wanalan
Joined: 19 Apr 2004 Posts: 1
|
Newbie help needed... Slow interrupt handler ?! |
Posted: Mon Apr 19, 2004 2:58 am |
|
|
Hi everyone,
First time posting here, I'm going to ask a very naive question: I'm going to transmit 32000 bytes from PC to PIC18F8720 using serial cable with HyperTerminal "send tex tfile" function (the file is binary), it should take 32000/115200 = 0.27 - less than a second even include the overhead of the interrupt handler. But when I ran my code, it took 1 minute 10 sec to finish sending... I'm really baffled by this, since it is simple code that I'm writing. Below is my code, please take a look. Thanks a lot in advance!!
AL
Code: |
#include <18F8720.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=115200, xmit=PIN_C6, rcv=PIN_C7)
#use fast_io (c)
int16 numsent = 0;
char tempChar;
#int_rda
void rda_handler() {
disable_interrupts(int_rda);
tempChar = getc();
numsent++;
enable_interrupts(int_rda);
}
int main(void) {
int16 i;
enable_interrupts(int_rda);
enable_interrupts(global);
while(1){
if(numsent > 32000){
printf("numsent: %x%x%x%x\n\r", numsent>>24, numsent>>16, numsent>>8, numsent);
break;
}
}
return 0;
}
|
|
|
|
Ttelmah Guest
|
Re: Newbie help needed... Slow interrupt handler ?! |
Posted: Mon Apr 19, 2004 4:45 am |
|
|
wanalan wrote: | Hi everyone,
First time posting here, I'm going to ask a very naive question: I'm going to transmit 32000 bytes from PC to PIC18F8720 using serial cable with HyperTerminal "send tex tfile" function (the file is binary), it should take 32000/115200 = 0.27 - less than a second even include the overhead of the interrupt handler. But when I ran my code, it took 1 minute 10 sec to finish sending... I'm really baffled by this, since it is simple code that I'm writing. Below is my code, please take a look. Thanks a lot in advance!!
AL
Code: |
#include <18F8720.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=115200, xmit=PIN_C6, rcv=PIN_C7)
#use fast_io (c)
int16 numsent = 0;
char tempChar;
#int_rda
void rda_handler() {
disable_interrupts(int_rda);
tempChar = getc();
numsent++;
enable_interrupts(int_rda);
}
int main(void) {
int16 i;
enable_interrupts(int_rda);
enable_interrupts(global);
while(1){
if(numsent > 32000){
printf("numsent: %x%x%x%x\n\r", numsent>>24, numsent>>16, numsent>>8, numsent);
break;
}
}
return 0;
}
|
|
Er.
First, remember 'bps', is _bits_ per second, not _bytes_ per second. To send 32000 bytes at 115200bps, takes (32000*10)/115200 = 2.78 seconds (assuming the minimum of one stop bit, and one start bit added to the data). Though only a factor of ten error (does not exlain your sloth), it still makes a difference...
Second comment. Do not disable/enable the receive interrupt inside the handler. This is not needed (the chip hardware disables the global interrupt when the handler is called), and is just extra 'overhead'.
Next comment, as written, the program would never report completion!. If you are sending 32000 bytes, the 'counter', wll reach 32000, but not _pass_ it. You are testing for it going beyond 32000. Are you sure that the transfer has not actually finished a long time in the past, and an extra character is being received leading to the printout.
Add the 'ERRORS' directive to the serial declaration. Though you should not be hitting errors, there can (easily) be timing problems with serial comms (if you look back a couple of weeks, you will find a poster who was having 'framing' errors on PC comms, which turned out to be a fault with the timing from the PC itself...). If it was an 'errors' problem, the sysem might well lose a few more characters or the receive could completely hang (with an overrun error this will happen if the error is not cleared).
Though the interrupt overhead is large, it has no effect at all, on the speed of the transfer. The 'sending' device times the transfer, and takes the same time to send the data, whether or not there is a receiver there, unless handshaking is used (which you are not). The interrupt overhead may lead to overrun errors, but will not change the speed the data is being sent.
Though it shouldn't cause this problem, you are declaring 'use fast_io(c)', but are not then setting the TRIS register. Using fast_io, has no effect on the speed of hardware devices, but once it is used. _you_ are responsible for controlling the TRIS register.
Seperately, why waste so much work in the printf statement?.
printf("numsent: %04lx",numsent);
does the entire prinout of four digits for you...
There is another potential problem here. You 'break' out of the while loop, and then execute a return (where this will take you is undefined - CCS does not 'call' the main). However the body of the ROM in CCS, contains 'sleep' instructions, so you should allways wait for the data to have finished sending (there will be three characters in the RS232 hardware buffer when the printf statement exits), before 'ending' th program.
Best Wishes |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|