STM32 备份寄存器操作

发布者:DreamyMoon最新更新时间:2016-10-11 来源: eefocus关键字: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、测试
下载好程序后,用串口线将开发板与电脑连接,打开串口调试软件,查看信息。给开发板上电,就会看到下图的现象:
STM32 备份寄存器操作 - ziye334 - ziye334的博客
 图中可以看到,第一次上电的时候,向备份寄存器写入1~42。接下去,再复位下开发板,就i可以看到下图现象:
STM32 备份寄存器操作 - ziye334 - ziye334的博客
 复位后,因为备份寄存器已经被设置了初值,所以先会读取备份寄存器的值,图中可以看到备份寄存器的值与设置的值相同,所以不会在一次对备份寄存器写数据了!

关键字:STM32  备份寄存器操作 引用地址:STM32 备份寄存器操作

上一篇:STM32 独立看门狗定时器IWDG复位
下一篇:STM32 RTC时钟日历

推荐阅读最新更新时间:2024-03-16 15:14

stm32定时器之Output Compare
stm32f103vb发出逻辑信号给MOC3020,控制BTA16可控硅的通断。 在检测到过零信号时,延时x毫秒,输出1;延时y毫秒,关闭输出。 实现相位控制调速感应电机(小功率)。 在stm32 discovery开发板上,使用蓝灯和绿灯模拟。 采用定时器的OC,比较输出来做。 选用VBT6的一个Timer来做,它有4个通道可以使用,可以拿来控制4路可控硅输出。 使用CubeMX做外设配置。 针脚配置: 这样不把输出直接发送到Pin上。 能直接发送到Pin上,使用One Pulse Mode 比较方便。 受限于委托公司的设计限制,没法使用脉冲模式。 注意Prescaler的值, 值 = 时钟频率/1000
[单片机]
<font color='red'>stm32</font>定时器之Output Compare
STM32单片机学习笔记(9):定时器中断
项目简介 利用CubMX生成基于32单片机的HAl库工程,然后编写程序在proteus上仿真验证。本项目最适合没有开发板的同学学习,零成本利用仿真软件率先入门STM32单片机。本项目利用CubMX创建一个32工程,用以实现定时器中断控制LED灯的状态转换的功能,并在Proteus中进行仿真验证。 硬件模块 STM32F103R4 LED 软件工具 CubMX Proteus KEIL 电路连接图 工作流程 首先,创建一个CubMX工程。这里选择的是STM32F103R4型号的单片机。下图是时钟树的设置,这个根据自己习惯设置就好,这里的时钟频率,也就是定时器时钟频率是8MHz. 介绍定时器发生中断时间的计算方法:
[单片机]
<font color='red'>STM32</font>单片机学习笔记(9):定时器中断
STM32入门编程总结2
上手思路,第一步先查芯片datasheet,一切以官网资料为准,可以在STM32 Cube MX软件里选择 ACCESS TO MCU SELECTOR ,在左上角输入 STM32F103C8后,点击 datasheet 自动打开 芯片手册,点击另存为保存到桌面慢慢看。1看封装,2看供电,3看GPIO,4看中断,FLASH大小+USART也瞅瞅看。建议先搜个官方开发板原理图混个脸熟,软件项目文件打开后先编译一遍能否 0 error (s) 0 warning(s)。 最小系统,3.3V供电电路(2.0-3.6V)+复位电路(低电平复位)+8M晶振 + 启动选择电路(BOOT0 、BOOT1)+调试下载SWD接口(PA13、PA
[单片机]
STM32 f103搭配LM386声音传感器实现简单音乐识别
1.前言 2019年12月初,有一个中国机器人技能大赛中的双足机器人比赛项目,意思是机器人识别音乐跳对应节奏的舞蹈,五首音乐随机抽三首歌曲,音乐停,机器人停。 新比赛,新项目,难度自然有,坑也不少。希望这篇文章能给大家带来一点帮助。废话不多说,进入正题。 2.效果 (健康歌)每100ms采样一次,歌曲前5秒内共测50次数据,重复12组 (卡路里) 重复7组 可以看出一首歌经过多次测值,其采样值数组呈现出有规律的特征;不同的歌曲的特征也有较好的区分度。达到了区分歌曲的效果。下面讲讲具体实现步骤。 3.思路 href= 做什么:识别不同音乐,识别声音有无。 href= 怎么做:a.利用传感器判断出音乐或声音
[单片机]
<font color='red'>STM32</font> f103搭配LM386声音传感器实现简单音乐识别
10天学会STM32的学习心得总结
01 前言 有读者问,如何系统地入门学习stm32呢? 假如你会使用8051 , 会写C语言,那么STM32本身并不需要刻意的学习。 我们要考虑的是, 我可以快速用STM32实现什么?为什么使用STM32而不是8051? 是因为51的频率太低,无法满足计算需求? 是51的管脚太少,无法满足众多外设的IO? 是51的功耗太大,电池挺不住? 是51的功能太弱,而你要使用SPI、I2C、ADC、DMA? 是51的内存太小而你要存储的东西太多? 当你需要使用STM32某些功能,而51实现不了的时候, 那STM32自然不需要学习,你会直接去寻找STM32某方面的使用方法。 比如要用spi协议的网卡、要使用串口通信、要使用
[单片机]
STM32学习笔记:gps两种解码的方式
做为现在的物联网行业,手持设备中,缺少不了的就是GPS定位功能。GPS模块和STM32的串口进行通信,将GPS的数据发送给M3的串口,由M3进行GPS协议的解码。解析出来后保存在响应的结构体中。在进行显示。 这里分别介绍2中解析协议的方法,第一种就是自己写解析协议函数,第二种便是采用别人写好的GPS解析协议库:NMEALIB库,将这个库移植到M3中,直接调用API函数,就可以解析出GPS信息,同样的也保存在一个结构体中。 下面分析一下这两种解析协议的算法,第一种,采用的是正点原子写的GPS解析算法(感谢原子哥) //从buf里面得到第cx个逗号所在的位置//返回值:0~0XFE,代表逗号所在位置的偏移.// 0XFF,代表不
[单片机]
<font color='red'>STM32</font>学习笔记:gps两种解码的方式
基于STM32设计的自动刹车灯
一、项目介绍 随着科技的发展,人们对低碳环保的认知和需求不断提高。骑自行车既能够低碳环保,又能够锻炼身体,成为了很多人出行的首选。然而,由于自行车本身没有带指示灯,比如刹车指示灯等,所以自行车的安全性并不是很好,如果人们在骑自行车时紧急刹车,后车无法及时判断前方自行车的行为,容易造成交通事故。因此,设计一款自动刹车灯系统具有十分重要的意义。 本项目实现了通过安装ADXL345陀螺仪和四枚LED灯还有STM32F103C8T6主控芯片来实现自行车自动刹车灯的功能。当自行车上安装了该设备后,ADXL345通过IIC通信协议将X,Y,Z三轴的加速度实时值发送给SMT32F103C8T6主控芯片,并结合STM32高级定时器的PWM功能
[单片机]
基于<font color='red'>STM32</font>设计的自动刹车灯
在单片机上实现动态加载功能
本项目是一个在单片机(如:STM32)上实现动态加载功能的函数库,与Windows中的dll,Linux中的so类似,可以将代码动态地从其他的存储介质,动态加载到RAM中。 软件架构 本项目文件夹有三个,其中common存储了用于生成可重定位的.axf文件的工程与动态加载器工程交互用的函数,src提供动态加载器的源码,rel_axf_project_template提供了一个简单的可重定位的.axf文件的工程示例,example.c是一个简单的使用示例,所有文件的主要功能如下: /common/dl_extern_lib.h 描述了app程序用于调用host程序的函数向量表的基地址,以及相关的一些宏定义 /common/dl_
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved