|
前言& e! p1 K' b/ S& e4 s) c4 N
直接看代碼2 r# C! F1 _8 O! g
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。
4 z3 @6 e+ }! B. z/ L* u7 O4 _: S在這里存在一個(gè)風(fēng)險(xiǎn),就是sys_time_tick_ms到達(dá)最大值后會(huì)溢出,會(huì)變成0。所以之前的代碼我的習(xí)慣是先判斷一下sys_time_tick_ms和old_time_tick的大小關(guān)系。1 S, m P1 S! r; e1 Q* p: M
uint32_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 q/ b( P8 o
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\r7 X7 R# h R; B- K
",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" ~, v: ]6 b/ s/ K7 V
",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# n" ?. R0 Z" d) L4 v
",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* b. e8 F9 G, @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, [ t/ I/ a2 Z5 r, X, U/ D1 \
",sys_time_tick_ms,data);具體打印如下 i/ |; I* v3 D' U5 X
sys_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溢出,也不影響正常功能的。
2 V& A( O4 S1 a如果你很明白這個(gè)問題,大佬可以出門左轉(zhuǎn)了,這篇文章會(huì)浪費(fèi)你的時(shí)間的。) M, [, @8 T; l) I9 [
無符號(hào)減法的本質(zhì), G. ]% i8 O' f+ z: I) s s' b9 w4 e+ ?
注意:本文只討論無符號(hào)的減法,有符號(hào)和其他數(shù)據(jù)類型本人沒有深究。8 J6 d% t, e/ f$ R: N
在計(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
6 }; i* {! o. Z2 J9 g3 v8 I% `",c);打印如下
: }* e* [- B; ^$ S$ O8 dc:fffffffb這個(gè)是我們上面結(jié)論的簡單例子,將這個(gè)減法手動(dòng)模擬一下,就方便理解了5的原碼: 00000000 | 00000000 | 00000000 | 0000010110的原碼:00000000 | 00000000 | 00000000 | 000010105的補(bǔ)碼: 00000000 | 00000000 | 00000000 | 00000101! |; B! [- E3 U5 r% x0 i. ^
-10的補(bǔ)碼:11111111 | 11111111 | 11111111 | 111101109 i% Z4 `! s6 y
(5)補(bǔ) + (-10)補(bǔ) = 00000000 00000000 00000000 00000101 + 11111111 11111111 11111111 11110110& D2 X' d4 Q, e! W* j
結(jié)果就是fffffffb
0 f# y, U2 K2 x8 j( `5 ~總結(jié)
; S( \1 G2 S* f! v; |發(fā)現(xiàn)這個(gè)合法的操作,能更加深入的了解無符號(hào)的加法操作。但是這種操作還是要慎重,我的測試環(huán)境是IAR7.2,建議大家使用時(shí)先測試一下,還是要謹(jǐn)慎的,別因?yàn)檫@個(gè)問題"捅了婁子"。6 H8 ?% {" D! n: d5 @8 L
除了需要在開發(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)境下是否有問題
4 F0 x0 s2 \8 m+ f( P8 m* n5 `& R! ~2、養(yǎng)成良好習(xí)慣,寫清楚注釋
/ i& Q' W( c" e. D6 XEND
; ^* X1 z5 Z4 @ W- k' W1 W
yggnbcaubfy64014187858.gif (170.56 KB, 下載次數(shù): 0)
下載附件
保存到相冊(cè)
yggnbcaubfy64014187858.gif
2024-9-1 11:48 上傳
' u0 ~2 r( ^) o& t" h
4xo5pobjjag64014187958.gif (66.66 KB, 下載次數(shù): 1)
下載附件
保存到相冊(cè)
4xo5pobjjag64014187958.gif
2024-9-1 11:48 上傳
. r3 } C/ a& D* D# \
?如何查找官方資料
n- ?* k1 }( @6 i$ p4 M?VS code調(diào)試C代碼 必讀$ k( Y& a( z$ F) W6 E& H
?STM32中volatile的應(yīng)用
* p0 ?- p$ u4 ^' X# G' r7 Q?回調(diào)函數(shù)在STM32中的應(yīng)用 必讀$ W2 h4 J" @2 h* k6 ~1 ]) {9 ~
?設(shè)計(jì)一款兼容ST207和GD207的開發(fā)板 |
|