久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 777|回復: 33
收起左側

while(1)循環是不是很慢

  [復制鏈接]
ID:1144680 發表于 2025-5-31 21:06 | 顯示全部樓層 |閱讀模式
DS1302時鐘,在while(1)里有兩個"if"檢測按鍵,沒有按鍵時用switch/case顯示時鐘,結果發現時鐘不同步,秒進位時,有時候“小時”或“分鐘”會延遲1秒左右,這是while循環有延遲嗎?
回復

使用道具 舉報

ID:712493 發表于 2025-5-31 21:46 | 顯示全部樓層
肯定不是,while(1)只是大循環而已!
回復

使用道具 舉報

ID:584814 發表于 2025-5-31 22:33 | 顯示全部樓層
可能是防抖功能的設計問題
回復

使用道具 舉報

ID:619259 發表于 2025-5-31 23:38 | 顯示全部樓層
時間有延時與while(1)無關,秒溢出,分+1延時,應該是你的1302讀寫函數有延時了。
回復

使用道具 舉報

ID:624769 發表于 2025-5-31 23:54 | 顯示全部樓層
是你讀DS1302代碼的問題
回復

使用道具 舉報

ID:1128898 發表于 2025-6-1 06:15 | 顯示全部樓層
延遲對的,信號并不是時時的,關鍵看處理什么控制什么,又不是f16
回復

使用道具 舉報

ID:1109793 發表于 2025-6-1 07:51 | 顯示全部樓層
是一個循環,慢不慢,看你代碼啊
回復

使用道具 舉報

ID:1144680 發表于 2025-6-1 13:45 | 顯示全部樓層
xiaobendan001 發表于 2025-6-1 07:51
是一個循環,慢不慢,看你代碼啊

幫忙看看,謝謝!

  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();}        //更新時間                       
  11.                                
  12. //                                        LED_OF[TimeWei-1]=0xff;        //離開該位顯示,防止正好熄滅       
  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;        //讀取并顯示時間
  23.                                 case 1:        TimeWei=0;        break;        //10時               
  24.                                 case 2:        TimeWei=1;        break;        // 時               
  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();        //設置時間
  38.         }       
  39.                
  40. }
復制代碼



回復

使用道具 舉報

ID:1144680 發表于 2025-6-1 13:47 | 顯示全部樓層
  1. void TimeShow()
  2. {
  3.      DS1302_ReadTime();//讀取時間
  4.           LED_BCD[0] =DS1302_Time[0];                  //最高位,10時               
  5.           LED_BCD[1] =DS1302_Time[1];         

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

復制代碼


顯示時間代碼
回復

使用道具 舉報

ID:1144680 發表于 2025-6-1 13:49 | 顯示全部樓層
man1234567 發表于 2025-5-31 22:33
可能是防抖功能的設計問題

是有兩個延遲,不過是按鍵按下后才起作用。
回復

使用道具 舉報

ID:1144680 發表于 2025-6-1 13:50 | 顯示全部樓層
cy009 發表于 2025-5-31 23:38
時間有延時與while(1)無關,秒溢出,分+1延時,應該是你的1302讀寫函數有延時了。

有點頭暈,下面有代碼,能不能幫忙看看。。。
回復

使用道具 舉報

ID:1144680 發表于 2025-6-1 13:51 | 顯示全部樓層
188610329 發表于 2025-5-31 23:54
是你讀DS1302代碼的問題

一開始沒問題,后來加了按鍵檢測后出現的,不知道哪個環節出的。
回復

使用道具 舉報

ID:1152291 發表于 2025-6-1 16:53 | 顯示全部樓層
dcc60 發表于 2025-6-1 13:51
一開始沒問題,后來加了按鍵檢測后出現的,不知道哪個環節出的。

其實加了按鍵檢測是不太靈敏的,首先按鍵檢測是是基于一個模塊的,但是你如果添加了多個模塊的話,按鍵檢測到底是應用于誰了,所以基于按鍵檢測模塊的書寫,一般是只能需求一個模塊的,多個模塊添加進來,是會使軟件整混的,應用于仿真和實物都是不太靈敏的。
回復

使用道具 舉報

ID:1133081 發表于 2025-6-1 17:31 | 顯示全部樓層
dcc60 發表于 2025-6-1 13:51
一開始沒問題,后來加了按鍵檢測后出現的,不知道哪個環節出的。

TM1639讀到的鍵值是1個字節,并不是位信號0/1。沒有看到相關代碼,無法判斷與你所說的延遲1秒是否有關。
回復

使用道具 舉報

ID:1152365 發表于 2025-6-1 17:40 | 顯示全部樓層
肯定不是,while(1)只是大循環而已
回復

使用道具 舉報

ID:1144680 發表于 2025-6-1 18:15 | 顯示全部樓層
WL0123 發表于 2025-6-1 17:31
TM1639讀到的鍵值是1個字節,并不是位信號0/1。沒有看到相關代碼,無法判斷與你所說的延遲1秒是否有關。

估計是我搞錯了。
下次把按鍵改為單片機引腳。
回復

使用道具 舉報

ID:1144680 發表于 2025-6-1 18:17 | 顯示全部樓層
單片機重購 發表于 2025-6-1 16:53
其實加了按鍵檢測是不太靈敏的,首先按鍵檢測是是基于一個模塊的,但是你如果添加了多個模塊的話,按鍵檢 ...

太復雜了。
謝謝支持,再研究研究。
回復

使用道具 舉報

ID:883242 發表于 2025-6-2 18:48 | 顯示全部樓層
就是while按鍵那兩句卡住的。
回復

使用道具 舉報

ID:1144680 發表于 2025-6-3 10:27 | 顯示全部樓層
Hephaestus 發表于 2025-6-2 18:48
就是while按鍵那兩句卡住的。

下次刪了試試。
回復

使用道具 舉報

ID:1152291 發表于 2025-6-3 17:10 | 顯示全部樓層
有時候不用while(1)進行循環,用其它語言指令對單片機進行書寫也是可以使得單片機的程序可以運行起來
回復

使用道具 舉報

ID:1152595 發表于 2025-6-3 18:41 | 顯示全部樓層
這個函數本身沒有快慢的說法,主要看內部函數
回復

使用道具 舉報

ID:1152630 發表于 2025-6-3 22:48 來自觸屏版 | 顯示全部樓層
試一下移除按鍵檢測中的延時消抖,改為狀態機方式。
回復

使用道具 舉報

ID:65956 發表于 2025-6-4 08:32 | 顯示全部樓層
你可以不用while試試,因為用這個就是在死等,等超時了才重新來
回復

使用道具 舉報

ID:1144680 發表于 2025-6-4 10:58 | 顯示全部樓層
aking991 發表于 2025-6-4 08:32
你可以不用while試試,因為用這個就是在死等,等超時了才重新來

在計時器里試過,沒有延遲。
問題是以前也沒有延遲,按說,即便延遲,應該時分秒一起延遲才對。
回復

使用道具 舉報

ID:1144680 發表于 2025-6-4 11:51 | 顯示全部樓層
Hephaestus 發表于 2025-6-2 18:48
就是while按鍵那兩句卡住的。

試過了,不是按鍵問題。
回復

使用道具 舉報

ID:1144680 發表于 2025-6-4 11:53 | 顯示全部樓層
單片機重購 發表于 2025-6-3 17:10
有時候不用while(1)進行循環,用其它語言指令對單片機進行書寫也是可以使得單片機的程序可以運行起來

是的,放在定時器里就沒延遲。
回復

使用道具 舉報

ID:1144680 發表于 2025-6-4 11:55 | 顯示全部樓層
2631449463 發表于 2025-6-3 22:48
試一下移除按鍵檢測中的延時消抖,改為狀態機方式。

試了,可能還是其它問題。
回復

使用道具 舉報

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

使用道具 舉報

ID:1144680 發表于 2025-6-4 13:38 | 顯示全部樓層
jzh1 發表于 2025-6-4 12:06
在DS1302時鐘程序中,當`while(1)`循環內用兩個`if`檢測按鍵,且無按鍵時通過`switch/case`顯示時鐘,出現 ...

謝謝支持。說的很詳細。
經過反復試驗,發現循環之前的主函數運行時間太長(1-2秒左右),可能是造成不同步的主要原因。時分秒是直接讀取DS1302時間,不是按秒進位,理應“快、慢”同步才對,不知道為什么分鐘或小時會慢1秒。
回復

使用道具 舉報

ID:1146186 發表于 2025-6-9 09:11 | 顯示全部樓層
while(1) 本身不慢,但你在循環里做了按鍵檢測( if ) + 時鐘顯示( switch/case ),這倆操作會占用CPU時間。秒進位時,若CPU正忙按鍵檢測或顯示邏輯,沒及時讀取DS1302的最新時間,就會“延遲1秒”,本質是主循環被耗時任務阻塞,沒做到“實時響應時鐘更新”。
回復

使用道具 舉報

ID:1146186 發表于 2025-6-9 10:52 | 顯示全部樓層
while(1) 本身不慢,但你在循環里做了按鍵檢測( if ) + 時鐘顯示( switch/case ),這倆操作會占用CPU時間。秒進位時,若CPU正忙按鍵檢測或顯示邏輯,沒及時讀取DS1302的最新時間,就會“延遲1秒”,本質是主循環被耗時任務阻塞,沒做到“實時響應時鐘更新”
回復

使用道具 舉報

ID:1153440 發表于 2025-6-10 15:15 | 顯示全部樓層
與while(1)無關吧,更多與內部函數相關
回復

使用道具 舉報

ID:1144680 發表于 2025-6-10 21:26 | 顯示全部樓層
1763333333 發表于 2025-6-9 10:52
while(1) 本身不慢,但你在循環里做了按鍵檢測( if ) + 時鐘顯示( switch/case ),這倆操作會占用CPU時 ...

在while里只留timeshow也還是不同步,估計與主函數有關。
回復

使用道具 舉報

ID:1144680 發表于 2025-6-10 21:26 | 顯示全部樓層
gmlxh 發表于 2025-6-10 15:15
與while(1)無關吧,更多與內部函數相關

應該是的,現在放在定時器里就正常。
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 一级视频黄色 | 精品国产乱码久久久久久丨区2区 | 日韩中文字幕在线观看 | 久久久精品久久 | caoporn视频| 国产精品色婷婷久久58 | 国产羞羞视频在线观看 | 欧美日韩国产高清视频 | 99精品视频在线观看 | 在线一区二区三区 | 日本理论片好看理论片 | 99精品视频在线观看 | 欧美一级片在线观看 | 久久伦理中文字幕 | 日本精品久久久久久久 | 成人综合一区二区 | 亚洲精品一区二三区不卡 | 日韩免费中文字幕 | 九九福利 | 九九伦理电影 | 欧美日韩在线视频一区 | 国产精品成人一区二区 | 欧美日韩亚洲视频 | 国产精品1区2区3区 欧美 中文字幕 | 激情网站在线观看 | 久久久久91 | 国产精品久久久久久久久久三级 | 亚洲精品av在线 | 成人福利视频网站 | 在线播放国产一区二区三区 | 天天射天天操天天干 | 国产一区二区在线播放视频 | 亚洲视频一区在线播放 | 成人黄色在线观看 | 亚洲一区二区电影在线观看 | 国产一级免费在线观看 | 久久久综合网 | 久久99视频这里只有精品 | 91av视频在线观看 | 亚洲www| 7777精品伊人久久精品影视 |