找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 872|回復(fù): 33
打印 上一主題 下一主題
收起左側(cè)

while(1)循環(huán)是不是很慢

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:1144680 發(fā)表于 2025-5-31 21:06 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
DS1302時(shí)鐘,在while(1)里有兩個(gè)"if"檢測(cè)按鍵,沒(méi)有按鍵時(shí)用switch/case顯示時(shí)鐘,結(jié)果發(fā)現(xiàn)時(shí)鐘不同步,秒進(jìn)位時(shí),有時(shí)候“小時(shí)”或“分鐘”會(huì)延遲1秒左右,這是while循環(huán)有延遲嗎?
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:712493 發(fā)表于 2025-5-31 21:46 | 只看該作者
肯定不是,while(1)只是大循環(huán)而已!
回復(fù)

使用道具 舉報(bào)

板凳
ID:584814 發(fā)表于 2025-5-31 22:33 | 只看該作者
可能是防抖功能的設(shè)計(jì)問(wèn)題
回復(fù)

使用道具 舉報(bào)

地板
ID:619259 發(fā)表于 2025-5-31 23:38 | 只看該作者
時(shí)間有延時(shí)與while(1)無(wú)關(guān),秒溢出,分+1延時(shí),應(yīng)該是你的1302讀寫(xiě)函數(shù)有延時(shí)了。
回復(fù)

使用道具 舉報(bào)

5#
ID:624769 發(fā)表于 2025-5-31 23:54 | 只看該作者
是你讀DS1302代碼的問(wèn)題
回復(fù)

使用道具 舉報(bào)

6#
ID:1128898 發(fā)表于 2025-6-1 06:15 | 只看該作者
延遲對(duì)的,信號(hào)并不是時(shí)時(shí)的,關(guān)鍵看處理什么控制什么,又不是f16
回復(fù)

使用道具 舉報(bào)

7#
ID:1109793 發(fā)表于 2025-6-1 07:51 | 只看該作者
是一個(gè)循環(huán),慢不慢,看你代碼啊
回復(fù)

使用道具 舉報(bào)

8#
ID:1144680 發(fā)表于 2025-6-1 13:45 | 只看該作者
xiaobendan001 發(fā)表于 2025-6-1 07:51
是一個(gè)循環(huán),慢不慢,看你代碼啊

幫忙看看,謝謝!

  1.         while (1)      
  2. {       
  3.       if (TM1639_KEY_B1==1)
  4. {
  5.     _nop_();
  6.     while(TM1639_KEY_B1==1);//按住不放
  7.     _nop_();
  8.         SetSelect++;//松手后
  9.        
  10.                                 if(SetSelect>=7){SetSelect=0;DS1302_GengxinTime();}        //更新時(shí)間                       
  11.                                
  12. //                                        LED_OF[TimeWei-1]=0xff;        //離開(kāi)該位顯示,防止正好熄滅       
  13.                                 LED_OF[0]=0xff;
  14.                                 LED_OF[1]=0xff;                                
  15.                                 LED_OF[3]=0xff;        
  16.                                 LED_OF[4]=0xff;
  17.                                 LED_OF[6]=0xff;                                
  18.                                 LED_OF[7]=0xff;                                        
  19. }
  20.                         switch(SetSelect)
  21.                         {
  22.                                 case 0:        TimeShow(); break;        //讀取并顯示時(shí)間
  23.                                 case 1:        TimeWei=0;        break;        //10時(shí)               
  24.                                 case 2:        TimeWei=1;        break;        // 時(shí)               
  25.                                 case 3:        TimeWei=3;        break;                //10分       
  26.                                 case 4: TimeWei=4;        break;                //分       
  27.                                 case 5:        TimeWei=6;        break;        //10秒                       
  28.                                 case 6: TimeWei=7;        break;        //秒       
  29.                         }
  30.                
  31. if (TM1639_KEY_B2==1)
  32.         {
  33.     _nop_();
  34.     while(TM1639_KEY_B2==1);//按住不放
  35.     _nop_();
  36.                
  37.     Shezhi();        //設(shè)置時(shí)間
  38.         }       
  39.                
  40. }
復(fù)制代碼



回復(fù)

使用道具 舉報(bào)

9#
ID:1144680 發(fā)表于 2025-6-1 13:47 | 只看該作者
  1. void TimeShow()
  2. {
  3.      DS1302_ReadTime();//讀取時(shí)間
  4.           LED_BCD[0] =DS1302_Time[0];                  //最高位,10時(shí)               
  5.           LED_BCD[1] =DS1302_Time[1];         

  6.           LED_BCD[3] =DS1302_Time[3];                        
  7.           LED_BCD[4] =DS1302_Time[4];                       

復(fù)制代碼


顯示時(shí)間代碼
回復(fù)

使用道具 舉報(bào)

10#
ID:1144680 發(fā)表于 2025-6-1 13:49 | 只看該作者
man1234567 發(fā)表于 2025-5-31 22:33
可能是防抖功能的設(shè)計(jì)問(wèn)題

是有兩個(gè)延遲,不過(guò)是按鍵按下后才起作用。
回復(fù)

使用道具 舉報(bào)

11#
ID:1144680 發(fā)表于 2025-6-1 13:50 | 只看該作者
cy009 發(fā)表于 2025-5-31 23:38
時(shí)間有延時(shí)與while(1)無(wú)關(guān),秒溢出,分+1延時(shí),應(yīng)該是你的1302讀寫(xiě)函數(shù)有延時(shí)了。

有點(diǎn)頭暈,下面有代碼,能不能幫忙看看。。。
回復(fù)

使用道具 舉報(bào)

12#
ID:1144680 發(fā)表于 2025-6-1 13:51 | 只看該作者
188610329 發(fā)表于 2025-5-31 23:54
是你讀DS1302代碼的問(wèn)題

一開(kāi)始沒(méi)問(wèn)題,后來(lái)加了按鍵檢測(cè)后出現(xiàn)的,不知道哪個(gè)環(huán)節(jié)出的。
回復(fù)

使用道具 舉報(bào)

13#
ID:1152291 發(fā)表于 2025-6-1 16:53 | 只看該作者
dcc60 發(fā)表于 2025-6-1 13:51
一開(kāi)始沒(méi)問(wèn)題,后來(lái)加了按鍵檢測(cè)后出現(xiàn)的,不知道哪個(gè)環(huán)節(jié)出的。

其實(shí)加了按鍵檢測(cè)是不太靈敏的,首先按鍵檢測(cè)是是基于一個(gè)模塊的,但是你如果添加了多個(gè)模塊的話(huà),按鍵檢測(cè)到底是應(yīng)用于誰(shuí)了,所以基于按鍵檢測(cè)模塊的書(shū)寫(xiě),一般是只能需求一個(gè)模塊的,多個(gè)模塊添加進(jìn)來(lái),是會(huì)使軟件整混的,應(yīng)用于仿真和實(shí)物都是不太靈敏的。
回復(fù)

使用道具 舉報(bào)

14#
ID:1133081 發(fā)表于 2025-6-1 17:31 | 只看該作者
dcc60 發(fā)表于 2025-6-1 13:51
一開(kāi)始沒(méi)問(wèn)題,后來(lái)加了按鍵檢測(cè)后出現(xiàn)的,不知道哪個(gè)環(huán)節(jié)出的。

TM1639讀到的鍵值是1個(gè)字節(jié),并不是位信號(hào)0/1。沒(méi)有看到相關(guān)代碼,無(wú)法判斷與你所說(shuō)的延遲1秒是否有關(guān)。
回復(fù)

使用道具 舉報(bào)

15#
ID:1152365 發(fā)表于 2025-6-1 17:40 | 只看該作者
肯定不是,while(1)只是大循環(huán)而已
回復(fù)

使用道具 舉報(bào)

16#
ID:1144680 發(fā)表于 2025-6-1 18:15 | 只看該作者
WL0123 發(fā)表于 2025-6-1 17:31
TM1639讀到的鍵值是1個(gè)字節(jié),并不是位信號(hào)0/1。沒(méi)有看到相關(guān)代碼,無(wú)法判斷與你所說(shuō)的延遲1秒是否有關(guān)。

估計(jì)是我搞錯(cuò)了。
下次把按鍵改為單片機(jī)引腳。
回復(fù)

使用道具 舉報(bào)

17#
ID:1144680 發(fā)表于 2025-6-1 18:17 | 只看該作者
單片機(jī)重購(gòu) 發(fā)表于 2025-6-1 16:53
其實(shí)加了按鍵檢測(cè)是不太靈敏的,首先按鍵檢測(cè)是是基于一個(gè)模塊的,但是你如果添加了多個(gè)模塊的話(huà),按鍵檢 ...

太復(fù)雜了。
謝謝支持,再研究研究。
回復(fù)

使用道具 舉報(bào)

18#
ID:883242 發(fā)表于 2025-6-2 18:48 | 只看該作者
就是while按鍵那兩句卡住的。
回復(fù)

使用道具 舉報(bào)

19#
ID:1144680 發(fā)表于 2025-6-3 10:27 | 只看該作者
Hephaestus 發(fā)表于 2025-6-2 18:48
就是while按鍵那兩句卡住的。

下次刪了試試。
回復(fù)

使用道具 舉報(bào)

20#
ID:1152291 發(fā)表于 2025-6-3 17:10 | 只看該作者
有時(shí)候不用while(1)進(jìn)行循環(huán),用其它語(yǔ)言指令對(duì)單片機(jī)進(jìn)行書(shū)寫(xiě)也是可以使得單片機(jī)的程序可以運(yùn)行起來(lái)
回復(fù)

使用道具 舉報(bào)

21#
ID:1152595 發(fā)表于 2025-6-3 18:41 | 只看該作者
這個(gè)函數(shù)本身沒(méi)有快慢的說(shuō)法,主要看內(nèi)部函數(shù)
回復(fù)

使用道具 舉報(bào)

22#
ID:1152630 發(fā)表于 2025-6-3 22:48 來(lái)自觸屏版 | 只看該作者
試一下移除按鍵檢測(cè)中的延時(shí)消抖,改為狀態(tài)機(jī)方式。
回復(fù)

使用道具 舉報(bào)

23#
ID:65956 發(fā)表于 2025-6-4 08:32 | 只看該作者
你可以不用while試試,因?yàn)橛眠@個(gè)就是在死等,等超時(shí)了才重新來(lái)
回復(fù)

使用道具 舉報(bào)

24#
ID:1144680 發(fā)表于 2025-6-4 10:58 | 只看該作者
aking991 發(fā)表于 2025-6-4 08:32
你可以不用while試試,因?yàn)橛眠@個(gè)就是在死等,等超時(shí)了才重新來(lái)

在計(jì)時(shí)器里試過(guò),沒(méi)有延遲。
問(wèn)題是以前也沒(méi)有延遲,按說(shuō),即便延遲,應(yīng)該時(shí)分秒一起延遲才對(duì)。
回復(fù)

使用道具 舉報(bào)

25#
ID:1144680 發(fā)表于 2025-6-4 11:51 | 只看該作者
Hephaestus 發(fā)表于 2025-6-2 18:48
就是while按鍵那兩句卡住的。

試過(guò)了,不是按鍵問(wèn)題。
回復(fù)

使用道具 舉報(bào)

26#
ID:1144680 發(fā)表于 2025-6-4 11:53 | 只看該作者
單片機(jī)重購(gòu) 發(fā)表于 2025-6-3 17:10
有時(shí)候不用while(1)進(jìn)行循環(huán),用其它語(yǔ)言指令對(duì)單片機(jī)進(jìn)行書(shū)寫(xiě)也是可以使得單片機(jī)的程序可以運(yùn)行起來(lái)

是的,放在定時(shí)器里就沒(méi)延遲。
回復(fù)

使用道具 舉報(bào)

27#
ID:1144680 發(fā)表于 2025-6-4 11:55 | 只看該作者
2631449463 發(fā)表于 2025-6-3 22:48
試一下移除按鍵檢測(cè)中的延時(shí)消抖,改為狀態(tài)機(jī)方式。

試了,可能還是其它問(wèn)題。
回復(fù)

使用道具 舉報(bào)

28#
ID:1152676 發(fā)表于 2025-6-4 12:06 | 只看該作者
在DS1302時(shí)鐘程序中,當(dāng)`while(1)`循環(huán)內(nèi)用兩個(gè)`if`檢測(cè)按鍵,且無(wú)按鍵時(shí)通過(guò)`switch/case`顯示時(shí)鐘,出現(xiàn)時(shí)間不同步(如秒進(jìn)位時(shí)小時(shí)或分鐘延遲1秒左右),**主要原因是按鍵檢測(cè)邏輯導(dǎo)致主循環(huán)阻塞,影響了時(shí)鐘數(shù)據(jù)的及時(shí)讀取和刷新**。以下是具體分析和解決思路:   ### **一、問(wèn)題根源:主循環(huán)阻塞導(dǎo)致時(shí)鐘更新延遲** 1. **按鍵檢測(cè)的潛在阻塞**      如果`if`語(yǔ)句中直接使用**延時(shí)消抖**(如`delay(20ms)`)或復(fù)雜邏輯,會(huì)導(dǎo)致整個(gè)`while(1)`循環(huán)卡頓。例如:      ```c    while(1) {        if(按鍵按下) {            delay(20ms); // 阻塞20ms,期間無(wú)法讀取時(shí)鐘            // 處理按鍵        }        // 讀取DS1302時(shí)鐘并顯示    }    ```      此時(shí),若按鍵按下,程序會(huì)在`delay`處停留20ms,導(dǎo)致**DS1302的秒更新可能被錯(cuò)過(guò)**,進(jìn)而出現(xiàn)顯示延遲。  2. **循環(huán)頻率與時(shí)鐘更新不匹配**      DS1302的秒數(shù)據(jù)每秒更新一次,若主循環(huán)執(zhí)行周期較長(zhǎng)(如因按鍵檢測(cè)耗時(shí)),可能導(dǎo)致:      - 秒進(jìn)位時(shí),程序尚未讀取到最新數(shù)據(jù),仍在顯示舊值;      - 下一次循環(huán)讀取時(shí),秒已進(jìn)位,但分鐘/小時(shí)的計(jì)算依賴(lài)舊秒值,導(dǎo)致延遲。   ### **二、解決方案:非阻塞式按鍵檢測(cè)與定時(shí)刷新時(shí)鐘** #### **1. 核心思路**   - **用定時(shí)器中斷掃描按鍵**,避免主循環(huán)阻塞;   - **定時(shí)讀取DS1302時(shí)鐘**(如每100ms一次),確保數(shù)據(jù)更新頻率穩(wěn)定。  #### **2. 具體實(shí)現(xiàn)步驟**   ##### **(1)改用定時(shí)器中斷檢測(cè)按鍵(非阻塞式)**   - **原理**:通過(guò)定時(shí)器(如1ms中斷)周期性?huà)呙璋存I狀態(tài),用狀態(tài)機(jī)記錄按鍵按下、消抖、釋放的過(guò)程,避免主循環(huán)中直接延時(shí)。   - **示例邏輯**:     ```c   unsigned char key_state = 0; // 0=未按下,1=按下消抖中,2=確認(rèn)按下,3=釋放等待   unsigned char key_flag = 0;  // 按鍵觸發(fā)標(biāo)志    // 定時(shí)器1ms中斷函數(shù)   void Timer0_ISR() interrupt 1 {       if(按鍵按下) {           switch(key_state) {               case 0: key_state = 1; break; // 首次檢測(cè)到按下,進(jìn)入消抖               case 1: key_state = 2; key_flag = 1; break; // 消抖完成,標(biāo)記按鍵觸發(fā)           }       } else {           key_state = 0; // 按鍵釋放,重置狀態(tài)       }   }   ```  ##### **(2)定時(shí)讀取DS1302時(shí)鐘數(shù)據(jù)**   - **原理**:在主循環(huán)中用計(jì)數(shù)器控制讀取頻率(如每100ms讀取一次),避免頻繁讀取占用資源。   - **示例邏輯**:     ```c   unsigned int tick = 0; // 計(jì)數(shù)器   unsigned char time_buf[7]; // 存儲(chǔ)時(shí)分秒等數(shù)據(jù)    while(1) {       if(tick >= 100) { // 每100ms讀取一次(100ms=0.1秒,可根據(jù)需求調(diào)整)           tick = 0;           DS1302_ReadTime(time_buf); // 讀取時(shí)鐘數(shù)據(jù)       }              // 顯示時(shí)鐘(switch/case邏輯)       switch(mode) {           case 0: 顯示正常時(shí)間; break;           case 1: 顯示調(diào)時(shí)界面; break;           // ...其他模式       }              tick++; // 每循環(huán)一次自增,控制讀取頻率       // 其他非阻塞操作(如少量延時(shí)或任務(wù))   }   ```  ##### **(3)優(yōu)化顯示邏輯**   - 確保`switch/case`中的顯示函數(shù)(如數(shù)碼管驅(qū)動(dòng))執(zhí)行速度快,避免包含耗時(shí)操作(如長(zhǎng)延時(shí))。   - 若顯示需要?jiǎng)討B(tài)效果(如閃爍),可通過(guò)定時(shí)器中斷控制,而非在主循環(huán)中阻塞。   ### **三、其他可能原因及排查方向** 1. **DS1302通信時(shí)序問(wèn)題**      - 檢查讀寫(xiě)函數(shù)是否嚴(yán)格遵循DS1302的時(shí)序要求(如時(shí)鐘沿、復(fù)位信號(hào)順序),避免因通信錯(cuò)誤導(dǎo)致數(shù)據(jù)讀取失敗。   2. **變量緩存與臨界資源**      - 若在中斷中修改時(shí)間數(shù)據(jù),需用`volatile`關(guān)鍵字聲明變量,并在主循環(huán)讀取時(shí)關(guān)閉中斷,避免數(shù)據(jù)不一致。   3. **晶振穩(wěn)定性**      - DS1302的走時(shí)精度依賴(lài)外部晶振(如32.768kHz),若晶振質(zhì)量差或電容匹配不當(dāng),可能導(dǎo)致實(shí)際秒長(zhǎng)偏移,需硬件排查。   ### **四、總結(jié)**   - **核心問(wèn)題**:按鍵檢測(cè)的阻塞式邏輯導(dǎo)致主循環(huán)無(wú)法及時(shí)讀取和刷新時(shí)鐘數(shù)據(jù)。   - **解決關(guān)鍵**:用定時(shí)器中斷實(shí)現(xiàn)非阻塞按鍵掃描,主循環(huán)專(zhuān)注于定時(shí)讀取時(shí)鐘和快速顯示,確保每秒至少讀取一次時(shí)鐘數(shù)據(jù)(如每100ms讀取一次,每秒可讀取10次),避免秒進(jìn)位被遺漏。   - **擴(kuò)展建議**:若系統(tǒng)支持多任務(wù)(如RTOS),可將按鍵處理、時(shí)鐘讀取、顯示分別分配到獨(dú)立任務(wù),通過(guò)消息隊(duì)列或信號(hào)量同步,進(jìn)一步提升實(shí)時(shí)性。
回復(fù)

使用道具 舉報(bào)

29#
ID:1144680 發(fā)表于 2025-6-4 13:38 | 只看該作者
jzh1 發(fā)表于 2025-6-4 12:06
在DS1302時(shí)鐘程序中,當(dāng)`while(1)`循環(huán)內(nèi)用兩個(gè)`if`檢測(cè)按鍵,且無(wú)按鍵時(shí)通過(guò)`switch/case`顯示時(shí)鐘,出現(xiàn) ...

謝謝支持。說(shuō)的很詳細(xì)。
經(jīng)過(guò)反復(fù)試驗(yàn),發(fā)現(xiàn)循環(huán)之前的主函數(shù)運(yùn)行時(shí)間太長(zhǎng)(1-2秒左右),可能是造成不同步的主要原因。時(shí)分秒是直接讀取DS1302時(shí)間,不是按秒進(jìn)位,理應(yīng)“快、慢”同步才對(duì),不知道為什么分鐘或小時(shí)會(huì)慢1秒。
回復(fù)

使用道具 舉報(bào)

30#
ID:1146186 發(fā)表于 2025-6-9 09:11 | 只看該作者
while(1) 本身不慢,但你在循環(huán)里做了按鍵檢測(cè)( if ) + 時(shí)鐘顯示( switch/case ),這倆操作會(huì)占用CPU時(shí)間。秒進(jìn)位時(shí),若CPU正忙按鍵檢測(cè)或顯示邏輯,沒(méi)及時(shí)讀取DS1302的最新時(shí)間,就會(huì)“延遲1秒”,本質(zhì)是主循環(huán)被耗時(shí)任務(wù)阻塞,沒(méi)做到“實(shí)時(shí)響應(yīng)時(shí)鐘更新”。
回復(fù)

使用道具 舉報(bào)

31#
ID:1146186 發(fā)表于 2025-6-9 10:52 | 只看該作者
while(1) 本身不慢,但你在循環(huán)里做了按鍵檢測(cè)( if ) + 時(shí)鐘顯示( switch/case ),這倆操作會(huì)占用CPU時(shí)間。秒進(jìn)位時(shí),若CPU正忙按鍵檢測(cè)或顯示邏輯,沒(méi)及時(shí)讀取DS1302的最新時(shí)間,就會(huì)“延遲1秒”,本質(zhì)是主循環(huán)被耗時(shí)任務(wù)阻塞,沒(méi)做到“實(shí)時(shí)響應(yīng)時(shí)鐘更新”
回復(fù)

使用道具 舉報(bào)

32#
ID:1153440 發(fā)表于 2025-6-10 15:15 | 只看該作者
與while(1)無(wú)關(guān)吧,更多與內(nèi)部函數(shù)相關(guān)
回復(fù)

使用道具 舉報(bào)

33#
ID:1144680 發(fā)表于 2025-6-10 21:26 | 只看該作者
1763333333 發(fā)表于 2025-6-9 10:52
while(1) 本身不慢,但你在循環(huán)里做了按鍵檢測(cè)( if ) + 時(shí)鐘顯示( switch/case ),這倆操作會(huì)占用CPU時(shí) ...

在while里只留timeshow也還是不同步,估計(jì)與主函數(shù)有關(guān)。
回復(fù)

使用道具 舉報(bào)

34#
ID:1144680 發(fā)表于 2025-6-10 21:26 | 只看該作者
gmlxh 發(fā)表于 2025-6-10 15:15
與while(1)無(wú)關(guān)吧,更多與內(nèi)部函數(shù)相關(guān)

應(yīng)該是的,現(xiàn)在放在定時(shí)器里就正常。
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表