|
|
View previous topic :: View next topic |
Author |
Message |
Ringo42
Joined: 07 May 2004 Posts: 263
|
delay interferes with INt_rda |
Posted: Sat Sep 29, 2007 4:23 pm |
|
|
I'm using a pic18452 at 20mhz, talking 19200 from a pc.
In main I have code that looks like this.
if(SonarEnabled==1)
{
for(SonarNumber=0;SonarNumber<10;SonarNumber++)
{
range=timeEcho2(trig,echo);
delay_ms(Delay_between_readings);
}
}
When SonarEnabled is = to 1 then it is very difficult to send commands to the board. In My PC app I have to send a char, wait 10ms, then send another char, etc. When SonarEnabled=0 I can send a variety of commands with any delay, so I'm assuming it has something to do with the delay_ms. Does delay_ms turn off serial ints?
Here is the TimeEcho code, I don't think there is anything in it that would cause interference.
Code: |
int32 timeEcho2(int trigger, int echo)
{
int timeout=0;
int16 RawData=0;
int16 ccs_trig, ccs_echo;
int8 retval;
unsigned int flight_time=0;
//trigger goes high for 10us minimum
//wait for echo to go high
//time how long echo is high
//100us to 25ms
switch(trigger)
{
case(0):
ccs_trig=PIN_C1;
ccs_echo=Pin_C0;
break;
case(2):
ccs_trig=PIN_D0;
ccs_echo=Pin_C2;
break;
case(4):
ccs_trig=PIN_D2;
ccs_echo=Pin_D1;
break;
case(6):
ccs_trig=PIN_C5;
ccs_echo=Pin_D3;
break;
case(8):
ccs_trig=PIN_D5;
ccs_echo=Pin_D4;
break;
case(10):
ccs_trig=PIN_D7;
ccs_echo=Pin_D6;
break;
case(12):
ccs_trig=PIN_B1;
ccs_echo=Pin_B0;
break;
case(14):
ccs_trig=PIN_B3;
ccs_echo=Pin_B2;
break;
case(16):
ccs_trig=PIN_B5;
ccs_echo=Pin_B4;
break;
case(18):
ccs_trig=PIN_E2;
ccs_echo=Pin_E1;
break;
}
// start off with the trigger low, just in case
output_low(ccs_trig);
delay_us(25);
// pulse the trigger to send the ping
output_high(ccs_trig);
delay_us(25);
output_low(ccs_trig);
//
// Wait for the ping to actually be sent- it may be slightly delayed
while(input(ccs_echo) == 0)//700 us delay
{
delay_us(10);
timeout++;
if(timeout >150)//timeout
{
return(0);
}
}
//Start timing the return flight
set_timer0(0); // timer0 is .4us per timer tick
while(input(ccs_echo)==1)
{
RawData = get_timer0();
//timeout after 25ms
if(RawData > 62500) // .4*62500=25ms
return(0);
}
// Raw data is 0.4us.
// sonar = 147us/inch.
// 1/.4 = 2.5 ticks/us
// 147us/inch*2.5ticks/us=367 ticks/inch
if(Sonar_data_mode == 0)//cm
{
flight_time=RawData/145; // 367/2.54 (inches to Cm)
if(debug==1)
printf("Sonar_data_mode == %d dist = %d\r\n",Sonar_data_mode,flight_time);
return(flight_time);
}
else if(Sonar_data_mode == 1)//inch
{
flight_time=RawData/367;
if(debug==1)
printf("Sonar_data_mode == %d dist = %d\r\n",Sonar_data_mode,flight_time);
return(flight_time);
}
else
{
// Raw Mode
if(debug==1)
printf("Sonar_data_mode == %d dist = %ld\r\n",Sonar_data_mode,RawData);
return(RawData);
}
}
|
My serial int is here. I use the same function on a bunch of different boards so I don't think there is anything wrong with it.
Code: |
#int_rda //HIGH
void serial_int_routine()
{
disable_interrupts(INT_RDA); // RS232 OFF
//printf(".");
// Read incoming byte:
*curPos = getc();
//putc(*curPos);
// Make sure we don't overrun the buffer:
if (curCnt < SERIAL_BUFFER_SIZE)
{
// End of command, set flag to process the command:
if (*curPos =='\r')
{
// printf("processing commands\r\n");
// putc('z');
ProcessCommands();
// Reset pointer to beginning of buffer:
curPos = SERIAL_BUFFER;
curCnt = 0;
}
else
{
// Increment buffer position:
curPos++;
curCnt++;
}
}
else
{
curCnt = 0;
curPos = SERIAL_BUFFER;
}
enable_interrupts(INT_RDA); // RS232 ON
}
|
Any Ideas?
Thanks
Ringo _________________ Ringo Davis |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1934 Location: Norman, OK
|
|
Posted: Sat Sep 29, 2007 4:55 pm |
|
|
I try to never use delay_ms() type routines at all. They are VERY
inefficient and can also interfere with other processes running in in your
code. With these types of delays your processor is in a tight loop and is
completely wasting time when other things can be accomplished during the
delay.
I set up timers to keep track of delays and just loop in the background
code doing other things until the desired delay flag is set. See one of my
posts in another thread on how it can be done:
http://www.ccsinfo.com/forum/viewtopic.php?t=26600
Also, I don't know what ProcessCommands() does but you should never
try to use PRINTF, PUTC etc. or execute any subroutines while in an RDA
interrupt. The rule of thumb is to keep it "short and sweet". Receive the
RS232 data, put it in a processing queue, set a flag if required and and get
out QUICK. You only have milliseconds (or less depending on baud rate)
between interrupts. Interrupts are NOT re-entrant and you MUST be out of
the interrupt routine before the next interrupt occurs.
Finally, enabling and disabling interrupts in the interrupt routine is not
recommended. Let the compiler take care of this automatically.
I hope this helps....
dave |
|
|
Ttelmah Guest
|
|
Posted: Sun Sep 30, 2007 2:27 am |
|
|
First, get rid of the interrupt disable/enable in the interrupt handler. This is not wanted, and is doing nothing. The hardware, disables _all_ interrupts, when you are inside the handlers (except when delaing with hardware 'high priority' interrupts). Though this won't cause a problem, it is two wasted instructons!...
Now, delays, _do not disable interrupts_, _unless you use delays inside the interrupt_. You do not show the 'ProcessCommands' code, but if this contains any delays, then this is the cause of your problem.
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
|