|
|
View previous topic :: View next topic |
Author |
Message |
jonpaul
Joined: 10 Feb 2004 Posts: 7
|
Dual Serial port problems |
Posted: Tue Feb 10, 2004 8:51 pm |
|
|
I am trying to add another rs232 port to a project I have. I followed the guidance given in the FAQ and a post from 2001. The hardware UART still works just great. However, I can't get the SW uart to recognize a kbhit. It seems to recieve fine (at least that's what MPLAB's watch window reports), but the transmit is wrong. Here's my test code. I am running at 20Mhz on a Pic 16F77
Code: |
#include <16f77.h> // for PCM compiler
#use delay(clock=20000000)
#use RS232(BAUD = 115200, XMIT = PIN_D6, RCV = PIN_D7, PARITY = N, BITS = 8)
void SWputchar(char input)
{
putchar(input);
}
char SWgetch()
{
return (getch());
}
char SWkbhit()
{
return (kbhit());
}
#use RS232(BAUD = 115200, XMIT = PIN_C6, RCV = PIN_C7, PARITY = N, BITS = 8)
#use fast_io(c)
#use fast_io(b)
#use fast_io(a)
#byte PORTB = 6
static char swchar;
main()
{
portb=0x00;
set_tris_b(0x00);
set_tris_a(0xFF);
set_tris_e(0b111);
setup_adc_ports(A_ANALOG);
setup_adc(ADC_CLOCK_DIV_32);
enable_interrupts(int_rda);
enable_interrupts(global);
do
{
swchar=SWgetch();
SWputchar(swchar);
SWputchar(0x41);
SWputchar(0x42);
SWputchar(0x43);
SWputchar(0x44);
SWputchar(0x45);
SWputchar(0x46);
SWputchar(0x47);
SWputchar(0x48);
SWputchar(0x49);
SWputchar(0x4a);
SWputchar(0x4b);
SWputchar(0x4c);
SWputchar(0x4d);
SWputchar(0x4e);
SWputchar(0x4f);
SWputchar(0x50);
SWputchar(0x51);
SWputchar(0x52);
SWputchar(0x53);
SWputchar(0x54);
SWputchar(0x55);
SWputchar(0x56);
SWputchar(0x57);
SWputchar(0x58);
SWputchar(0x59);
SWputchar(0x5a);
}
while(TRUE);
} |
When I transmit a 0x4D ('M') I get a 0xCD echoed back. And the progression of the alphabet from A-Z gets transmitted as 0xC1 to 0xDA.
Any ideas why my transmit is wacky? And why it won't recognize a KBhit? |
|
|
Ttelmah Guest
|
|
Posted: Wed Feb 11, 2004 3:40 am |
|
|
I'm afraid your problem screams 'timing'. Bytes are sent LSBit first, so your error reflects the penultimate bit in the character, either being mistimed on receive, or on transmit. The fact that the same error occurs on the constant values afterwards, suggests it is the transmit that has the problem. Now sending at 115200, involves a 'bit time', of just 43.4 instructions. The error, is that the bit is being sent late (hence the bit for the '4', is seen at the sample point for both the 4 bit, and the 8 bit). At the point where this bit is sent, the system will be seven bit times from the start of the byte (start bit, plus six data bits). How much time error this represents, depends on both the timing, and sampling strategy of the system at the other end. Generally, you can normally assume that timings have to be better than about 3% to be 'safe'. Assuming this is the allowable tolerance, then the error, could be as small as perhaps 2uSec. Given the '0.4' in the instruction time figure, it suggests that the code is using a value of perhaps 44 instructions for the loop, and this is adding up to produce the error. Remember also that there will be other errors that may contribute through the system:
Clock frequency on both systems. Crystals are not perfect.
UART divider on the PC.
Switching and detection times on the transceiver chips (at this high rate, a slight difference in the 'on' versus the 'off' time of the transceiver, can create a significant reduction in the error margin).
Added to the timing errors in the soft UART, these are 'ganging up' to result in your problem (the fact that the bit is sampled in two bit points, suggests that a transceiver problem may be contributing significantly).
Basically, you are trying for too much. The soft UART, is fine for low speed communications, but will be straining at this rate.
One small comment on the code, is that you should put the #use fast_io statements _before_ the #use RS232. The #use RS232 statement, uses the I/O mode selected at the point where the statement is placed, and hence will not be using fast_io.
Realistically, look to using a slower baud rate if possible.
Best Wishes
You are really trying for too much, to operate a software |
|
|
jonpaul
Joined: 10 Feb 2004 Posts: 7
|
Thanks |
Posted: Wed Feb 11, 2004 12:21 pm |
|
|
When I was thinking about it this morning I figured maybe I was trying to run it too fast. I could dial it back, I just wanted to run it as fast as possible. However, moving the #fast_io statements above the use RS232 statements seems to have fixed the problem without having to change the speed. I'm not exactly sure why since I don't have a fast_io statement for port D, which the software Uart is on. Maybe it is just phase of the moon and it is still unstable and I just haven't seen it yet. |
|
|
ttelmah Guest
|
Re: Thanks |
Posted: Thu Feb 12, 2004 4:54 am |
|
|
jonpaul wrote: | When I was thinking about it this morning I figured maybe I was trying to run it too fast. I could dial it back, I just wanted to run it as fast as possible. However, moving the #fast_io statements above the use RS232 statements seems to have fixed the problem without having to change the speed. I'm not exactly sure why since I don't have a fast_io statement for port D, which the software Uart is on. Maybe it is just phase of the moon and it is still unstable and I just haven't seen it yet. |
I like the 'phase of the Moon' idea. :-)
This (combined with whether you have correctly sacrificed the chicken), explains so many code problems....
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
|