STM32 备份寄存器操作
STM32系列為處理器都有備份寄存器,他它們處于備份區域里,當VDD電源被切斷,它們仍然由VBAT維持供電,當系統在待機模式下被喚醒,或者系統復位或電源復位是,它們都不會被復位。以實時時鐘RTC為例,在上一篇文章中講過,RTC處理依賴系統電源(VDD供電)外,還依賴者備份電源(VBAT供電),即使系統電源被切斷,只要備份電源還在,RTC就能繼續工作。備份寄存器也是依賴者備份電源的。STM32都有備份寄存器,但是備份寄存器的數量卻不一定相同!對于大容量的微處理器系列來說,它有著42個16位的寄存器,而中小容量的微處理器卻只有10個16為的寄存器。我使用的微處理器是STM32F103ZET6,屬于大容量系列,所以它他有著42個備份寄存器。下面就是基于大容量的。
下面就來講講備份寄存器(BKP)的操作,還是基于我自己的規范工程。
1、工程的修改
1)首先當然要添加stm32f10x_bkp.c文件到STM32F10x_StdPeriph_Driver工程組中。除此之外,要想訪問備份寄存器,還要講stm32f10x_pwr.c文件再添加進去。
2)打開stm32f10x_conf.c文件,將其中原先屏蔽著的:#include "stm32f10x_bkp.h" 與 #include "stm32f10x_pwr.h"這兩句話的屏蔽去掉。
3)新建Backup.c與Backup.h兩個文件,分別保存在BSP文件下的src與inc中,并將Backup.c文件添加到BSP工作組中。
?
2、Backup.c與Backup.h兩個文件的代碼編寫
首先要初始化下備份寄存器,代碼如下:
/*************************************************************
Function : Backup_Init
Description: 備份寄存器初始化
Input : none
return :
*************************************************************/
void Backup_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);//初始化電源控制時鐘與備份寄存器時鐘
PWR_BackupAccessCmd(ENABLE); //允許訪問備份寄存器
BKP_ClearFlag();//清除入侵引腳事件標志位
if(RCC_GetFlagStatus(RCC_FLAG_PORRST) != RESET)//上電復位
{
RCC_ClearFlag();//清除復位標志位
if(Backup_CheckData(0x0001) != 0)//備份寄存器數據錯誤或,沒有數據 {
Backup_WriteData(0x0001);//寫入數據
}
}
}
?
要初始化備份寄存器,當然要線初始化PWR與BKP的時鐘了,接著設置允許訪問,然后清除入侵事件標志位。什么是入侵事件?STM32對應有一個入侵引腳,STM32F103ZET6對應的入侵引腳是PC13,當它的電平從0變成1或者從1變成0時,就會產生一個入侵檢測事件,然后會把所有的數據備份寄存器的內容清除張佑赫就是為什叫做"入侵"這個名字的原因了。所以這里初始化的時候,要將它的標志位清除。接下去再判斷上電復位標志位,如果檢測到上電復位,那么先清除下標志位,再調用自己寫的Backup_CheckData()函數來讀取備份寄存器的數據進而判斷之前備份寄存器的數據是否有數據或者說正確的指定數據,如果沒有,則想他寫入數據,這里調用自己編寫的Backup_WriteData()函數向備份急寄存器寫入數據,下面馬上講到。
下面先來講講Backup_WriteData()函數如何向備份寄存器寫數據,代碼如下:
uint16_t BKPDataReg[42] ={//對大容量微處理器來說,它有42個備份寄存器,地址偏移為: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: 向備份寄存器寫的數據
Input : firstBackupData - 數據的首數據
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++)
{ /向備份寄存器寫數據
BKP_WriteBackupRegister(BKPDataReg[index], firstBackupData + index);/
PRINTF("BKP_DR%d: %d\r\n", index + 1, firstBackupData + index);
}
}
代碼很簡單,不過在這個函數之前要線定義一個數組BKPDataReg[],它的元素就是42個備份寄存器的地址。在Backup_WriteData()函數中,通過一個循環函數,使用庫函數BKP_WriteBackupRegister()分別向備份寄存器中寫入firstBackupData + index,也就是1~42了。
再來講講Backup_CheckData()函數,代碼如下:
/*************************************************************
Function : Backup_CheckData
Description: 檢查備份寄存器的數據是否正確
Input : firstBackupData-第一個備份寄存器數據
return : 0-正確 其他-錯誤
*************************************************************/
static u8 Backup_CheckData(u32 firstBackupData)
{
u32 index;
PRINTF("Begin to check backup registers\r\n");
for(index = 0; index < 42; index++)
{ //檢查備份寄存器的數據是否正確
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;
}
這個函數其實也是很簡單,循環42次讀出42個備份寄存器的數據,在與之前寫入的數據進行比較,如果相等則放回0,否者返回最先不同的備份寄存器索引。這里調用庫函數BKP_ReadBackupRegister()來讀取備份寄存器的值。
這樣Backup.c的代碼就結束了,下面貼下Backup.h的代碼,如下:
#ifndef __BACKUP_H__
#define __BACKUP_H__
#include "stm32f10x.h"
void Backup_Init(void);
#endif
3、main函數的編寫
main函數很簡單,只是調用下備份寄存器的初始化函數就可以了,代碼如下:
/*************************************************************
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、測試
下載好程序后,用串口線將開發板與電腦連接,打開串口調試軟件,查看信息。給開發板上電,就會看到下圖的現象:
?圖中可以看到,第一次上電的時候,向備份寄存器寫入1~42。接下去,再復位下開發板,就i可以看到下圖現象:
?復位后,因為備份寄存器已經被設置了初值,所以先會讀取備份寄存器的值,圖中可以看到備份寄存器的值與設置的值相同,所以不會在一次對備份寄存器寫數據了!
總結
以上是生活随笔為你收集整理的STM32 备份寄存器操作的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: STM32L152RC 在keil4中使
- 下一篇: STM32 RTC实时时钟