下面的程序根據(jù)固件庫(kù)進(jìn)行修改蚊夫,變成自己想要的程序,包含RTC秒中斷以及鬧鐘中斷懦尝,由于嵌入式競(jìng)賽板沒有外加晶振知纷,所以使用內(nèi)部低速時(shí)鐘LSI
下面的程序不能進(jìn)行年月計(jì)時(shí),只能在一天之內(nèi)進(jìn)行計(jì)時(shí)陵霉,如果要進(jìn)行長(zhǎng)時(shí)間計(jì)時(shí)琅轧,那么就得考慮閏年,還要考慮一月是31,30還是29或28天踊挠。應(yīng)對(duì)比賽來說就夠了
(2018/1/22加)今天添加一點(diǎn)小竅門乍桂,利用數(shù)組對(duì)時(shí)間的時(shí)、分、秒進(jìn)行
存儲(chǔ)睹酌,這樣就不用定義三個(gè)變量了权谁,鬧鐘時(shí)間使用相同的方式比較好,這樣寫程序會(huì)更快;
配置步驟(原子教程)
1) 使能電源時(shí)鐘和備份區(qū)域時(shí)鐘憋沿。
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);//PWR是電池時(shí)鐘
2) 取消備份區(qū)寫保護(hù)旺芽。//原子點(diǎn)的視頻有斷電恢復(fù)斷電時(shí)間的功能
PWR_BackupAccessCmd(ENABLE); //使能 RTC 和后備寄存器訪問
3) 復(fù)位備份區(qū)域,開啟外部低速振蕩器辐啄。
BKP_DeInit();//復(fù)位備份區(qū)域
RCC_LSEConfig(RCC_LSE_ON);// 開啟外部低速振蕩器
4) 選擇 RTC 時(shí)鐘采章,并使能。
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); //選擇 LSE 作為 RTC 時(shí)鐘,
RCC_RTCCLKSource_LSI//選擇的是低速時(shí)鐘
RCC_RTCCLKSource_HSE_Div128// HSE 的 128 分頻
5) 設(shè)置 RTC 的分頻则披,以及配置 RTC 時(shí)鐘共缕。
在進(jìn)行 RTC 配置之前首先要打開允許配置位(CNF)洗出,庫(kù)函數(shù)是:
RTC_EnterConfigMode();/// 允許配置
在配置完成之后士复,千萬別忘記更新配置同時(shí)退出配置模式,函數(shù)是:
RTC_ExitConfigMode();//退出配置模式翩活, 更新配置
設(shè)置 RTC 時(shí)鐘分頻數(shù)阱洪, 庫(kù)函數(shù)是:
void RTC_SetPrescaler(uint32_t PrescalerValue);
這個(gè)函數(shù)只有一個(gè)入口參數(shù),就是 RTC 時(shí)鐘的分頻數(shù)菠镇,很好理解冗荸。
然后是設(shè)置秒中斷允許, RTC 使能中斷的函數(shù)是:
void RTC_ITConfig(uint16_t RTC_IT, FunctionalState NewState)利耍;
這個(gè)函數(shù)的第一個(gè)參數(shù)是設(shè)置秒中斷類型蚌本,這些通過宏定義定義的。 對(duì)于使能秒中斷方法是:
RTC_ITConfig(RTC_IT_SEC, ENABLE); //使能 RTC 秒中斷
6) 更新配置隘梨,設(shè)置 RTC 中斷分組程癌。
在設(shè)置完時(shí)鐘之后,我們將配置更新同時(shí)退出配置模式轴猎,這里還是通過 RTC_CRH 的 CNF
來實(shí)現(xiàn)嵌莉。 庫(kù)函數(shù)的方法是:
RTC_ExitConfigMode();//退出配置模式,更新配置
void BKP_WriteBackupRegister(uint16_t BKP_DR, uint16_t Data)捻脖;//寫入后備寄存器
7) 編寫中斷服務(wù)函數(shù)
void RTC_IRQHandler(void)
{
if (RTC_GetITStatus(RTC_IT_SEC) != RESET)//秒中斷
{
RTC_ClearITPendingBit(RTC_IT_SEC);//清除中斷標(biāo)志位
}
if(RTC_GetITStatus(RTC_IT_ALR)!=RESET)//鬧鐘中斷
{
RTC_ClearITPendingBit(RTC_IT_ALR);
AlarmFlag = 1;
}
}
第六屆省賽代碼“電壓測(cè)量監(jiān)控設(shè)備”
#include "include.h"
#include "rtc.h"
#include "lcd.h"
#define HH 23 //時(shí)
#define MM 59 //分
#define SS 55 //秒
u32 THH = 0, TMM = 0, TSS = 0;
_Bool TimeDisplay = 0;
_Bool AlarmFlag = 0;//鬧鐘中斷
/**
* @說明 配置RTC
* @參數(shù) None
* @返回值 None
*/
void RTC_Configuration(void)
{
/* Enable PWR and BKP clocks */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
PWR_BackupAccessCmd(ENABLE);
BKP_DeInit();
RCC_LSICmd(ENABLE);
/* Wait till LSE is ready */
while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET);
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
RCC_RTCCLKCmd(ENABLE);
RTC_WaitForSynchro();
RTC_WaitForLastTask();
/* Enable the RTC Second */
RTC_ITConfig(RTC_IT_SEC, ENABLE); //秒中斷
RTC_WaitForLastTask();
RTC_ITConfig(RTC_IT_ALR, ENABLE); //鬧鐘中斷
RTC_WaitForLastTask();
/* Set RTC prescaler: set RTC period to 1sec */
RTC_SetPrescaler(39999); /* RTC period = RTCCLK/RTC_PR = (40 KHz)/(39999+1) */
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
RTC_SetCounter(HH*3600+MM*60+SS);//設(shè)置初始時(shí)間
RTC_WaitForLastTask();
RTC_SetAlarm(0); //設(shè)置鬧鐘時(shí)間
RTC_WaitForLastTask();
NVIC_Configuration();//中斷優(yōu)先級(jí)
}
/**
* @說明 顯示當(dāng)前時(shí)間
* @參數(shù) TimeVar:RTC Counter值
* @返回值 None
*/
uint8_t text[20];
void Time_Display(u32 TimeVar)
{
/* 23:59:59 */
if (RTC_GetCounter() == 23*3600+59*60+59)
{
RTC_SetCounter(0x0);
RTC_WaitForLastTask();
}
/* Compute hours */
THH = TimeVar / 3600;
/* Compute minutes */
TMM = (TimeVar % 3600) / 60;
/* Compute seconds */
TSS = (TimeVar % 3600) % 60;
sprintf(text," T: %0.2d:%0.2d:%0.2d",THH, TMM, TSS);
LCD_DisplayStringLine(Line5,text);
}
/**
* @說明 配置中斷向量控制器
* @參數(shù) None
* @返回值 None
*/
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
// NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
/* Enable the RTC Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void RTC_IRQHandler(void)
{
if (RTC_GetITStatus(RTC_IT_SEC) != RESET)//秒中斷
{
RTC_ClearITPendingBit(RTC_IT_SEC);
TimeDisplay = 1; //時(shí)間更新標(biāo)志置位
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
}
if(RTC_GetITStatus(RTC_IT_ALR)!=RESET)//鬧鐘中斷發(fā)生
{
RTC_ClearITPendingBit(RTC_IT_ALR);
AlarmFlag = 1;//送出標(biāo)志位
}
}