|
|
View previous topic :: View next topic |
Author |
Message |
kpkale
Joined: 16 Mar 2007 Posts: 4
|
Hardware UART not opening after setup_uart(1) |
Posted: Fri Jun 18, 2010 1:31 am |
|
|
I am using PIC18F4620 with 2 UART. One Hardware and other Software.
I am changing the Baudrate of the hardware UART at runtime using the set_uart_speed command.
I am required to connect a barcode scanner to the hardware UART and read the scanned barcode and process the data. However, the problem is that by mistake if the barcode is scanned twice, the uart hangs. Or even while I am processing the data if someone scans a barcode, the uart hangs. What is the way to ensure this does not happen.
I tried to switch ON the uart when needed and switch OFF after gettting the data. But that does not seem to work. I simply dont get the kbhit() or the uart does not switch ON.
Can any one help me with both these things. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Fri Jun 18, 2010 1:56 am |
|
|
Have you got 'ERRORS' in your hardware UART setup?.
Commonest problem with the hardware UART, is that if characters arrive, and are _not_ processed by your code (so perhaps with the second scan, the chip is doing something else when the second set of data arrives), the UART will trigger an 'overrun' error, and lock up. 'ERRORS' adds code to stop this.
Best Wishes |
|
|
kpkale
Joined: 16 Mar 2007 Posts: 4
|
|
Posted: Fri Jun 18, 2010 10:21 pm |
|
|
I have used Errors.
Code: |
#fuses NOWDT, WDT128, H4, PROTECT, NOIESO, NOBROWNOUT, BORV43, STVREN // PUT,
#fuses DEBUG, NOLVP, NOWRT, NOWRTD, NOWRTB, NOWRTC, NOCPD, NOCPB, NOEBTR, NOEBTRB
#use delay(clock=40000000)
#use rs232(stream=PC,baud=115200, xmit=PIN_C6,rcv=PIN_C7,PARITY=N,BITS =8,STOP=1,errors)
#use rs232(stream=LC,baud=9600, parity=N,xmit=PIN_D1,rcv=PIN_D0,bits=8)
|
In spite of that, I am still getting the problem. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Sat Jun 19, 2010 4:29 am |
|
|
How are you reading characters from the UART?.
Basically, 'ERRORS', clears the fault, but only when a character is read.
The 'sequence' needed, is basically to turn the UART off, read a character, and turn it on again. If the OERR bit is set, and you call read, this should happen. Just disabling, end re-enabling the UART, won't clear the error, unless a character is read.
Reaslistically this covers 99% of possible reasons for the UART to get hung.
Other possibilities are:
1) Having a falling edge arrive, with the 'uart speed' set to a silly low value. If so, the UART will be receiving the character at this rate, and won't do anything else on the receive side, till the byte time has elapsed. You mention using set_uart_speed, are you sure the value arriving at this is legitimate....
2) Electrical 'lockup' of part of the chip. Rare, but can happen if there are supply spikes, or unexpected voltages present.
Best Wishes |
|
|
kpkale
Joined: 16 Mar 2007 Posts: 4
|
|
Posted: Sun Jun 20, 2010 12:07 am |
|
|
When the user presses a button to start the cycle, I have a loop for reading the barcode data on a UART.
After breaking from this loop, I process the string collected. That processing takes time. The sequence starts again only after the user presses a start button. And in case the user has scanned a barcode twice or even scanned a barcode while he is not expected to scan it, then the next time he scans it when required, the kbhit does not get fired.
Is there a way to first check if there are any characters pending to be processed on the serial, clear them first and then wait for the kbhit?
Code: |
// setup_uart(1,PC);
// delay_ms(100);
do
{
if(kbhit(PC)) // Check for USART interrupt
{
if(bit_test(rs232_errors,0))
{
rs232_errors=0;
bit_clear(RCSTA,4);//
clear_inpbuf();
fprintf(PC,"!");
}
if(bit_test(rs232_errors,1))
{
rs232_errors=0;
bit_clear(RCSTA,4);//
clear_inpbuf();
fprintf(PC,"^");
}
if(bit_test(rs232_errors,2))
{
rs232_errors=0;
bit_clear(RCSTA,4);//
clear_inpbuf();
fprintf(PC,"~");
}
udata = fgetc(PC);
temp_str[b++]=udata;
if(udata==0x0D)
{
// setup_uart(0,PC);
// delay_ms(100);
break;
}
}
}while(True);
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Sun Jun 20, 2010 1:48 am |
|
|
In all honesty, use a serial interrupt.
Have the characters be received as and when they arrive.
If you want to disable receipt, have a flag, called something like 'throw_away', and in the interrupt, if this flag is set, simply receive the character, and don't add it to the buffer. When you want to start receiving again, turn the flag off.
What you are currently doing, is overriding the behaviour of the compiler. You are clearing the error, without reading a character, so the compiler will no longer know there is an error, and the read which is needed to clear it in hardware, is not being done.
Take advantage of interrupts. You don't need to test the erorr bits, unless you want to know there is an error. Read characters when the interrupt happens, and the compiler will handle clearing errors for you.
Best Wishes |
|
|
kpkale
Joined: 16 Mar 2007 Posts: 4
|
|
Posted: Tue Jun 22, 2010 2:47 am |
|
|
Hi
My problem is that I am using one software uart and one hardware uart. Serial interrupt only works with hardware uart and not with software uart. The other processing commands need to be accessed either from the hardware uart or from the software uart hence I am unable to use the interrupt but forced to use the kbhit to detect if there is a character on the uart.
So, can there be some way of checking if there are any characters in the recieve buffer, clear the transmit recieve buffers and then again wait for the kbhit to give the next key stroke. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Tue Jun 22, 2010 4:14 am |
|
|
On a software UART, 'kbhit', won't 'detect if there is a character on the UART'. It purely reflects the level on the RX line. It needs to be repeatedly called at a rate no slower than about 1/2 the bit time, to have any hope of seeing a character. Unless this is done, characters _will_ be missed.
If data is coming in at any sort of reasonable rate, and you are doing anything much else, you _will_ miss characters with the software UART.
I'm afraid it is a poor solution for anything expecting to receive data without knowing in advance that it is due to arrive.
It is possible to use an interrupt with the software UART. Use one of the lines on the processor supporting a hardware interrupt, set this to interrupt on the falling edge, and receive one character in the handler for this. Combine with separate buffers for the hardware and software UARTs, and provided the rate you want to use is not too high, you have a much better chance of success.
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
|