在貨物監控裝置研發中,如何對微控制器進行實時時鐘配置?

近期,筆者在進行貨物監控裝置的研發。貨物監控裝置是基於無線感測技術以及最新的定位技術等研發的。可以對運輸中的貨物進行實時監控,管理者可以在雲端後臺實時視覺化的觀看到貨物運輸的軌跡。

在貨物監控裝置研發中,如何對微控制器進行實時時鐘配置?

貨物監控裝置中的無線感測裝置可以監測到貨物箱內的溫溼度情況,以及光感度。一旦貨物在沒有被允許的情況下開啟貨箱,感測器監測到光感的異常變化會立即啟動報警系統,保證貨物的安全。

在貨物監控裝置的研發過程中,筆者會根據產品效能的需要對STM32的RTC進行相應配置。RTC是獨立的定時器。

在貨物監控裝置研發中,如何對微控制器進行實時時鐘配置?

RTC在相應軟體配置下,可提供時鐘日曆的功能。對RTC計數器進行修改,可以重新設定產品的系統時間。相信很多產品研發的小夥伴都會用到RCT的設定,那麼具體如何操作呢?

STM32 RTC原理‍

RTC的核心部分是由一組可以程式設計的計數器組成的。這個計數器分為兩個模組。第一個模組是實時時鐘的預分頻模組,它可以程式設計產生出最長時間為1秒的實時時鐘時間基TR_CLK。實時時鐘的預分頻模組中包括一個20位的RTC預分頻器。

在貨物監控裝置研發中,如何對微控制器進行實時時鐘配置?

如果使用者在RTC_CR暫存器中設定了相對應的允許位。那麼每一個TR_CLK週期中實時時鐘都會產生一個秒中斷;RTC的第二個模組是一個32位的可程式設計計數器,這個計數器可以被初始化為當前的系統時間。這個系統時間會按照TR_CLK週期進行累加,並與儲存在RTC_ALR暫存器的可程式設計時間進行比較。

在貨物監控裝置研發中,如何對微控制器進行實時時鐘配置?

如果RTC_CR控制暫存器中已經設定了相對應的允許位,在比較匹配時,將會產生的一個鬧鐘的中斷。

STM32 RTC原理和配置

在貨物監控裝置研發中,如何對微控制器進行實時時鐘配置?

RTC的配置過程如下:

(1)查詢RTOFF位,直到RTOFF的值變為』1』

(2)置CNF值為1,進入配置模式

(3)對一個或多個RTC暫存器進行寫操作

(4)清除CNF標誌位,退出配置模式

(5)查詢RTOFF,直至RTOFF位變為』1』以確認寫操作已經完成。

僅當CNF標誌位被清除時,寫操作才能進行,這個過程至少需要3個RTCCLK週期

在貨物監控裝置研發中,如何對微控制器進行實時時鐘配置?

例項配置過程:

配置:RTC使用內部LSI時鐘,使能鬧鐘中斷,設定本地時間為2021-03-30 01:34:30

void RTCInit(void)

{

NVIC_InitTypeDef NVIC_InitStruct;

EXTI_InitTypeDef EXTI_InitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR|RCC_APB1Periph_BKP,ENABLE);

PWR_BackupAccessCmd(ENABLE);

RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);

RCC_RTCCLKCmd(ENABLE);

//RCT Config

RTC_WaitForLastTask();

RTC_WaitForSynchro();

RTC_ITConfig(RTC_IT_ALR,ENABLE);

RTC_WaitForLastTask();

RTC_WaitForSynchro();

RTC_ClearITPendingBit(RTC_IT_ALR);

RTC_WaitForLastTask();

RTC_EnterConfigMode();

RTC_SetPrescaler(40*1000-1);

RTC_WaitForLastTask();

RTC_Set(2021,3,30,1,34,40); //設定時間

RTC_WaitForLastTask();

RTC_SetAlarm(RTC_GetCounter()+1);

RTC_WaitForLastTask();

RTC_ExitConfigMode();

EXTI_InitStructure.EXTI_Line = EXTI_Line17;

EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;

EXTI_InitStructure.EXTI_LineCmd = ENABLE;

EXTI_Init(&EXTI_InitStructure);

NVIC_InitStruct.NVIC_IRQChannel = RTCAlarm_IRQn;

NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;

NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 6;

NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;

NVIC_Init(&NVIC_InitStruct);

RTC_ClearITPendingBit(RTC_IT_ALR|RTC_IT_SEC);

EXTI_ClearITPendingBit(EXTI_Line17);

}