不過,今天主要想聊聊如何通過RTC來實現(xiàn)該需求。了解STM32的RTC的人可能知道,RTC模塊往往還自帶一個專門的16位向下計數(shù)的喚醒定時器,即下面RTC局部框圖中紅框所在單元。我這里要分享的也不是這個專用喚醒定時器,而是想基于ALARM事件和亞秒特性來實現(xiàn)上面需求。
對于RTC的ALARM功能我們都不陌生,即先預(yù)設(shè)需要ALARM的時間點,當(dāng)日歷時間跟設(shè)定的ALARM時間匹配時就可以觸發(fā)ALARM事件及中斷。對于ALARM時間點的報警條件可以有很多靈活的組合配置,比方我們可以設(shè)置在某月某日某時某分某秒ALARM,也可以設(shè)置在某分某秒ALARM,其它不關(guān)心,或者僅設(shè)置在某個亞秒時刻ALARM,其它不關(guān)心。
上圖中四種ALARM設(shè)置,灰色部分表示不關(guān)心項,即不參與日歷值與ALARM設(shè)定值相關(guān)項的比較。這里分別表示的警情時刻是:
第一種,只要日歷中跟ALARM設(shè)置的時、分、秒匹配時報警,其它不關(guān)心;
第二種,只要日歷中跟ALARM設(shè)置的分值、秒值匹配時報警,其它不關(guān)心;
第三種,只要日歷中跟ALARM設(shè)置的秒值和亞秒低3位值匹配時報警,其它不關(guān)心;
第四種,只要日歷中跟ALARM設(shè)置的亞秒的低4位值匹配時報警,其它不關(guān)心;
我們回到前面提到的需求,每隔50±20ms做喚醒,即30ms~70ms范圍內(nèi)實現(xiàn)喚醒都可以接受。如果說使用ALARM中斷,相信很多人自然會想到,先設(shè)定一個ALARM點,等喚醒后再修改新的ALARM值,就這樣延續(xù)下去。
這樣操作也是可以的,即每次在ALARM中斷里修改新的ALARM時間點。下圖是對ALARM值進(jìn)行編程的流程【設(shè)置時先要關(guān)閉ALARM,修改ALARM值后再手動開啟ALARM單元】:
不過,結(jié)合眼前的應(yīng)用需求,我們可以不使用上面的做法,而是巧妙地使用RTC亞秒特性來實現(xiàn)周期性的ALARM以滿足需求。怎么個巧法呢?一起來看看。
先假定RTCCLK為32768Hz,RTC同步分頻系數(shù)和異步分頻系數(shù)分別為如下參數(shù):
PREDIV_A=127,PREDIV_S=255。
依據(jù)現(xiàn)有的分頻配置,則亞秒的時間精度或者說分辨率為(1/256)秒,3.9ms的樣子,即亞秒計數(shù)器每計1個脈沖所對應(yīng)的時間就是3.9ms,算4ms吧。【記住這個數(shù)據(jù)后面要用】
談到這里,我們跳躍一下思路,換個數(shù)學(xué)話題聊聊。【注:這個地方可能有點突兀。突兀的突悟往往離不開艱辛的修行。】
這里有從0開始按照從小到大排列的一批足夠多的自然數(shù)列,按10進(jìn)制展現(xiàn)。我們來看看幾種情形:
1、如果找出只要個位數(shù)相同的數(shù)據(jù),仍然按照從小到大排列,每相鄰兩個數(shù)的差值一定是10。對不對?
2、如果找出只要個位數(shù)與十位數(shù)都相同的數(shù)據(jù),仍然按照從小到大排列,每相鄰兩個數(shù)的差值一定是100。沒錯吧。
3、如果找出只要個位數(shù)與十位數(shù)以及百位數(shù)都相同的數(shù)據(jù) 仍然按照從小到大排列,每相鄰兩個數(shù)的差值一定是1000。結(jié)論也沒問題。
。。。。。。
到此,我們應(yīng)該發(fā)現(xiàn)規(guī)律了,通過關(guān)注低幾位數(shù)相同而重新有序排列而成的相鄰數(shù)據(jù)之差即為10的幾次方,其實這里相鄰數(shù)的差值也就是原自然數(shù)列中兩個數(shù)的位置間隔。【注意關(guān)鍵詞:位數(shù),數(shù)據(jù),相鄰】我們可以基于下圖的一批十進(jìn)制數(shù)據(jù)表格做些直觀的觀察。
好,我們不妨改變下數(shù)據(jù)的進(jìn)制看看。還是從0開始按照從小到大排列的一批足夠多的自然數(shù)列,按2進(jìn)制展現(xiàn)。依然看看幾種情形并得出相應(yīng)結(jié)論。
1、若找出只要低1位數(shù)相同的數(shù)據(jù),仍按照從小到大排列,每相鄰兩個數(shù)的差值一定是2;
2、若找出只要低2位數(shù)都相同的數(shù)據(jù),仍按照從小到大排列,每相鄰兩個數(shù)的差值一定是4;
3、若找出只要低3位數(shù)都相同的數(shù)據(jù) 仍按照從小到大排列,每相鄰兩個數(shù)的差值一定是8;
其它我們可以依次類推。
同樣,我們也發(fā)現(xiàn)規(guī)律,通過關(guān)注二進(jìn)制數(shù)的低幾位相同而重新有序排列而成的相鄰數(shù)據(jù)之差即為2的幾次方。我們可以基于下圖的一批二進(jìn)制數(shù)據(jù)表格做些直觀的觀察。【橙色代表低2位相同的數(shù)據(jù),綠色代表低3位相同的數(shù)據(jù),紅色代表低4位相同的數(shù)據(jù)】
上面專門聊了一段純數(shù)學(xué)話題,繼續(xù)回到我們的亞秒應(yīng)用問題。
我們知道,包括亞秒在內(nèi)的整個日歷數(shù)據(jù)實質(zhì)上是個具有高低順序和進(jìn)位關(guān)系的數(shù)據(jù),其中,亞秒是整個日歷數(shù)據(jù)里的最低端。當(dāng)我們設(shè)置ALARM參數(shù)時,如果說只關(guān)注亞秒的低1位,其它都不關(guān)心。基于前面的數(shù)學(xué)話題鋪墊可知,每當(dāng)出現(xiàn)低1位數(shù)據(jù)相同的兩個相鄰數(shù),總是相差2個計數(shù)單位,這里就是2個計數(shù)脈沖。換言之,每隔2個計數(shù)脈沖,結(jié)合前面分析,即每隔8ms都會觸發(fā)ALARM事件。
如果說只關(guān)注亞秒的低2位,其它都不關(guān)心,那么每當(dāng)出現(xiàn)低2位數(shù)據(jù)相同的相鄰數(shù),總是相差4個計數(shù)單位,即4個計數(shù)脈沖。換言之,每隔4個計數(shù)脈沖,即16ms都會觸發(fā)ALARM事件。
如果只關(guān)注亞秒的低3位,其它參數(shù)都不關(guān)心,每當(dāng)出現(xiàn)低3位數(shù)據(jù)相同的相鄰數(shù),總是相差8個計數(shù)單位,即8個計數(shù)脈沖,每隔32ms都會觸發(fā)ALARM事件。
其它依此類推。
談到這里,設(shè)置的只關(guān)心亞秒的位數(shù)跟ALARM周期的關(guān)系應(yīng)該說很清晰了。我在下面簡單羅列了基于前面條件下亞秒的關(guān)心位數(shù)與ALARM周期的對應(yīng)表:【灰色表示不關(guān)心,不參與日歷值與ALARM設(shè)定值的比較,只有綠色位參與比較】
現(xiàn)在期望的喚醒周期是50±20ms,我們配置亞秒計數(shù)器的低3位或者低4位作為ALARM的比較位【說關(guān)心位、參與位什么的都可以】,其它設(shè)置為不關(guān)心就可以滿足要求。我們不妨選擇亞秒計數(shù)值的低4位參與比較,即每兩次相鄰ALARM相差16個計數(shù)脈沖,周期約為64ms。
下面是我使用CubeMx進(jìn)行的日歷和ALARM A的配置,重點看下ALARM配置。
這里的ALARM配置只選擇亞秒的低4位參與比較,既然這樣其它參數(shù)就無所謂了。其中那個用于比較的亞秒值我這里寫的12,這個值寫多少并不影響ALARM周期的擬定,只會影響每次發(fā)生ALARM事件時的亞秒計數(shù)器的低4位的值。其實,當(dāng)我們選定只關(guān)心亞秒計數(shù)器的低4位時,重復(fù)ALARM的周期就已經(jīng)定了。
完成配置、建立工程、組織測試代碼。
我在ALARM中斷里讀取每次發(fā)生ALARM事件時的亞秒值。我截取幾個連續(xù)ALARM事件的相關(guān)信息在如下幾幅圖。其中變量Sub_Value和stime1.SubSeconds是一個東西,表示發(fā)生ALARM事件時亞秒計數(shù)器的值。比如下面各截圖中的236、220、204、188、172、156幾個數(shù),顯然兩相鄰數(shù)的間隔保持準(zhǔn)確的16個計數(shù)脈沖,若把這幾個數(shù)轉(zhuǎn)成2進(jìn)制,他們的低4位都是1100B,即我在前面ALARM設(shè)置的亞秒比較值12。
若在每次的ALARM中斷里把發(fā)生ALARM的時間點實時打印出來,可以清晰地看到相鄰兩次ALARM事件的時間間隔固定在63ms左右,這個值跟前面規(guī)劃的基本一致。
有人或許會問,相鄰ALARM事件的時間差為什么沒有計數(shù)脈沖數(shù)差值那樣穩(wěn)定精準(zhǔn)。我認(rèn)為主要有兩點原因,一是我測試時并沒有使用標(biāo)準(zhǔn)的32768外部時鐘,而是選擇的內(nèi)部LSI,它的頻率一般在31Khz到33KHz之間,不像LSE那么精準(zhǔn)。還有一個原因,在做亞秒時間計算時,因為無法整除原因肯定會帶來計算偏差。
利用上面方法可以省去每次修改ALARM配置的操作,類似這種具有周期性且周期不大于1秒的應(yīng)用都可以嘗試考慮上述方法,必要的時候可以考慮調(diào)整同步分頻系數(shù)即亞秒計數(shù)器的重裝值以滿足具體的時間精度要求。當(dāng)然,調(diào)整同步分頻系數(shù)的同時往往要調(diào)整異步分頻系數(shù),原則上異步分頻系數(shù)要盡量大以充分降低RTC模塊帶來的功耗,具體應(yīng)用時我們可以綜合考慮后再做調(diào)整。
-
STM32
+關(guān)注
關(guān)注
2270文章
10895瀏覽量
355747 -
RTC
+關(guān)注
關(guān)注
2文章
538瀏覽量
66468
發(fā)布評論請先 登錄
相關(guān)推薦
評論