View previous topic :: View next topic |
Author |
Message |
starkeeper
Joined: 06 Apr 2006 Posts: 9
|
RS232 speed problems? |
Posted: Thu Dec 28, 2006 7:36 am |
|
|
Hi,
I'm stuck in talking to a MCA25 Handy-Camera.
I have to talk with 460800bps and it works fine for a few commands and responses. But after a few steps the PIC starts receiving garbage.
I'm using the Hardware UART of my PIC18F2550. First I used a 7,3773MHz crystal. That worked not very good, it was luck, if the data read was correct. So I switched over to 14,7546MHz now I was able to read a few more commands from the camera and it was more reliable. So I tried a 20MHz with the internal PLL so that the PIC runs on 48MHz. Now I'm able to initiliaze and configure the Camera, the communication is nearly stable. But the read error still occure after a few more commands than with the 14MHz.
Using interrupts had no effect. But rewriting the code in my interrupt routine and buffer handling, using less commands, improves the results a bit. Then I am able to read some more characters correct. But that can't be the point cause there are 48MHz of power now!! I could calculate prime numbers before the next carachter will arrive!
Any Suggestions for me? |
|
|
Ttelmah Guest
|
|
Posted: Thu Dec 28, 2006 9:32 am |
|
|
Seriously, you are going to need to write very tight code to handle this. 460800bps, imples a character can arrive every 46000th second. Even at 48MHz, the chip only executes 12Mips. This gives just 260 instruction times between characters. The interrupt will involve typically perhaps 80 instructions (just for the register saving/call and return). So you have just 180 machine instructions available between characters to do anything. Now a single array access like:
buffer[ctr]=getc();
will involve typically perhaps thirty machine instructions. Suddenly 180 instructions, does not seem very much. If you are doing very much at all with the image, you are going to run out of time between characters. Given the size of the images involved, there is presumably a reasonable amount of work likely...
Best Wishes |
|
|
starkeeper
Joined: 06 Apr 2006 Posts: 9
|
|
Posted: Thu Dec 28, 2006 11:30 am |
|
|
Ttelmah wrote: | Seriously, you are going to need to write very tight code to handle this. 460800bps, imples a character can arrive every 46000th second. Even at 48MHz, the chip only executes 12Mips. This gives just 260 instruction times between characters. The interrupt will involve typically perhaps 80 instructions (just for the register saving/call and return). So you have just 180 machine instructions available between characters to do anything. Now a single array access like:
buffer[ctr]=getc();
will involve typically perhaps thirty machine instructions. Suddenly 180 instructions, does not seem very much. If you are doing very much at all with the image, you are going to run out of time between characters. Given the size of the images involved, there is presumably a reasonable amount of work likely...
Best Wishes |
Well than it would be better to do that without interupts?
There are some people who have done the same with the camera but with an Atmel Mega128 and they need only 7MHz. The Hardware UART is the same, it has a 2 character buffer like the microchip one. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Thu Dec 28, 2006 2:49 pm |
|
|
starkeeper wrote: | Well than it would be better to do that without interupts? | That certainly is an option, it will save you the large interrupt overhead. Just make sure you will check for received data being present often enough.
Another solution would be to write your own interrupt dispatcher. This can be optimized as you only have to save/restore the registers you are actually using in your interrupt routine.
starkeeper wrote: | There are some people who have done the same with the camera but with an Atmel Mega128 and they need only 7MHz. The Hardware UART is the same, it has a 2 character buffer like the microchip one. | You can not compare directly to the ATMega128, for example the ATMega doesn't divide the external clock by 4 as the PIC does. An ATMega running at 7MHz executes (almost) 7 million instructions per second (7 MIPS) while a PIC requires 4 * 7 = 28MHz external clock to achieve the same 7 MIPS. Furthermore the ATMega has a design which allows to achieve the same goal with less instructions to execute, giving another few percents advantage to the ATMega (for example: seperate interrupt vectors and 32 GPR's instead of only a single working register for the PIC). |
|
|
starkeeper
Joined: 06 Apr 2006 Posts: 9
|
|
Posted: Thu Dec 28, 2006 3:12 pm |
|
|
ckielstra wrote: | You can not compare directly to the ATMega128, for example the ATMega doesn't divide the external clock by 4 as the PIC does. An ATMega running at 7MHz executes (almost) 7 million instructions per second (7 MIPS) while a PIC requires 4 * 7 = 28MHz external clock to achieve the same 7 MIPS. Furthermore the ATMega has a design which allows to achieve the same goal with less instructions to execute, giving another few percents advantage to the ATMega (for example: seperate interrupt vectors and 32 GPR's instead of only a single working register for the PIC). |
Well that is somthing that should somebody write down for starters.. this is the simple but serious difference why so much people choose Atmel. And no one is talking about..
At the moment I got an internal clock of 48MHz that is 7 times more than the Atmel-Crew was using. Don't you think that this is nearly the power of a 7Mhz clocked Atmel?
By the way its not the problem that I miss characters I get the wrong value, for instance:
expected: 0xF9 0x83 0xEF 0x3F 0xA0 0x00 0x1F
read: 0x00 0x00 0xE0 0x3F 0xA0 0x00 0x1F
That doesn't look like a to slow processor to me, than there would be missing characters. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Thu Dec 28, 2006 4:13 pm |
|
|
Quote: | Well that is somthing that should somebody write down for starters.. this is the simple but serious difference why so much people choose Atmel. And no one is talking about.. | There is a large difference in clock speed but I don't see how that matters, to me the number of MIPS is what counts and I don't care what crystal I have to buy to achieve that throughput. What could be important is the maximum number of MIPS you can squeeze out of a processor, for the ATMega128 that is 16MIPS and for an 48MHz PIC18 it will be 12MIPS. Your reference design of the ATMega128 is running at 7 MIPS, easy to match for your PIC18.
Until now we are assuming it is a performance issue, it would be nice to get proof of this. Could you add a test to your interrupt handler for the UART overrun flag being set? Add this test before the getc() call or it will be cleared by the hardware.
Maybe you can post the code of your interupt handler so we can make some suggestions for optimizations? If you don't want to share your code to the world you can send it to me in a private mail (you'll have to become a member of this forum for this option to be available). |
|
|
starkeeper
Joined: 06 Apr 2006 Posts: 9
|
|
Posted: Fri Dec 29, 2006 2:07 am |
|
|
Code: | #use rs232(baud=460800, xmit=PIN_C6, rcv=PIN_C7, STREAM=MCA, ERRORS)
#int_rda
void serial_isr()
{
int t;
while(kbhit())
{
MCA_buffer[MCA_next_in] = fgetc(MCA);
t=MCA_next_in;
MCA_next_in=(MCA_next_in+1) % MCA_BUFFER_SIZE;
if(MCA_next_in==MCA_next_out)
MCA_next_in=t; // Buffer full !!
}
} |
Thats my interrupt routine. This is taken from on of the CCS-Examples and only tweaked a little bit regarding the kbhit()-loop. My Buffer is 121Bytes big, the maximum message size the camera sends is 40Byte so the PIC could buffer four of them.
I checked the rs232_errors and it says 0x90 even when I receive garbage. To me 0x90 says normal operation and no overruns.. |
|
|
Ttelmah Guest
|
|
Posted: Fri Dec 29, 2006 3:53 am |
|
|
One 'glaring' problem. You need to use 'kbhit(MCA)'...
Otherwise (depending on the order the streams are declared),you could not accept a character on the MCA stream at all, and sit looping in the interrupt, or keep trying to get characters from the MCA stream, when none are ready.
Personally, I'd expand the buffer to 128 bytes, and use:
MCA_next_in=(MCA_next_in+1) & 127;
This will evaluate much faster than using the modulus function. The modulus operator, will take about one hundred machine instructions to execute, while uing '&', with a binary buffer size, will take less than ten!...
Best Wishes |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1635 Location: Perth, Australia
|
|
Posted: Fri Dec 29, 2006 4:19 am |
|
|
It is possible to drive a 40MHz PIC with a 2.5Mbps serial stream using interrupts however to do this you need to use HP Interrupts with fast return to minimize the overhead and code the interrupt handler either in assembler or in carefully crafted by hand. One trick is to use "#locate" to place any variables (other than those accessed by an FSR) in the access bank. This saves having to manage the BSR _________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
|
starkeeper
Joined: 06 Apr 2006 Posts: 9
|
|
Posted: Fri Dec 29, 2006 12:43 pm |
|
|
Well as we figured out it is not a speed problem anymore. Because the overrun error bit is never set.
I could only imagine that there is a hardware error. Maybe someone could help mee to with this. I directly connected the camera to my pic18f2550, but the camera uses cmos-levels and the PIC uses TTL. Maybe that results to theese mysterious bugs.
Is there a more glamorous way of connecting cmos to TTL? |
|
|
rwyoung
Joined: 12 Nov 2003 Posts: 563 Location: Lawrence, KS USA
|
|
Posted: Fri Dec 29, 2006 12:54 pm |
|
|
starkeeper wrote: | Well as we figured out it is not a speed problem anymore. Because the overrun error bit is never set.
I could only imagine that there is a hardware error. Maybe someone could help mee to with this. I directly connected the camera to my pic18f2550, but the camera uses cmos-levels and the PIC uses TTL. Maybe that results to theese mysterious bugs.
Is there a more glamorous way of connecting cmos to TTL? |
Depends on the actual CMOS voltage levels. CMOS used to be accepted to mean 0 to 5V (although some older CMOS logic works fine up to Vdd=9V and higher) but now it should be taken to mean low = 0, high = Vdd with various thresholds, consult the datasheet. So it stongly depends on the value of your Vdd.
In theory, TLL low is <1>2.4V (for Vcc=5V) so even a Vdd=3.3V should work. This however is not necessarily always the case.
And techincally, the PIC is CMOS, not TTL (TTL = transistor-transistor logic and used bipolar transistors). I'd be very supprised if the 18F2550 has any bipolar process "stuff" in it at all.
So, the questions are, what are the voltage levels output by your camera and at what Vdd are you running the PIC? _________________ Rob Young
The Screw-Up Fairy may just visit you but he has crashed on my couch for the last month! |
|
|
starkeeper
Joined: 06 Apr 2006 Posts: 9
|
|
Posted: Fri Dec 29, 2006 2:04 pm |
|
|
The PIC runs at 5V and the Camera has 3.6V. |
|
|
rwyoung
Joined: 12 Nov 2003 Posts: 563 Location: Lawrence, KS USA
|
|
Posted: Fri Dec 29, 2006 2:40 pm |
|
|
OK, so the TX from the camera to the PIC should be OK. You might want to have a small series resistor in place if you are paranoid about accidentally configuring the PIC pin as an output and driving it to 5V but careful programming should prevent that from happening.
But to be safe, you shouldn't drive the camera's inputs with 5V. The easiest would be to select something like a 74LVX125 powered by the same Vdd as the camera. Then it acts as the 5V to 3.3V buffer PIC to camera.
Double check the LVX logic family but I think it is 5V tolerant, if not look at LVC or just spend a few minutes on the Fairchild Semiconductor or TI pages looking at high speed CMOS familes. Keep in mind the propagation delay of the logic family when selecting one to use as a buffer.
There are more expensive parts around that can handle the 5V to 3.3/3.6V conversion in both directions but LVX125's (or '244 or '245) are cheap and cheerful little guys. _________________ Rob Young
The Screw-Up Fairy may just visit you but he has crashed on my couch for the last month! |
|
|
Ttelmah Guest
|
|
Posted: Fri Dec 29, 2006 4:24 pm |
|
|
Switch to a LF2550, and run it off 3.6v as well at 20MHz.
The problem is that the UART input pin is a Schmitt input. This requires driving to 0.8*Vdd to 'see' a logic high. 0.8*5v = 4v. The 3.6v unit will not generate this. You can run the PIC at full speed off 4.2v, and the 3.6v device (assuming the output drives to within perhaps 0.5v or the supply rail), will then just provide an adequate signal.
This is nothing to do with CMOS versus TTL, but is the problem of mixing different oprating voltage devices...
Best Wishes |
|
|
starkeeper
Joined: 06 Apr 2006 Posts: 9
|
|
Posted: Sat Dec 30, 2006 3:30 am |
|
|
Ttelmah wrote: | Switch to a LF2550, and run it off 3.6v as well at 20MHz.
The problem is that the UART input pin is a Schmitt input. This requires driving to 0.8*Vdd to 'see' a logic high. 0.8*5v = 4v. The 3.6v unit will not generate this. You can run the PIC at full speed off 4.2v, and the 3.6v device (assuming the output drives to within perhaps 0.5v or the supply rail), will then just provide an adequate signal.
This is nothing to do with CMOS versus TTL, but is the problem of mixing different oprating voltage devices...
Best Wishes |
Isn't the factor 0.5 and the input swithes at 2.5V to a high Signal? I thought all Inputs are normaly Schmitt Triggers... |
|
|
|