標題: C語言while嵌套中,判斷條件改變后,執(zhí)行程序為啥沒有改變? [打印本頁]

作者: hxdby    時間: 2022-2-24 23:26
標題: C語言while嵌套中,判斷條件改變后,執(zhí)行程序為啥沒有改變?
我做一個方案,就是做一個小的監(jiān)控器(帶顯示屏),隨時監(jiān)控設備運行情況,當設備發(fā)生緊急情況時,監(jiān)控器立即啟動報警,同時顯示屏上顯示對應的故障碼。

緊急情況有兩種,設備過流(對應故障碼E1),以及設備過載(對應故障碼E2).

緊急情況的優(yōu)先級最高,當程序正常運行時,一旦發(fā)生緊急情況,無論當前在運行什么程序,必須無條件跳轉(zhuǎn)到緊急情況程序中,緊急情況結(jié)束后,再自動返回到之前運行的程序中。

程序框架如下:

int  main(void)
{

uint8_t   over_current_flag=1;  //過流發(fā)生標志位, 當為低時,表示過流發(fā)生,下同
uint8_t   over_load_flag=1; //設備過載標志位

while(1)
{

   normal_run(); //正常運行程序,即時監(jiān)控

   while(!over_current_flag || !over_load_flag)  //檢測到低電平時,立即跳轉(zhuǎn)到該循環(huán)

    ErrorCode_DISPALY() ;  //根據(jù)發(fā)生實際情況,顯示E1, E2, 或兩種同時發(fā)生時,組合顯示E1,E2

}

}



void  ErrorCode_DISPLAY()
{
if(!over_current_flag)
E1_DISPLAY(); //過流時顯示E1

if(!over_load_flag)
E2_DISPLAY(); //過載時顯示E2

if(!over_current_flag && !over_load_flag)
E12_DISPLAY(); //過流和過載同時發(fā)生,顯示屏同時顯示E1和E2

}


現(xiàn)在的問題是:
如果只發(fā)生一種, 比如E1或E2,顯示屏可以正常顯示,沒問題。如果發(fā)生了過流,顯示屏顯示E1, 過了一會,又發(fā)生了過載,可是仍然顯示的是E1. 并不會同時顯示E1,E2, 這是為何呢?
當發(fā)生E1時,由于 while循環(huán)中while(!over_current_flag || !over_load_flag) 用的是||,只要有一個為真就執(zhí)行程序,此時!over_current_flag 為真,開始執(zhí)行程序。后來當!over_load_flag也為真時,并沒有改變!over_current_flag || !over_load_flag整個的邏輯,因為他一直為真,是這個原因嗎?還是其他什么原因呢?

作者: qq603599910    時間: 2022-2-25 08:20
個人淺見,首先邏輯沒有理清12狀態(tài)獨立區(qū)分,一旦發(fā)生12,首先是1,然后2,然后如果沒有什么處理12依然會顯示.和while沒有大關(guān)系.
作者: man1234567    時間: 2022-2-25 08:26
E1發(fā)生后,是否卡死在報警而不去檢測了 ?
只給出片段讓大家猜謎真的不好玩
作者: TEC    時間: 2022-2-25 09:18
是你說的情況,過流如果不消除,就一直在執(zhí)行while循環(huán)里的
作者: TEC    時間: 2022-2-25 09:21
如果需要區(qū)分,就要做更多的邏輯判斷,比如只有過流while(!over_current_flag &&over_load_flag),過流和過載同時有,while(!over_current_flag && !over_load_flag);
只有過載while(over_current_flag && !over_load_flag);
作者: wulin    時間: 2022-2-25 09:23
單從樓主貼的代碼看不出有什么大問題,問題應該出在顯示代碼中。建議樓主不要在主循環(huán)中使用while(x)不確定的長時間等待,而是要讓程序不停跑起來。
  1. void main(void)
  2. {
  3.         uint8_t   over_current_flag=1;  //過流發(fā)生標志位, 當為低時,表示過流發(fā)生,下同
  4.         uint8_t   over_load_flag=1; //設備過載標志位
  5.         uint8_t   state=0,state_A=0;//狀態(tài)變量

  6.         while(1)
  7.         {
  8.                 if(!over_current_flag || !over_load_flag)  //檢測到低電平時
  9.                 {

  10.                         if(!over_current_flag && !over_load_flag) state=4; //過流和過載同時發(fā)生

  11.                         else if(!over_current_flag) state=2;//過流
  12.                        
  13.                         else state=3;//過載

  14.                 }
  15.                 else state=1; //正常

  16.                 if(state_A != state)//即時監(jiān)控,當狀態(tài)發(fā)生變化時
  17.                 {
  18.                         state_A = state;//保存當前狀態(tài)
  19.                         ErrorCode_DISPLAY(state);//更新顯示
  20.                 }
  21.         }
  22. }

  23. void  ErrorCode_DISPLAY(uint8_t Code)
  24. {
  25.         switch(Code)
  26.         {
  27.                 case 1: /*顯示正常  */ break;
  28.                 case 2: /*顯示E1    */ break;
  29.                 case 3: /*顯示E2    */ break;
  30.                 case 4: /*顯示E1、E2*/ break;
  31.                 default:/*          */ break;
  32.         }
  33. }
復制代碼

作者: hxdby    時間: 2022-2-25 09:56
man1234567 發(fā)表于 2022-2-25 08:26
E1發(fā)生后,是否卡死在報警而不去檢測了 ?
只給出片段讓大家猜謎真的不好玩

檢測主要是硬件檢測的,軟件上很簡單,就是用這兩個變量over_current_flag  和over_load_flag來監(jiān)控的,因為這兩個變量是直接連接到單片機IO口的,如果IO口變?yōu)榈停琽ver_current_flag  和over_load_flag就為0,反之為1,沒其他檢測代碼
作者: LPB2021    時間: 2022-2-25 10:24
沒清標志位的話程序都有運行,只是后面的那段運行較快,你顯示的時候只顯示第一次運行的那個
作者: hxdby    時間: 2022-2-25 10:53
wulin 發(fā)表于 2022-2-25 09:23
單從樓主貼的代碼看不出有什么大問題,問題應該出在顯示代碼中。建議樓主不要在主循環(huán)中使用while(x)不確定 ...

感謝大神提供的代碼!感謝幫助!從你這里真的學到好多東西,萬分感謝!
作者: yzwzfyz    時間: 2022-2-26 11:15
因為你是循環(huán)做事的:
E1時,就去除了E2
E2時,又不做E1了
E1、E2時,雖然都做了,但旋即你又循環(huán)加頭,做E1,去除了E2……
總體年上去,E1、E2時你不斷的切換,改變顯示方式
明白道理就知道如何處理了。方法很多,這里說兩個:
1、先判E1E2,是,顯示退出;再判E1,是,顯示退出;最后再E2……。(要點,每個做完退出,復雜的先做)
2、先清顯示;再分別判E1、E2,無需判E1E2同時,重點來了:顯示E1時不清E2,顯示E2時也不清E1。即讓E1與E2在表達上(顯示上)無關(guān)聯(lián)。
以上1、2、都能達成目的,但不是很好的方案,自己再想更好的方案吧。




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1