STM32 备份寄存器操作
STM32系列為處理器都有備份寄存器,他它們處于備份區(qū)域里,當(dāng)VDD電源被切斷,它們?nèi)匀挥蒝BAT維持供電,當(dāng)系統(tǒng)在待機(jī)模式下被喚醒,或者系統(tǒng)復(fù)位或電源復(fù)位是,它們都不會(huì)被復(fù)位。以實(shí)時(shí)時(shí)鐘RTC為例,在上一篇文章中講過,RTC處理依賴系統(tǒng)電源(VDD供電)外,還依賴者備份電源(VBAT供電),即使系統(tǒng)電源被切斷,只要備份電源還在,RTC就能繼續(xù)工作。備份寄存器也是依賴者備份電源的。STM32都有備份寄存器,但是備份寄存器的數(shù)量卻不一定相同!對(duì)于大容量的微處理器系列來說,它有著42個(gè)16位的寄存器,而中小容量的微處理器卻只有10個(gè)16為的寄存器。我使用的微處理器是STM32F103ZET6,屬于大容量系列,所以它他有著42個(gè)備份寄存器。下面就是基于大容量的。
下面就來講講備份寄存器(BKP)的操作,還是基于我自己的規(guī)范工程。
1、工程的修改
1)首先當(dāng)然要添加stm32f10x_bkp.c文件到STM32F10x_StdPeriph_Driver工程組中。除此之外,要想訪問備份寄存器,還要講stm32f10x_pwr.c文件再添加進(jìn)去。
2)打開stm32f10x_conf.c文件,將其中原先屏蔽著的:#include "stm32f10x_bkp.h" 與 #include "stm32f10x_pwr.h"這兩句話的屏蔽去掉。
3)新建Backup.c與Backup.h兩個(gè)文件,分別保存在BSP文件下的src與inc中,并將Backup.c文件添加到BSP工作組中。
?
2、Backup.c與Backup.h兩個(gè)文件的代碼編寫
首先要初始化下備份寄存器,代碼如下:
/*************************************************************
Function : Backup_Init
Description: 備份寄存器初始化
Input : none
return :
*************************************************************/
void Backup_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);//初始化電源控制時(shí)鐘與備份寄存器時(shí)鐘
PWR_BackupAccessCmd(ENABLE); //允許訪問備份寄存器
BKP_ClearFlag();//清除入侵引腳事件標(biāo)志位
if(RCC_GetFlagStatus(RCC_FLAG_PORRST) != RESET)//上電復(fù)位
{
RCC_ClearFlag();//清除復(fù)位標(biāo)志位
if(Backup_CheckData(0x0001) != 0)//備份寄存器數(shù)據(jù)錯(cuò)誤或,沒有數(shù)據(jù) {
Backup_WriteData(0x0001);//寫入數(shù)據(jù)
}
}
}
?
要初始化備份寄存器,當(dāng)然要線初始化PWR與BKP的時(shí)鐘了,接著設(shè)置允許訪問,然后清除入侵事件標(biāo)志位。什么是入侵事件?STM32對(duì)應(yīng)有一個(gè)入侵引腳,STM32F103ZET6對(duì)應(yīng)的入侵引腳是PC13,當(dāng)它的電平從0變成1或者從1變成0時(shí),就會(huì)產(chǎn)生一個(gè)入侵檢測(cè)事件,然后會(huì)把所有的數(shù)據(jù)備份寄存器的內(nèi)容清除張佑赫就是為什叫做"入侵"這個(gè)名字的原因了。所以這里初始化的時(shí)候,要將它的標(biāo)志位清除。接下去再判斷上電復(fù)位標(biāo)志位,如果檢測(cè)到上電復(fù)位,那么先清除下標(biāo)志位,再調(diào)用自己寫的Backup_CheckData()函數(shù)來讀取備份寄存器的數(shù)據(jù)進(jìn)而判斷之前備份寄存器的數(shù)據(jù)是否有數(shù)據(jù)或者說正確的指定數(shù)據(jù),如果沒有,則想他寫入數(shù)據(jù),這里調(diào)用自己編寫的Backup_WriteData()函數(shù)向備份急寄存器寫入數(shù)據(jù),下面馬上講到。
下面先來講講Backup_WriteData()函數(shù)如何向備份寄存器寫數(shù)據(jù),代碼如下:
uint16_t BKPDataReg[42] ={//對(duì)大容量微處理器來說,它有42個(gè)備份寄存器,地址偏移為:0x04~0x48,0x40~0xBC
BKP_DR1, BKP_DR2, BKP_DR3, BKP_DR4, BKP_DR5, BKP_DR6, BKP_DR7, BKP_DR8,
BKP_DR9, BKP_DR10, BKP_DR11, BKP_DR12, BKP_DR13, BKP_DR14, BKP_DR15, BKP_DR16,
BKP_DR17, BKP_DR18, BKP_DR19, BKP_DR20, BKP_DR21, BKP_DR22, BKP_DR23, BKP_DR24,
BKP_DR25, BKP_DR26, BKP_DR27, BKP_DR28, BKP_DR29, BKP_DR30, BKP_DR31, BKP_DR32,
BKP_DR33, BKP_DR34, BKP_DR35, BKP_DR36, BKP_DR37, BKP_DR38, BKP_DR39, BKP_DR40,
BKP_DR41, BKP_DR42
};
/*************************************************************
Function : Backup_WriteData
Description: 向備份寄存器寫的數(shù)據(jù)
Input : firstBackupData - 數(shù)據(jù)的首數(shù)據(jù)
return : none
*************************************************************/
static void Backup_WriteData(u32 firstBackupData)
{
u32 index;
PRINTF("Begin to wite data to backup registers\r\n");
for(index = 0; index < 42; index++)
{ /向備份寄存器寫數(shù)據(jù)
BKP_WriteBackupRegister(BKPDataReg[index], firstBackupData + index);/
PRINTF("BKP_DR%d: %d\r\n", index + 1, firstBackupData + index);
}
}
代碼很簡(jiǎn)單,不過在這個(gè)函數(shù)之前要線定義一個(gè)數(shù)組BKPDataReg[],它的元素就是42個(gè)備份寄存器的地址。在Backup_WriteData()函數(shù)中,通過一個(gè)循環(huán)函數(shù),使用庫函數(shù)BKP_WriteBackupRegister()分別向備份寄存器中寫入firstBackupData + index,也就是1~42了。
再來講講Backup_CheckData()函數(shù),代碼如下:
/*************************************************************
Function : Backup_CheckData
Description: 檢查備份寄存器的數(shù)據(jù)是否正確
Input : firstBackupData-第一個(gè)備份寄存器數(shù)據(jù)
return : 0-正確 其他-錯(cuò)誤
*************************************************************/
static u8 Backup_CheckData(u32 firstBackupData)
{
u32 index;
PRINTF("Begin to check backup registers\r\n");
for(index = 0; index < 42; index++)
{ //檢查備份寄存器的數(shù)據(jù)是否正確
if(BKP_ReadBackupRegister(BKPDataReg[index]) != (firstBackupData + index))
{
PRINTF("BKP_DR%d data check impare!\r\n", index + 1);
return (index + 1);
}
else
{
PRINTF("BKP_DR%d data check OK!\r\n", index + 1);
}
}
return 0;
}
這個(gè)函數(shù)其實(shí)也是很簡(jiǎn)單,循環(huán)42次讀出42個(gè)備份寄存器的數(shù)據(jù),在與之前寫入的數(shù)據(jù)進(jìn)行比較,如果相等則放回0,否者返回最先不同的備份寄存器索引。這里調(diào)用庫函數(shù)BKP_ReadBackupRegister()來讀取備份寄存器的值。
這樣Backup.c的代碼就結(jié)束了,下面貼下Backup.h的代碼,如下:
#ifndef __BACKUP_H__
#define __BACKUP_H__
#include "stm32f10x.h"
void Backup_Init(void);
#endif
3、main函數(shù)的編寫
main函數(shù)很簡(jiǎn)單,只是調(diào)用下備份寄存器的初始化函數(shù)就可以了,代碼如下:
/*************************************************************
Function : main
Description: main入口
Input : none
return : none
*************************************************************/
int main(void)
{
BSP_Init();
PRINTF("\nmain() is running!\r\n");
Backup_Init();
while(1)
{
LED1_Toggle();
Delay_ms(1000);
}
}
4、測(cè)試
下載好程序后,用串口線將開發(fā)板與電腦連接,打開串口調(diào)試軟件,查看信息。給開發(fā)板上電,就會(huì)看到下圖的現(xiàn)象:
?圖中可以看到,第一次上電的時(shí)候,向備份寄存器寫入1~42。接下去,再復(fù)位下開發(fā)板,就i可以看到下圖現(xiàn)象:
?復(fù)位后,因?yàn)閭浞菁拇嫫饕呀?jīng)被設(shè)置了初值,所以先會(huì)讀取備份寄存器的值,圖中可以看到備份寄存器的值與設(shè)置的值相同,所以不會(huì)在一次對(duì)備份寄存器寫數(shù)據(jù)了!
總結(jié)
以上是生活随笔為你收集整理的STM32 备份寄存器操作的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: STM32L152RC 在keil4中使
- 下一篇: STM32 RTC实时时钟