【问题标题】:how can I escape from main while loop(C programming)?如何从 main while 循环(C 编程)中逃脱?
【发布时间】:2015-07-10 03:09:25
【问题描述】:

如果按下外部停止键,我会尝试退出主循环。 目前,AT32UC 与 ATmega128 通过 RS485 通信实现了 START 和 STOP 键。 如果接收端有数据要处理,则调用 RS485 接收中断,其中 0x10 = 开始,0x11 = 停止。

我的问题是可以很好地识别开始和停止键,如果开始,主循环将继续,如果按下停止键,我想终止主循环。 所以我已经相应地设置了开始标志和停止标志。但是,我正在努力实现停止(转义)。下面是中断例程和主循环的简要 sn-ps。

__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

【问题讨论】:

  • why "while(start_flag == false) ; " ?.. 范围是什么,它应该做什么?.. 任何地方都没有左括号或右括号,它没有做或调用任何东西使其停止
  • 嗨,我的意图是等待启动标志变高并继续。与正下方的同步部分类似,它等待同步标志变高并继续。我目前正在看gpio pin14高低进行调试。它的功能与我的意图不同吗?对不起,我是编程界的新手 :)
  • 此外,gpio pin14 如果按启动则变为高电平,如果按停止则变为低电平。但是如果我在停止键后按开始,它不会再次变高。
  • 它认为这只是不使用全局变量的问题。您在本地设置了 break_flag、start_flag 和 sync_flag 标志。尝试将它们声明为全局变量,以便保存数据更新
  • 只有一个问题:你想从main返回到哪里

标签: c while-loop embedded interrupt rs485


【解决方案1】:

你所有的标志都应该被声明为 volatile。

例如:

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

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

【讨论】:

  • 这很可能是问题所在。
  • 感谢大家的好意建议。我的标志都被全局声明为 volatile int,并且不太确定为什么它不工作是的.. 所以我目前正在将主循环重新实现到状态机中。希望这能解决问题!
猜你喜欢
  • 2016-03-11
  • 2020-08-26
  • 1970-01-01
  • 2012-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多