欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136
標題:
RTC實時時鐘驅動函數固件庫版和寄存器版對比
[打印本頁]
作者:
liuyy
時間:
2015-1-12 15:17
標題:
RTC實時時鐘驅動函數固件庫版和寄存器版對比
前天,有個朋友問:如果電腦突然掉電導致一些重要數據丟失怎么辦?我覺得對于STM32而言無需外掛E2PROM,憑借自身資源就可以解決:1,大容量STM32一般有512k的flash,可以在程序運行當中實時將重要數據更新到片內flash中;具體如何操作可以參考IAP例程,這個例程很好,不光可以學習IAP(在應用編程功能),還可以學到CM3內核的一些結構知識和對片內flash的操作;2,STM32的備份域(BKP)有42個u16類型數據寄存器,只要按流程操作這42個16位的備份域數據寄存器就可以當E2PROM用,當然必須配有電池。通過對備份域的操作還可以做一個鬧鐘。
STM32的資源很豐富對應每個功能,STM32的軟件工程師為其搭配了相應的庫函數。有了這個固件庫使得我們對STM32的應用程序開發更加簡單,節省開發時間。但是我感覺要熟練運用庫函數也不是一件容易的事,必須經常練習。
下面是RTC實時時鐘固件庫版驅動函數(原子例程):
//實時時鐘配置
//初始化RTC時鐘,同時檢測時鐘是否工作正常
//BKP->DR1用于保存是否第一次配置的設置
//返回0:正常
//其他:錯誤代碼
u8 RTC_Init(void)
{
//檢查是不是第一次配置時鐘
u8 temp=0;
if (BKP_ReadBackupRegister(BKP_DR1) != 0x5050)//從指定的后備寄存器中讀出數據:讀出了與寫入的指定數據不相乎
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);//使能PWR和BKP外設時鐘
PWR_BackupAccessCmd(ENABLE);//使能后備寄存器訪問
BKP_DeInit();//復位備份區域
RCC_LSEConfig(RCC_LSE_ON);//設置外部低速晶振(LSE),使用外設低速晶振
while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)//檢查指定的RCC標志位設置與否,等待低速晶振就緒
{
temp++;
delay_ms(10);
}
if(temp>=250)return 1;//初始化時鐘失敗,晶振有問題
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);//設置RTC時鐘(RTCCLK),選擇LSE作為RTC時鐘
RCC_RTCCLKCmd(ENABLE);//使能RTC時鐘
RTC_WaitForLastTask();//等待最近一次對RTC寄存器的寫操作完成
RTC_WaitForSynchro();//等待RTC寄存器同步
RTC_ITConfig(RTC_IT_SEC, ENABLE);//使能RTC秒中斷
RTC_WaitForLastTask();//等待最近一次對RTC寄存器的寫操作完成
RTC_EnterConfigMode();/// 允許配置
RTC_SetPrescaler(32767); //設置RTC預分頻的值
RTC_WaitForLastTask();//等待最近一次對RTC寄存器的寫操作完成
RTC_Set(2009,12,2,10,0,55); //設置時間
RTC_ExitConfigMode(); //退出配置模式
BKP_WriteBackupRegister(BKP_DR1, 0X5050);//向指定的后備寄存器中寫入用戶程序數據
}
else//系統繼續計時
{
RTC_WaitForSynchro();//等待最近一次對RTC寄存器的寫操作完成
RTC_ITConfig(RTC_IT_SEC, ENABLE);//使能RTC秒中斷
RTC_WaitForLastTask();//等待最近一次對RTC寄存器的寫操作完成
}
RTC_NVIC_Config();//RCT中斷分組設置
RTC_Get();//更新時間
return 0; //ok
}
復制代碼
該函數用的就是固件庫中關于RTC部分的函數,整個操作都是按數據手冊的操作流程來執行;其中用到了c語言編程技巧,臨時變量temp防止程序死機。中斷如何配置?一般都有固定格式。
下面是RTC實時時鐘寄存器版驅動函數(原子例程):
//實時時鐘配置
//初始化RTC時鐘,同時檢測時鐘是否工作正常
//BKP->DR1用于保存是否第一次配置的設置
//返回0:正常
//其他:錯誤代碼
u8 RTC_Init(void)
{
//檢查是不是第一次配置時鐘
u8 temp=0;
if(BKP->DR1!=0X5050)//第一次配置
{
RCC->APB1ENR|=1<<28; //使能電源時鐘
RCC->APB1ENR|=1<<27; //使能備份時鐘
PWR->CR|=1<<8; //取消備份區寫保護
RCC->BDCR|=1<<16; //備份區域軟復位
RCC->BDCR&=~(1<<16); //備份區域軟復位結束
RCC->BDCR|=1<<0; //開啟外部低速振蕩器
while((!(RCC->BDCR&0X02))&&temp<250)//等待外部時鐘就緒
{
temp++;
delay_ms(10);
};
if(temp>=250)return 1;//初始化時鐘失敗,晶振有問題
RCC->BDCR|=1<<8; //LSI作為RTC時鐘
RCC->BDCR|=1<<15;//RTC時鐘使能
while(!(RTC->CRL&(1<<5)));//等待RTC寄存器操作完成
while(!(RTC->CRL&(1<<3)));//等待RTC寄存器同步
RTC->CRH|=0X01; //允許秒中斷
while(!(RTC->CRL&(1<<5)));//等待RTC寄存器操作完成
RTC->CRL|=1<<4; //允許配置
RTC->PRLH=0X0000;
RTC->PRLL=32767; //時鐘周期設置(有待觀察,看是否跑慢了?)理論值:32767
RTC_Set(2012,9,7,13,16,55); //設置時間
RTC->CRL&=~(1<<4); //配置更新
while(!(RTC->CRL&(1<<5))); //等待RTC寄存器操作完成
BKP->DR1=0X5050;
printf("FIRST TIME\n");
}else//系統繼續計時
{
while(!(RTC->CRL&(1<<3)));//等待RTC寄存器同步
RTC->CRH|=0X01; //允許秒中斷
while(!(RTC->CRL&(1<<5)));//等待RTC寄存器操作完成
printf("OK\n");
}
MY_NVIC_Init(0,0,RTC_IRQChannel,2);//優先級設置
RTC_Get();//更新時間
return 0; //ok
}
復制代碼
就個人而言偏愛寄存器版本函數,思路清晰;同時可以學習如何操作寄存器。
歡迎光臨 (http://www.raoushi.com/bbs/)
Powered by Discuz! X3.1