CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

delay interferes with INt_rda

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Ringo42



Joined: 07 May 2004
Posts: 263

View user's profile Send private message

delay interferes with INt_rda
PostPosted: Sat Sep 29, 2007 4:23 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Sep 29, 2007 4:55 pm     Reply with quote

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







PostPosted: Sun Sep 30, 2007 2:27 am     Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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