|
前言) o: A2 G5 {- G. ?# ] j3 D! W
直接看代碼) A5 X i7 A. @9 x. t
uint32_t Time_Interval(){ static uint32_t old_time_tick; uint32_t data; data = sys_time_tick_ms - old_time_tick; old_time_tick = sys_time_tick_ms; return data;}上述代碼,sys_time_tick_ms每隔1ms自動(dòng)加1,Time_Interval函數(shù)的作用是的,計(jì)算上一次調(diào)用Time_Interval和下一次調(diào)用的時(shí)間差,單位ms。
) E3 `. U/ R& W3 M, j+ d在這里存在一個(gè)風(fēng)險(xiǎn),就是sys_time_tick_ms到達(dá)最大值后會(huì)溢出,會(huì)變成0。所以之前的代碼我的習(xí)慣是先判斷一下sys_time_tick_ms和old_time_tick的大小關(guān)系。
0 H8 R4 j6 I* Y; r- kuint32_t Time_Interval(){ static uint32_t old_time_tick; uint32_t data; if(sys_time_tick_ms > old_time_tick) data = sys_time_tick_ms - old_time_tick; else data = sys_time_tick_ms + (0xFFFFFFFF - old_time_tick); old_time_tick = sys_time_tick_ms; return data;}然而一次和同事交流的時(shí)候,我意識(shí)到其實(shí)不用這么做的,sys_time_tick_ms直接減去old_time_tick就行。如下代碼# U7 ?9 J h. s1 z+ Q7 K: g) n
sys_time_tick_ms = 0xFFFFFFFF - 2; old_time_tick = sys_time_tick_ms; sys_time_tick_ms++; data = sys_time_tick_ms-old_time_tick; printf("sys_time_tick_ms:%x data:%d\r
8 `6 b, @) D0 ], u",sys_time_tick_ms,data); sys_time_tick_ms++; data = sys_time_tick_ms-old_time_tick; printf("sys_time_tick_ms:%x data:%d\r4 A. j( P- P; c2 A9 T5 `9 u! b
",sys_time_tick_ms,data); sys_time_tick_ms++; data = sys_time_tick_ms-old_time_tick; printf("sys_time_tick_ms:%x data:%d\r1 ]: g9 h" R; H9 ?1 Y6 I; O
",sys_time_tick_ms,data); sys_time_tick_ms++; data = sys_time_tick_ms-old_time_tick; printf("sys_time_tick_ms:%x data:%d\r) {$ H% `7 O: ~4 F
",sys_time_tick_ms,data); sys_time_tick_ms++; data = sys_time_tick_ms-old_time_tick; printf("sys_time_tick_ms:%x data:%d\r
0 S+ J1 F0 \5 t w9 Z3 }8 u",sys_time_tick_ms,data);具體打印如下
6 h) g6 Y- g1 C. b% i$ Y& zsys_time_tick_ms:fffffffe data:1sys_time_tick_ms:ffffffff data:2sys_time_tick_ms:0 data:3sys_time_tick_ms:1 data:4sys_time_tick_ms:2 data:5可以看出,這種情況下,即使sys_time_tick_ms溢出,也不影響正常功能的。
4 b; u. R* u5 t8 J' L. ]如果你很明白這個(gè)問題,大佬可以出門左轉(zhuǎn)了,這篇文章會(huì)浪費(fèi)你的時(shí)間的。; E# F0 v1 H6 G5 h
無符號(hào)減法的本質(zhì)
, y5 i$ ^# }, u$ W0 Z注意:本文只討論無符號(hào)的減法,有符號(hào)和其他數(shù)據(jù)類型本人沒有深究。' h! F, ]2 X$ g5 a# G+ d
在計(jì)算機(jī)中,無符號(hào)的減法運(yùn)算是通過補(bǔ)碼來進(jìn)行的,比如a-b,實(shí)質(zhì)上是a補(bǔ) + (-b補(bǔ))。補(bǔ)碼的定義不懂的同學(xué)請(qǐng)自行百度。uint32_t a,b,c;a=5;b=10;c=a-b;printf("c:%x\r
5 U5 S+ G& b% d, z r* U",c);打印如下
6 O4 b/ k+ @0 ^) g1 C Yc:fffffffb這個(gè)是我們上面結(jié)論的簡單例子,將這個(gè)減法手動(dòng)模擬一下,就方便理解了5的原碼: 00000000 | 00000000 | 00000000 | 0000010110的原碼:00000000 | 00000000 | 00000000 | 000010105的補(bǔ)碼: 00000000 | 00000000 | 00000000 | 00000101- b5 k+ m5 y* c( W' i
-10的補(bǔ)碼:11111111 | 11111111 | 11111111 | 111101108 ^3 L) Y% Q) d8 k2 h
(5)補(bǔ) + (-10)補(bǔ) = 00000000 00000000 00000000 00000101 + 11111111 11111111 11111111 11110110
1 J1 }0 D# N$ [結(jié)果就是fffffffb
8 r4 Y8 a) j$ Y6 W& K總結(jié)
# E# {1 Q6 g; Z發(fā)現(xiàn)這個(gè)合法的操作,能更加深入的了解無符號(hào)的加法操作。但是這種操作還是要慎重,我的測試環(huán)境是IAR7.2,建議大家使用時(shí)先測試一下,還是要謹(jǐn)慎的,別因?yàn)檫@個(gè)問題"捅了婁子"。) Y% B8 N) C6 s( n! M$ P
除了需要在開發(fā)環(huán)境中測試一下外,還需要額外的備注如下?uint32_t Time_Interval(){ static uint32_t old_time_tick; uint32_t data; data = sys_time_tick_ms - old_time_tick;//數(shù)據(jù)溢出后,由于無符號(hào)減法特性,也不會(huì)出問題 old_time_tick = sys_time_tick_ms; return data;}建議加上這樣的注釋,方便其他人維護(hù),代碼清晰易讀。就像switch語句,合并處理某些情況是,最好添加備注。switch (data){ case:0 case:1//0和1情況一樣,合并處理 /*do some thing*/ break; case:2 /*do some thing*/ break; default: break;}總結(jié)兩點(diǎn):1、測試對(duì)應(yīng)開發(fā)環(huán)境下是否有問題
?! X& E$ \) M! n# A2、養(yǎng)成良好習(xí)慣,寫清楚注釋8 H/ ]2 h2 V+ E0 X! k) q
END" C6 g3 C r M! J; x; C
yggnbcaubfy64014187858.gif (170.56 KB, 下載次數(shù): 0)
下載附件
保存到相冊(cè)
yggnbcaubfy64014187858.gif
2024-9-1 11:48 上傳
0 L$ i: |1 o! D$ U: F0 o7 x3 ^
4xo5pobjjag64014187958.gif (66.66 KB, 下載次數(shù): 1)
下載附件
保存到相冊(cè)
4xo5pobjjag64014187958.gif
2024-9-1 11:48 上傳
7 x( M5 i, k$ J. x/ H! Q" c M?如何查找官方資料 P+ W6 J0 S% D5 T& o
?VS code調(diào)試C代碼 必讀 a" j1 B- }8 Y0 a$ l$ z
?STM32中volatile的應(yīng)用
, t i. O& F9 r; t; U/ j?回調(diào)函數(shù)在STM32中的應(yīng)用 必讀* B( p1 V7 F6 J- @. U
?設(shè)計(jì)一款兼容ST207和GD207的開發(fā)板 |
|