View previous topic :: View next topic |
Author |
Message |
iKevin
Joined: 27 Mar 2008 Posts: 9
|
Need help with RS232 and interrupt |
Posted: Sat Apr 12, 2008 12:10 pm |
|
|
I need to have interrupts for something like this:
Interrupt for receiving data:
Code: | 1 .The main program is doing whatever it has to do.
2. Computer transmits data to PIC, the program finishes its current instruction.
3. The main program stops and jumps to the Receiving Int Routine, gets all the data, updates global variables.
4. Instead of returns back to where it left off, it starts at the beginning of the program ( at void main() ) |
Interrupt for sending data
Code: | 1. The main program is doing whatever it has to do.
2. ADC conversion is done.
3. Transmitting Int Routine is invoked, the data of ADC (temperature) is sent to the computer
4. Tx is done, returns back to where it left off.
|
Also is there a way to send (RS232) data of ADC every 1-2 secs instead?
Can you some provide me some example code for these 2 interrupts? Thank you!
Last edited by iKevin on Sat Apr 12, 2008 12:20 pm; edited 1 time in total |
|
|
KU5D
Joined: 10 Feb 2008 Posts: 46 Location: Asheville, North Carolina
|
|
Posted: Sat Apr 12, 2008 12:20 pm |
|
|
This is a bit vague, but let's see...
1. What is the main() doing?
2. If you're using the hardware uart on the PIC, you can use INT_RDA to call your receiver routine and put the received data into a buffer.
3. Set up a housekeeper using a timer interrupt at some useful interval, say 10 mS or so. When your ADC is done, set a flag for the housekeeper to use to trigger the data send. Send the data and clear the flag.
4. Cardinal Rule: waste no time in your interrupt service routines.
That's the general idea... _________________ Confidence is the feeling you have right before you fully understand the situation... |
|
|
iKevin
Joined: 27 Mar 2008 Posts: 9
|
|
Posted: Sat Apr 12, 2008 12:40 pm |
|
|
1. Basically, I trying to control leds/motor via computer and also read the temperature from the sensor. Thus, the main() turns on/off leds and varies motor's speed.
2. Lets say I have something like this:
Code: | #include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4mhz)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, stream=PC)
int data;
#int_rda
void isr()
{
data = fgetc(PC);
}
void main(void) {
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
// I NEED TO GO BACK HERE;<-----------------------
// some settings
while(1)
{
if (data&0x02==0x02)
output_high(PIN_A);
else
output_low(PIN_A);
}
} |
How do I go back at the begining for main()
3. I'm not sure if I understand it, can you provide some CCS code to demonstrate this?
4. :D
Thank you for helping me |
|
|
KU5D
Joined: 10 Feb 2008 Posts: 46 Location: Asheville, North Carolina
|
|
Posted: Sat Apr 12, 2008 12:56 pm |
|
|
Where is it breaking? You don't really have to go back to "the beginning" of main, per se. You use main to set up your interrupts, initialize whatever variables, etc., then go into the while() loop. It's not uncommon to have a bunch of interrupt handlers and an empty while(1) loop. Unless you otherwise break it, you will aways return to the while(1) loop.
I'm not sure about your statement if(data&0x02==0x02)
perhaps:
Code: |
while(1)
{
if (data==0x02)
output_bit(PIN_A,1);
else
output_bit(PIN_A,0);
}
|
_________________ Confidence is the feeling you have right before you fully understand the situation... |
|
|
iKevin
Joined: 27 Mar 2008 Posts: 9
|
|
Posted: Sat Apr 12, 2008 1:05 pm |
|
|
I guess that will do then. What about sending ADC data every 1-2 seconds instead of every time it's done with the conversion? Can you help me with an example code?
Thanks a lot, KU5D. |
|
|
Douglas Kennedy
Joined: 07 Sep 2003 Posts: 755 Location: Florida
|
|
Posted: Sat Apr 12, 2008 2:40 pm |
|
|
Your isr fills data but it never sets a flag to the main routine to say that the data has arrived. This means your main routine will get whatever whenever. Sometimes it will be the incoming data sometimes it will be old data and at the start anything that was in ram. I know you test for a specific value but often the coder sets a flag in the receive isr to indicate that data is available and clears the flag in main after the main code reads the data. |
|
|
iKevin
Joined: 27 Mar 2008 Posts: 9
|
|
Posted: Sat Apr 12, 2008 9:50 pm |
|
|
Douglas Kennedy, how would I set the flag for this? |
|
|
KU5D
Joined: 10 Feb 2008 Posts: 46 Location: Asheville, North Carolina
|
|
Posted: Sat Apr 12, 2008 10:53 pm |
|
|
Code: |
int1 gotData = FALSE; //initialize flag to false
int8 data;
#int_rda
void isr()
{
data = fgetc(PC);
gotData = TRUE;
}
|
Then in your main;
Code: |
while(1)
{
//stuff
if(gotData == TRUE)
{
//branch accordingly;
gotData = FALSE;
}
}
|
_________________ Confidence is the feeling you have right before you fully understand the situation... |
|
|
|