久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1344|回復: 0
打印 上一主題 下一主題
收起左側

STM32單片機RTC時鐘程序 帶中文注釋

[復制鏈接]
跳轉到指定樓層
樓主
ID:1053560 發表于 2024-2-28 11:47 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
STM32 RTC時鐘帶中文注釋
#include "stm32f10x.h"                  // Device header
#include <time.h>

uint16_t MyRTC_Time[] = {2024, 2, 26, 15, 18, 00};        //定義全局的時間數組,數組內容分別為年、月、日、時、分、秒

void MyRTC_SetTime(void);                                //函數聲明

/**
  * 函    數:RTC初始化
  * 參    數:無
  * 返 回 值:無
  */
void MyRTC_Init(void)
{
        /*開啟時鐘*/
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);                //開啟PWR的時鐘
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP, ENABLE);                //開啟BKP的時鐘
        
        /*備份寄存器訪問使能*/
        PWR_BackupAccessCmd(ENABLE);                                                        //使用PWR開啟對備份寄存器的訪問
        
        if (BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5)                        //通過寫入備份寄存器的標志位,判斷RTC是否是第一次配置
                                                                                                                        //if成立則執行第一次的RTC配置
        {
                RCC_LSEConfig(RCC_LSE_ON);                                                        //開啟LSE時鐘
                while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) != SET);        //等待LSE準備就緒
               
                RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);                                //選擇RTCCLK來源為LSE
                RCC_RTCCLKCmd(ENABLE);                                                                //RTCCLK使能
               
                RTC_WaitForSynchro();                                                                //等待同步
                RTC_WaitForLastTask();                                                                //等待上一次操作完成
               
                RTC_SetPrescaler(32768 - 1);                                                //設置RTC預分頻器,預分頻后的計數頻率為1Hz
                RTC_WaitForLastTask();                                                                //等待上一次操作完成
               
                MyRTC_SetTime();                                                                        //設置時間,調用此函數,全局數組里時間值刷新到RTC硬件電路
               
                BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);                        //在備份寄存器寫入自己規定的標志位,用于判斷RTC是不是第一次執行配置
        }
        else                                                                                                        //RTC不是第一次配置
        {
                RTC_WaitForSynchro();                                                                //等待同步
                RTC_WaitForLastTask();                                                                //等待上一次操作完成
        }
}

//如果LSE無法起振導致程序卡死在初始化函數中
//可將初始化函數替換為下述代碼,使用LSI當作RTCCLK
//LSI無法由備用電源供電,故主電源掉電時,RTC走時會暫停
/*
void MyRTC_Init(void)
{
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP, ENABLE);
        
        PWR_BackupAccessCmd(ENABLE);
        
        if (BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5)
        {
                RCC_LSICmd(ENABLE);
                while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) != SET);
               
                RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
                RCC_RTCCLKCmd(ENABLE);
               
                RTC_WaitForSynchro();
                RTC_WaitForLastTask();
               
                RTC_SetPrescaler(40000 - 1);
                RTC_WaitForLastTask();
               
                MyRTC_SetTime();
               
                BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);
        }
        else
        {
                RCC_LSICmd(ENABLE);                                //即使不是第一次配置,也需要再次開啟LSI時鐘
                while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) != SET);
               
                RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
                RCC_RTCCLKCmd(ENABLE);
               
                RTC_WaitForSynchro();
                RTC_WaitForLastTask();
        }
}*/

/**
  * 函    數:RTC設置時間
  * 參    數:無
  * 返 回 值:無
  * 說    明:調用此函數后,全局數組里時間值將刷新到RTC硬件電路
  */
void MyRTC_SetTime(void)
{
        time_t time_cnt;                //定義秒計數器數據類型
        struct tm time_date;        //定義日期時間數據類型
        
        time_date.tm_year = MyRTC_Time[0] - 1900;                //將數組的時間賦值給日期時間結構體
        time_date.tm_mon = MyRTC_Time[1] - 1;
        time_date.tm_mday = MyRTC_Time[2];
        time_date.tm_hour = MyRTC_Time[3];
        time_date.tm_min = MyRTC_Time[4];
        time_date.tm_sec = MyRTC_Time[5];
        
        time_cnt = mktime(&time_date) - 8 * 60 * 60;        //調用mktime函數,將日期時間轉換為秒計數器格式
                                                                                                        //- 8 * 60 * 60為東八區的時區調整
        
        RTC_SetCounter(time_cnt);                                                //將秒計數器寫入到RTC的CNT中
        RTC_WaitForLastTask();                                                        //等待上一次操作完成
}

/**
  * 函    數:RTC讀取時間
  * 參    數:無
  * 返 回 值:無
  * 說    明:調用此函數后,RTC硬件電路里時間值將刷新到全局數組
  */
void MyRTC_ReadTime(void)
{
        time_t time_cnt;                //定義秒計數器數據類型
        struct tm time_date;        //定義日期時間數據類型
        
        time_cnt = RTC_GetCounter() + 8 * 60 * 60;                //讀取RTC的CNT,獲取當前的秒計數器
                                                                                                        //+ 8 * 60 * 60為東八區的時區調整
        
        time_date = *localtime(&time_cnt);                                //使用localtime函數,將秒計數器轉換為日期時間格式
        
        MyRTC_Time[0] = time_date.tm_year + 1900;                //將日期時間結構體賦值給數組的時間
        MyRTC_Time[1] = time_date.tm_mon + 1;
        MyRTC_Time[2] = time_date.tm_mday;
        MyRTC_Time[3] = time_date.tm_hour;
        MyRTC_Time[4] = time_date.tm_min;
        MyRTC_Time[5] = time_date.tm_sec;
}



#include "MyRTC.h"

int main(void)
{
        /*模塊初始化*/
        OLED_Init();                //OLED初始化
        MyRTC_Init();                //RTC初始化
//        MyRTC_SetTime();//設置時間
        /*顯示靜態字符串*/
        OLED_ShowString(1, 1, "Date:XXXX-XX-XX");
        OLED_ShowString(2, 1, "Time:XX:XX:XX");
        OLED_ShowString(3, 1, "CNT :");
        OLED_ShowString(4, 1, "DIV :");
        
        while (1)
        {
                MyRTC_ReadTime();                                                        //RTC讀取時間,最新的時間存儲到MyRTC_Time數組中
               
                OLED_ShowNum(1, 6, MyRTC_Time[0], 4);                //顯示MyRTC_Time數組中的時間值,年
                OLED_ShowNum(1, 11, MyRTC_Time[1], 2);                //月
                OLED_ShowNum(1, 14, MyRTC_Time[2], 2);                //日
                OLED_ShowNum(2, 6, MyRTC_Time[3], 2);                //時
                OLED_ShowNum(2, 9, MyRTC_Time[4], 2);                //分
                OLED_ShowNum(2, 12, MyRTC_Time[5], 2);                //秒
               
                OLED_ShowNum(3, 6, RTC_GetCounter(), 10);        //顯示32位的秒計數器
                OLED_ShowNum(4, 6, RTC_GetDivider(), 10);        //顯示余數寄存器
        }
}

原理圖: 無
仿真: 無
代碼: 12-2 實時時鐘.7z (179.82 KB, 下載次數: 23)

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 日韩欧美不卡 | 国产精久久久久久久妇剪断 | 久久久成人免费视频 | 久久久久久久久淑女av国产精品 | 欧美黄色片 | 日韩1区| 黑人巨大精品欧美黑白配亚洲 | 99精品视频一区二区三区 | 亚洲视频免费在线观看 | 欧美激情精品久久久久久变态 | 欧美日韩亚洲一区 | 久久香蕉精品视频 | 亚洲国产精品一区二区三区 | 91青青草视频 | 国产乱码精品一区二区三区中文 | 日本一区二区高清不卡 | 久久久久国产 | 免费看a | 狠狠色综合网站久久久久久久 | 古典武侠第一页久久777 | 国产精品久久9 | 亚洲情综合五月天 | 欧美区日韩区 | 国产1区2区 | 欧美aaaaaaaa| 免费精品 | 亚洲影音 | 日韩高清在线 | 国产成人精品一区二区三区四区 | 人人性人人性碰国产 | 亚洲午夜视频在线观看 | 男女午夜激情视频 | 国内精品视频免费观看 | 中文字幕在线观看视频一区 | 黄色片a级| 中文字幕亚洲欧美日韩在线不卡 | 欧美激情国产日韩精品一区18 | 日韩一级电影免费观看 | 国产成人精品免高潮在线观看 | 一区二区三区四区不卡 | 日本人爽p大片免费看 |