如何从主循环(C编程)中逃脱?

时间:2015-07-10 03:09:26

标签: c while-loop embedded interrupt rs485

如果按下外部停止键,我试图逃离主循环。 目前,通过RS485通信将AT32UC与ATmega128通信,其中实现了START和STOP键。 如果在接收器侧有要处理的数据,则调用RS485接收器中断,其中0x10 =开始,0x11 =停止。

我的问题是启动和停止键被识别得很好,如果启动则继续主循环,如果按下停止键,我想终止主循环。 所以我相应地设置了开始标志和停止标志。但是,我正在努力停止(逃避)实施。下面是中断例程和主循环的简要片段。

__attribute__((__interrupt__)) static void rs485RxInterrupt(void)
{
uint32_t data;
static char RxDatalength = 98;
data = AVR32_USART2.RHR.rxchr;

    if(data & 0x00000100) // rs485 9 bit check 
    {
        if((data & 0x000000ff) == 0x92) //dsp board address = 0x92
        {
            rxBuf[0] = data;
            addr_flag = true;
            rxInCtr = 1;
        }
        else
        {
            addr_flag = false;
            return;
        }
     }

     else if (addr_flag == true) // if 9 bit is checked
     {
         rxBuf[rxInCtr++] = data;
         if(rxInCtr == 2)           // command check
         {
            if(data < 0x80)
            {   
                if(data==0x10)  // start command
                {
                    addr_flag = false;  // reset addr flag
                    start_flag = true;
                    //RxDatalength = 0;
                }
                else if(data == 0x11)    // stop command
                    break_flag = true;
            }
            else if(data >= 0x80)
                //gpio_set_pin_high (AVR32_PIN_PA16);
                RxDatalength = 3;
        }

         if ((rxInCtr == RxDatalength) || ((RxDatalength == 98) && (rxInCtr == rxBuf[2]+1)))   // end of packet recognition
         {
            addr_flag = false;
            start_flag = true;
         }
     }
}

int main()
{
......
while(!break_flag)
{

    start_flag = false;
    while(start_flag == false)
    ;

    gpio_set_pin_high(AVR32_PIN_PA14);
    delay_us(40);
    gpio_set_pin_low(AVR32_PIN_PA14);

    //****** loop stays at this point and I am not giving sync_flag high to          
    //continue so if I press stop, I want this thing to get out of the main   
    //while loop!!


    //      peaksRdy_flag = true;
    //      SendTx(peaks);

    sync_flag = false;      // synchronising main with start of the input
    while(sync_flag == false)
        ;           
    envelopeIndex = 0;  


    for(uint32_t loop=0; loop<23; loop++)   // looping 23 times to cover approx 4.5s
    {           
        //reset counter
        sampleCounter = 0;
        samplingComplete = false;       

        //wait for sampling to finish, 256 samples
        while (samplingComplete == false)
            ;

        //gpio_set_pin_low(AVR32_PIN_PA15); // main loop indicator

        windowing(x);
        rms(x); // return ac_rms

        //gpio_set_pin_low(AVR32_PIN_PA16); // fft indicator
        fft_run(window);    // return fft magnitude
        //gpio_set_pin_high(AVR32_PIN_PA16);

        peak_search(fft_mag);
        envelope_output(envelope);

        // Function to transmit analysed data through RS485 communication.  
        //SendTx(peaks);

        sprintf(filtResult, "%04d %04d %04d %04d %04d\n", (int)peaks[loop][0], (int)peaks[loop][1], (int)peaks[loop][2], (int)peaks[loop][3],(int)ac_rms);
        char *ptr = &filtResult[0];
        do
        {
            c = *ptr;
            ptr++;
            usart_bw_write_char(&AVR32_USART2, (int)c);
            // sendByte(c);

        } while (c != '\n');
        //gpio_set_pin_high(AVR32_PIN_PA15);

    } // outer loop

        sprintf(filtResult, "%04d\n", (int)duty);
        char *ptr = &filtResult[0];
        do
            {
                c = *ptr;
                ptr++;
                usart_bw_write_char(&AVR32_USART2, (int)c);
                // sendByte(c);
            } while (c != '\n');
    break;
    }//while

 }//main

1 个答案:

答案 0 :(得分:6)

所有标志都应声明为volatile。

例如:

volatile int start_flag, sync_flag /*,other_flag ... */;

否则编译器可以优化检查其值是否被当前块之外的代码更改。