View previous topic :: View next topic |
Author |
Message |
sanddune008
Joined: 23 Oct 2008 Posts: 38
|
Application hangs |
Posted: Wed Feb 18, 2009 2:32 am |
|
|
Hi All,
Code: |
#include <16F628A.h>
#include <string.h>
#include "DoorBell.h"
#fuses XT,NOWDT,NOPROTECT,NOLVP,NOCPD
#use delay(clock=4000000)
#use fast_io(B)
#use rs232(baud=9600, xmit=PIN_B2, rcv=PIN_B1)
#int_rtcc
void clock_isr() {
if(kbhit())
{
gets(&UartBuf[0]);
disable_interrupts(INT_RTCC);
}
}
void main(void) //Program stepping point
{
//Initialize I/O pins
enable_interrupts(GLOBAL);
setup_timer_0(RTCC_INTERNAL|RTCC_8_BIT|RTCC_DIV_256);
clear_interrupt( INT_TIMER0 );
enable_interrupts(INT_RTCC);
while(1)
{
RED_LED_ON; //switches on the LED
delay_ms(1000);
strcpy(Cmd, COMMAND);
if(!(memcmp(UartBuf,Cmd, sizeof(COMMAND))))
{
//Send Mute command
//8Sec Delay
delay_ms(8000);
//Send Play Command
}
//Enabling after sending the command
enable_interrupts(INT_RTCC);
RED_LED_OFF;
delay_ms(1000);
}
} |
What i am doing is trying to receive a command from the uart and based on the command i am controlling the device.
Observed behaviour:
The LED does not blink even when there is no data at the UART RCV pin.
I don't know what is holding up the LED from blinking...... Is the timer a concern? |
|
|
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Wed Feb 18, 2009 3:27 am |
|
|
Many problems ;)
COMMAND is not defined (You do not show this!)
Cmd is not defined (you do not show this!)
UartBuf is not defined (you do not show it)
RED_LED_ON and RED_LED_OFF not shown, etc, etc. get the picture !!!
I know it is proberbly defined in DoorBell.h but that does not help me find your problem.
Try adding ERRORS to your #use rs232 statement.
Using gets in the interrupt is not a good idea. I know you check to see if kbhit but rs232 is slow and your code will stop until it recieves the char(13). So you are wasting clock cycles. if there is a glitch on the rs232 this will cause your program to hang until a char(13) is recieved. If your rs232 doesnt work properly, incorrect baud rate etc, this will also cause your program to hang. |
|
|
sanddune008
Joined: 23 Oct 2008 Posts: 38
|
|
Posted: Wed Feb 18, 2009 3:50 am |
|
|
Thanks for your time...
Wayne_ wrote: | Many problems ;)
COMMAND is not defined (You do not show this!)
Cmd is not defined (you do not show this!)
UartBuf is not defined (you do not show it)
RED_LED_ON and RED_LED_OFF not shown, etc, etc. get the picture !!!
I know it is proberbly defined in DoorBell.h but that does not help me find your problem.
|
yeah all those are defined......I am pretty confident about it, Since
I debugged the hardware with the RS232 interface, same code worked.
i.e
Entered the command over the hyper terminal.Based on the command received it(hardware) indeed sent the necessary control commands and hung(which is another issue).
Wayne_ wrote: | Many problems ;)
Try adding ERRORS to your #use rs232 statement.
Using gets in the interrupt is not a good idea. I know you check to see if kbhit but rs232 is slow and your code will stop until it recieves the char(13). So you are wasting clock cycles. if there is a glitch on the rs232 this will cause your program to hang until a char(13) is recieved. If your rs232 doesnt work properly, incorrect baud rate etc, this will also cause your program to hang
|
But it is not all..... i am interfacing an RS485 hardware to the UART...It is not goin to the point as earlier mention with RS232. It hangs in the begining.
And you can presume there is no problem with the RS485 hardware as i have tested it with another board..It worked fine.
I would be grateful if you can give me a work around?......I am a pessimist on timer usage here as i also call the delay_ms() function, as well can you check the line...........
Thanks............... |
|
|
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Wed Feb 18, 2009 4:20 am |
|
|
Yes you have defined these things elsewhere but the problem still remains, no one else can compile and run THAT code. This will mean that some people will not even bother looking at it for you as you have not provided a compilable example of the problem!
And I would sugest you try commenting out the gets line in the isr and see if your LEDs flash.
// gets(&UartBuf[0]); |
|
|
sanddune008
Joined: 23 Oct 2008 Posts: 38
|
|
Posted: Wed Feb 18, 2009 4:27 am |
|
|
thanks for your time......
Probably this can help you..........
Code: | #include <16F628A.h>
#include <string.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP,NOCPD
#use delay(clock=4000000)
#use fast_io(B)
#use rs232(baud=9600, xmit=PIN_B2, rcv=PIN_B1)
// Standard definitions for the IR Tx board
#define RED_LED PIN_A1 // (output) Red LED (low true)
#define IR_LED PIN_B4 // (output) Infrared LED (low true)
#define RED_LED_ON output_low(RED_LED)
#define RED_LED_OFF output_high(RED_LED)
#define IR_LED_ON output_low(IR_LED)
#define IR_LED_OFF output_high(IR_LED)
#define COMMAND "mute"
char UartBuf[20],Cmd[10];
#int_rtcc
void clock_isr() {
if(kbhit())
{
gets(&UartBuf[0]);
disable_interrupts(INT_RTCC);
}
}
void main(void) //Program stepping point
{
//Initialize I/O pins
enable_interrupts(GLOBAL);
setup_timer_0(RTCC_INTERNAL|RTCC_8_BIT|RTCC_DIV_256);
clear_interrupt( INT_TIMER0 );
enable_interrupts(INT_RTCC);
while(1)
{
RED_LED_ON; //switches on the LED
delay_ms(1000);
strcpy(Cmd, COMMAND);
if(!(memcmp(UartBuf,Cmd, sizeof(COMMAND))))
{
//Send Mute command
//8Sec Delay
delay_ms(8000);
//Send Play Command
}
//Enabling after sending the command
enable_interrupts(INT_RTCC);
RED_LED_OFF;
delay_ms(1000);
}
} |
|
|
|
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Wed Feb 18, 2009 4:32 am |
|
|
Some more questions.
Where do YOU think it hangs ("it hangs in the begining") means very little.
How do you know it is hanging there ?
Does the RED_LED_ actually come on ?
Does it go OFF then hang ?
your implimentation regarding the disabling and enabling of the interrupt is also flawed. If the command is executed, you have 8 seconds before it will recieve another command!.
You still don't have the ERRORS setting in the #use rs232, not sure if this is a problem as it LOOKS like you are using software uart! If it is a hardware UART then your rs232 will most likely hang up because you are not processing the incomming data. |
|
|
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Wed Feb 18, 2009 4:39 am |
|
|
I just checked the data sheet, it is a HARDWARE UART you are using.
This has a 2 deep FIFO buffer.
If it recieves another char before you have read 1 or both the data in the buffer an overrun conditon occurs. You have to clear this before it will recieve anymore data. Adding the ERRORS flag to the #use rs232 line will handle the overflow automatically for you.
As you are using a hardware uart you would be better off using the #int_RDA serial isr to handle incomming data. |
|
|
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Wed Feb 18, 2009 4:52 am |
|
|
You have RS485 hardware which you have tested.
This hardware and software work when connected via RS232 to hyperterminal.
It hangs when connected to the RS485 hardware.
Have you checked what the RS485 hardware is outputting ?
If it outputs data but never a return (char 13) then your code will hang.
Worse, you will get buffer overrun on UartBuf which will corrupt other memory. |
|
|
sanddune008
Joined: 23 Oct 2008 Posts: 38
|
|
Posted: Wed Feb 18, 2009 5:10 am |
|
|
Thanks for time wayne.............
When interfaced to RS232 it hangs after sending the control commands( i am not using UART for this). ie the LED glows forever...and doesn't excute the led off line.
When interfaced to RS485 board it hangs at the begining.
This error didn't exist if the command send from the hyperterminal, why other wise?
Let me try adding ERRORS flag. and let you know. |
|
|
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Wed Feb 18, 2009 5:46 am |
|
|
sanddune008 wrote: |
When interfaced to RS232 it hangs after sending the control commands( i am not using UART for this). ie the LED glows forever...and doesn't excute the led off line.
|
OK, not sure how you are doing it without the UART!
in this case there is no data on the rs232, the led flashes, so far so good. You send a command, The gets line waits for a char(13) which it never gets and the program hangs.
This may happen because your communication is flawed, wrong settings, errors on the line. How do you know that the data sent from the ? over RS232 is correct ? What is sending the data hyperterminal ?
sanddune008 wrote: |
When interfaced to RS485 board it hangs at the begining.
|
OK, not sure how long before the interrupt fires but you have a 1 sec delay after turning the LED on. I assume by you saying "at the beginnning" that the LED does not come on!
If the interrupt has fired before this point then there must be data on the serial line, again, this may be corrupt which would cause it to hang. Again no CR sent or it is corrupt.
sanddune008 wrote: |
This error didn't exist if the command send from the hyperterminal, why other wise?
|
No error here because your data from hyperterminal is correct. it sends the command followed by a CR. |
|
|
sanddune008
Joined: 23 Oct 2008 Posts: 38
|
|
Posted: Wed Feb 18, 2009 5:52 am |
|
|
Code: | #use rs232(baud=9600, xmit=PIN_B2, rcv=PIN_B1, ERRORS) |
I am using following serial interrupt routine to get the data instead of using the timer mentioned above
Code: | #INT_RDA
void serial_isr()
{
gets(&UartBuf[0]);
printf("\r\nReceived:%s\r\n",UartBuf);
} |
nothing seems to work now.... |
|
|
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Wed Feb 18, 2009 6:22 am |
|
|
That is because the rs232 isr interrupts on 1 char. You can not use gets in the serial isr.
Change to
Code: |
#define MAX_BUF 20
int next = 0;
int1 comflag = false;
char UartBuf[MAX_BUF],Cmd[10];
#INT_RDA
void serial_isr()
{
char c;
c = getc(); // Clears the serial interrupt
if (comflag) // Current command need sprocessing so ignore data
return;
if (c == 13)
{
c = 0;
comflag = true;
}
Uartbuf[next++] = c;
// protect against buffer overrun!
if (next == MAX_BUF)
next = 0;
}
|
Change main
Code: |
while(1)
{
RED_LED_ON; //switches on the LED
delay_ms(1000);
if (comflag) {
strcpy(Cmd, COMMAND);
if(strcmp(UartBuf,Cmd) == 0) // Command found
{
delay_ms(8000);
}
comflag = false;
}
RED_LED_OFF;
delay_ms(1000);
}
|
|
|
|
Ttelmah Guest
|
|
Posted: Wed Feb 18, 2009 6:38 am |
|
|
Lets make some basic comments:
Unfortunately, the poster is trying to be too complex. If you have a problem like this, 'start simple'. A basic loop, reading a message, and setting/resetting a couple of LEDs. Set one before trying to read the serial. If this comes on, you know you have go this far. Set the other, when the string is fetched. If this doesn't come on, you now 'know' it is the serial fetch that is causing the problem. Getting involved with interrupts etc., is uneccessary.
Now, the 'hangup', is _classic_, for a serial line coming into the PIC, that is not going high enough, when 'idle'. On TTL serial (which is what the PIC receives), the 'idle' state, is _high_. Your timer code, could be called almost immediately at startup, since the timer will run for quite a few clock cycles, with the default (/1) prescaler. If the serial line is not high, then the code will hang at this point. The description of 'testing' the serial connection, is vague, but suggests the poster may have tried connecting using the software UART, instead of the hardware UART. Look carefully at the data sheet. Note that the normal input on pin B1, is a _TTL_ input buffer, while the UART input, has a Schmitt input buffer. The difference in required voltages, is huge. The latter requires the line to go to 4v (assuming running on a 5v supply), while the former only requires the signal to reach 2v. I'd suspect this is the actual problem...
Best Wishes |
|
|
sanddune008
Joined: 23 Oct 2008 Posts: 38
|
|
Posted: Mon Feb 23, 2009 1:08 am |
|
|
Thanks Wayne_ and Ttelmah for your time..............
Things are working fine now......
Why does gets() function look for carriage return?...Generally it has to
look for a null (' \0 ') or newline isn't and each string is appended by a NULL character?
Thanks in advance. |
|
|
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Mon Feb 23, 2009 3:16 am |
|
|
gets is reading characters from an IO line, in your case a serial interface. It needs a way of determining the end of a line of input. Char(13) a carridge return is sent when someone presses return, a LF may not be!
Once gets sees the CR it replaces is with a null char '\0' so you now have a usable string. |
|
|
|