日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

STM32CubeMX教程11 RTC 实时时钟 - 入侵检测和时间戳

發布時間:2024/1/11 windows 59 coder
生活随笔 收集整理的這篇文章主要介紹了 STM32CubeMX教程11 RTC 实时时钟 - 入侵检测和时间戳 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

使用STM32CubeMX軟件配置STM32F407開發板RTC實現入侵檢測和時間戳功能,具體為周期喚醒回調中使用串口輸出當前RTC時間,按鍵WK_UP存儲當前RTC時間到備份寄存器,按鍵KEY_2從備份寄存器中讀取上次存儲的時間,按鍵KEY_1負責產生入侵事件

1、準備材料

開發板(正點原子stm32f407探索者開發板V2.4)
ST-LINK/V2驅動
STM32CubeMX軟件(Version 6.10.0)
keil μVision5 IDE(MDK-Arm)
CH340G Windows系統驅動程序(CH341SER.EXE)
XCOM V2.6串口助手
杜邦線一根

2、實驗目標

使用STM32CubeMX軟件配置STM32F407開發板RTC實現入侵檢測和時間戳功能,具體為周期喚醒回調中使用串口輸出當前RTC時間,按鍵WK_UP存儲當前RTC時間到備份寄存器,按鍵KEY_2從備份寄存器中讀取上次存儲的時間,按鍵KEY_1負責產生入侵事件

3、實驗流程

3.0、前提知識

STM32F407的RTC上有兩個入侵檢測模塊,但是筆者使用的LQFP144封裝的STM32F407ZGT6只有一個入侵檢測模塊,只有一個入侵檢測模塊的STM32F407單片機是利用RTC_AF1(PC13)引腳來進行觸發的,和按鍵外部中斷類似,如果設置入侵檢測觸發為低電平觸發,那么當PC13為低電平時就會進入Tampere1事件回調函數,當發生入侵事件時,RTC的20個備份寄存器中的值會全部丟失

由于開發板上PC13引腳并沒有按鍵控制,不方便實現其電平的翻轉變化操作,因此本實驗需要一根杜邦線,將按鍵KEY_1所使用的PE3引腳與PC13引腳短接,相當于使用按鍵KEY_1來間接控制PC13的電平變化,如下圖所示,當按鍵KEY_1松開時,此時PE3/PC13狀態應該由外部上/下拉決定,而當按鍵KEY_1按下時,PE3/PC13的狀態應該為低電平,通過設置PC13外部上拉,就可以實現KEY_1按鍵松開時為高電平,按下為低電平

3.1、CubeMX相關配置

請閱讀“STM32CubeMX教程10 RTC 實時時鐘 - 周期喚醒、鬧鐘A/B事件和備份寄存器”實驗3.1.1小節配置RCC和SYS

3.1.1、時鐘樹配置

系統時鐘樹配置與上一實驗一致,均設置為STM32F407總線能達到的最高時鐘頻率,配置LSE,RTC時鐘頻率為32.768kHz,具體如下圖所示

3.1.2、外設參數配置

本實驗需要需要初始化USART1作為輸出信息渠道,具體配置步驟請閱讀“STM32CubeMX教程9 USART/UART 異步通信”

單擊Pinout & Configuration頁面左邊Timers/RTC,并在頁面中間激活日歷,周期喚醒WakeUp采用內部模式,勾選入侵檢測1將其輸入復用到引腳RTC_AF1(PC13),則此后PC13引腳便作為入侵檢測引腳,具體配置如下圖所示

與上一小節實驗類似,需要配置RTC通用參數、日歷日期時間、周期喚醒參數和入侵檢測參數

① 濾波設置中,如果不濾波則入侵檢測的觸發方式只能選擇邊沿觸發,而如果選擇濾波,則觸發方式只能選擇電平觸發,這里由于使用的機械按鍵存在抖動,因此對輸入濾波

② 入侵引腳是否上拉設置中,如上述3.0小節所述,我們需要PE3/PC13外部上拉才能實現目標,因此此處選擇上拉

③ 保存了入侵時間戳就可以在Tampere1事件回調函數中使用HAL_RTCEx_GetTimeStamp獲取入侵時間戳

④ 入侵檢測觸發方式設置中,由于按鍵按下為低電平,因此這里選擇低電平

3.1.3、外設中斷配置

在Pinout & Configuration頁面左邊System Core/NVIC中勾選入侵檢測及周期喚醒中斷,然后選擇合適的中斷優先級即可

3.2、生成代碼

請先閱讀“STM32CubeMX教程1 工程建立”實驗3.4.3小節配置Project Manager

單擊頁面右上角GENERATE CODE生成工程

3.2.1、外設初始化調用流程

與上一小節RTC初始化函數MX_RTC_Init對比,可以發現本小節的初始化函數中減少了鬧鐘A/B的初始化,但是新增加了入侵檢測的初始化,如下圖所示,也即我們在CubeMX中設置的參數,類似的中斷相關的初始化設置仍然在HAL_RTC_MspInit函數中

3.2.2、外設中斷調用流程

在CubeMX中勾選RTC入侵檢測啟動中斷后,在stm32f4xx_it.c中均會生成對應的中斷服務函數TAMP_STAMP_IRQHandler()

在該TAMP_STAMP_IRQHandler()中斷服務函數中調用了HAL庫HAL_RTCEx_TamperTimeStampIRQHandler()函數統一處理時間戳/入侵事件

最終根據發生的事件來源調用了時間戳事件回調函數HAL_RTCEx_TimeStampEventCallback()、入侵檢測1事件回調函數HAL_RTCEx_Tamper1EventCallback()和入侵檢測2事件HAL_RTCEx_Tamper2EventCallback()

具體流程如下圖所示

3.2.3、添加其他必要代碼

由于無入侵檢測2,筆者這里只實現了入侵檢測1事件回調函數HAL_RTCEx_Tamper1EventCallback(RTC_HandleTypeDef *hrtc),將其實現在了rtc.c中,另外周期喚醒回調函數內容與上一小結內容一致,這里不再贅述,入侵檢測1事件回調函數具體代碼如下圖所示

源代碼如下

/*Tampere1事件回調函數*/
void HAL_RTCEx_Tamper1EventCallback(RTC_HandleTypeDef *hrtc)
{
    RTC_TimeTypeDef sTime;
    RTC_DateTypeDef sDate;
    if(HAL_RTCEx_GetTimeStamp(hrtc, &sTime, &sDate, RTC_FORMAT_BIN) == HAL_OK)
    {
        char str[24];
        sprintf(str,"TimeStamp = %2d:%2d:%2d\r\n",sTime.Hours,sTime.Minutes,sTime.Seconds);
        printf("Tampere1 Event Happend, %s", str);
    }
    HAL_GPIO_TogglePin(GREEN_LED_GPIO_Port,GREEN_LED_Pin);
}

經過了上述的過程之后目前還缺少兩個操作,利用按鍵WK_UP存儲當前RTC時間到備份寄存器,按鍵KEY_2從備份寄存器中讀取上次存儲的時間,其代碼實現在了主函數主循環中,簡單采用輪詢的方式處理按鍵,如下圖所示

源代碼如下


/*按下WK_UP按鍵將當前時間存儲到備份寄存器*/
if(HAL_GPIO_ReadPin(WK_UP_GPIO_Port,WK_UP_Pin) == GPIO_PIN_SET)
{
    HAL_Delay(50);
    if(HAL_GPIO_ReadPin(WK_UP_GPIO_Port,WK_UP_Pin) == GPIO_PIN_SET)
    {
        RTC_TimeTypeDef sTime;
        RTC_DateTypeDef sDate;
        if(HAL_RTC_GetTime(&hrtc, &sTime,  RTC_FORMAT_BIN) == HAL_OK)
        {
            HAL_RTC_GetDate(&hrtc, &sDate,  RTC_FORMAT_BIN);
            HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR2, sTime.Hours);
            HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR3, sTime.Minutes);
            HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR4, sTime.Seconds);
            char timeStr[30];
            sprintf(timeStr,"%2d:%2d:%2d",sTime.Hours,sTime.Minutes,sTime.Seconds);
            printf("Store %s to the backup register\r\n", timeStr);
            while(HAL_GPIO_ReadPin(WK_UP_GPIO_Port,WK_UP_Pin));
        }
    }
}

/*按下KEY2按鍵將存儲到備份寄存器的時間利用串口輸出*/
if(HAL_GPIO_ReadPin(KEY_2_GPIO_Port,KEY_2_Pin) == GPIO_PIN_RESET)
{
    HAL_Delay(50);
    if(HAL_GPIO_ReadPin(KEY_2_GPIO_Port,KEY_2_Pin) == GPIO_PIN_RESET)
    {
        uint32_t  sHour,sMinute,sSecond;
        sHour = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR2);	//Hour
        sMinute = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR3);	//Minute
        sSecond = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR4);	//Second
        char timeStr[30];
        sprintf(timeStr,"%u:%u:%u",sHour,sMinute,sSecond);
        printf("Read out %s from the backup register\r\n", timeStr);
        while(!HAL_GPIO_ReadPin(KEY_2_GPIO_Port,KEY_2_Pin));
    }
}

4、常用函數

/*時間戳回調函數*/
void HAL_RTCEx_TimeStampEventCallback(RTC_HandleTypeDef *hrtc)
 
/*Tampere1事件回調函數*/
void HAL_RTCEx_Tamper1EventCallback(RTC_HandleTypeDef *hrtc)
 
/*Tampere2事件回調函數*/
void HAL_RTCEx_Tamper2EventCallback(RTC_HandleTypeDef *hrtc)
 
/*獲取RTC時間戳*/
HAL_StatusTypeDef HAL_RTCEx_GetTimeStamp(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTimeStamp, RTC_DateTypeDef *sTimeStampDate, uint32_t Format)

5、燒錄驗證

5.1、具體步驟

“RTC Mode and Configuration中啟用內部模式的WakeUp周期喚醒 -> 勾選入侵檢測Tamper1 Routed to AF1 -> 配置合適的日歷通用參數、日歷日期時間、周期喚醒參數和入侵檢測參數 -> NVIC中勾選RTC周期喚醒中斷及RTC入侵檢測中斷,并選擇合適的中斷優先級 -> 在生成的工程代碼中重新實現周期喚醒回調函數、Tampere1事件回調函數HAL_RTCEx_Tamper1EventCallback -> 添加必要的代碼邏輯(具體看上述3.2)”

5.2、實驗現象

燒錄程序,利用杜邦線短接PE3和PC13,當開發板上電后,會在周期喚醒回調函數中不斷地輸出當前RTC的時間,另外開發板上的紅色LED燈也會不斷地閃爍,當按下開發板上的WK_UP按鍵之后會將當前RTC日歷的時間存儲到備份寄存器RTC_BKP_DR2~4中,按下開發板上的KEY_2按鍵可以從備份寄存器中將上次存儲的時間讀出來

然后當按下按鍵KEY_1的時候,會發生入侵事件,此時入侵被檢測到,會觸發Tampere1事件回調函數通過串口輸出入侵事件的信息,并且如果再去通過KEY_2按鍵讀取備份寄存器中存儲的時間會發現由于入侵的發生,備份寄存器中的值已經被清空

上述整個流程串口輸出信息如下圖所示

6、奇怪的現象

有時候會出現寫備份寄存器寫不進去的情況,如果你也遇到了,可以嘗試將開發板完全斷電(電源線、USB串口和調試器接口),然后重新上電復位再向備份寄存器中寫入試試

參考資料

STM32Cube高效開發教程(基礎篇)

更多內容請瀏覽 OSnotes的CSDN博客

總結

以上是生活随笔為你收集整理的STM32CubeMX教程11 RTC 实时时钟 - 入侵检测和时间戳的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。