stm32 BKP寄存器操作[操作寄存器+库函数]
来源:互联网 发布:第四次人口普查数据 编辑:程序博客网 时间:2024/04/30 08:07
BKP是“BACKUP”的缩写,stm32f103RCTE的内部配备了10个16位宽度的BKP寄存器。在主电源切断或系统产生复位时间时,BKP寄存器仍然可以在备用电源的支持下保持其内容。
BKP在实际应用中可以存入重要数据,防止被恶意查看,或用于断电回复等。
本例实现对BKP寄存器的读写操作,和入侵检测和处理。主程序中写入寄存器后,依次打印出10个BKP寄存器数据,然后触发GPIOC13的入侵中断(输入低电平),在中断中打印出入侵事件发生后的寄存器内容(复位为0 )。
直接操作寄存器
用到的寄存器描述如下:
备份数据寄存器x(BKP_DRx) (x = 1 … 10):低16位[15:0]有效,用来写入或读出备份数据。
备份控制寄存器(BKP_CR):
低两位有效。
TPAL[1]:侵入检测TAMPER引脚有效电平(TAMPER pin active level)
- 0:侵入检测TAMPER引脚上的高电平会清除所有数据备份寄存器(如果TPE位为1)
- 1:侵入检测TAMPER引脚上的低电平会清除所有数据备份寄存器(如果TPE位为1)
TPE[0]:启动侵入检测TAMPER引脚(TAMPER pin enable)
- 0:侵入检测TAMPER引脚作为通用IO口使用
- 1:开启侵入检测引脚作为侵入检测使用
备份控制/状态寄存器(BKP_CSR):
TIF[9]:侵入中断标志(Tamper interrupt flag) 0:无侵入中断 1:产生侵入中断
当检测到有侵入事件且TPIE位为1时,此位由硬件置1。
通过向CTI位写1来清除此标志位(同时也清除了中断)。如果TPIE位被清除,则此位也会被清除。
TEF[8]:侵入事件标志(Tamper event flag) 0:无侵入事件 1:检测到侵入事件
当检测到侵入事件时此位由硬件置1。通过向CTE位写1可清除此标志位
TPIE[2]:允许侵入TAMPER引脚中断(TAMPER pin interrupt enable)
0:禁止侵入检测中断 1:允许侵入检测中断(BKP_CR寄存器的TPE位也必须被置1)
注1:侵入中断无法将系统内核从低功耗模式唤醒。 注2:仅当系统复位或由待机模式唤醒后才复位该位。
CTI[1]:清除侵入检测中断(Clear tamper interrupt)
0:无效 1:清除侵入检测中断和TIF侵入检测中断标志
CTE[0]:清除侵入检测事件(Clear tamper event)
0:无效 1:清除TEF侵入检测事件标志(并复位侵入检测器)。
要写入BKP寄存器数据必须在 PWR->CR中取消备份区写保护,才可以写入BKP数据。stm32开启入侵检测也不需要设置GPIOC的时钟和输入输出模式。
代码如下:(system.h 和 stm32f10x_it.h 等相关代码参照 stm32 直接操作寄存器开发环境配置)
User/main.c
01
#include <stm32f10x_lib.h>
02
#include "system.h"
03
#include "usart.h"
04
#include "bkp.h"
05
06
#define LED1 PAout(4)
07
#define LED2 PAout(5)
08
09
void
Gpio_Init(
void
);
10
11
int
main(
void
)
12
{
13
u16 data,i=10;
14
15
Rcc_Init(9);
//系统时钟设置
16
17
Usart1_Init(72,9600);
18
19
Bkp_Init();
20
21
Tamper_Init();
22
23
Nvic_Init(0,0,TAMPER_IRQChannel,0);
//设置中断
24
25
Gpio_Init();
26
27
while
(i){
28
29
Write_Bkp(i,i);
30
31
data = Read_Bkp(i);
32
33
printf
(
"\n DR%u = 0x%04X\n"
,i,data);
34
35
delay(30000);
//延时30ms
36
37
i--;
38
39
}
40
41
while
(1);
42
}
43
44
45
void
Gpio_Init(
void
)
46
{
47
RCC->APB2ENR|=1<<2;
//使能PORTA时钟
48
49
GPIOA->CRL&=0x0000FFFF;
// PA0~3设置为浮空输入,PA4~7设置为推挽输出
50
GPIOA->CRL|=0x33334444;
51
52
53
//USART1 串口I/O设置
54
55
GPIOA -> CRH&=0xFFFFF00F;
//设置USART1 的Tx(PA.9)为第二功能推挽,50MHz;Rx(PA.10)为浮空输入
56
GPIOA -> CRH|=0x000008B0;
57
}
User/stm32f103x_it.c
01
#include "stm32f10x_it.h"
02
#include "system.h"
03
#include "stdio.h"
04
05
#define LED1 PAout(4)
06
#define LED2 PAout(5)
07
#define LED3 PAout(6)
08
#define LED4 PAout(7)
09
10
extern
u16 Read_Bkp(u8 reg);
11
12
void
TAMPER_IRQHandler(
void
)
13
{
14
u16 i=10,data;
15
16
LED4 =1 ;
17
18
printf
(
"\r\n A Tamper is coming .\r\n"
);
19
20
while
(i){
21
22
data = Read_Bkp(i);
23
24
printf
(
"\n DR%u = 0x%04X\n"
,i,data);
25
26
delay(30000);
//延时30ms
27
28
i--;
29
30
}
31
32
BKP->CSR |= 3<<0;
//清除事件中断标志位
33
34
}
Library/src/bkp.c
001
#include <stm32f10x_lib.h>
002
#include "bkp.h"
003
004
void
Bkp_Init(
void
)
005
{
006
RCC->APB1RSTR |= 1<<27;
//复位BKP寄存器
007
RCC->APB1RSTR &= ~(1<<27);
008
009
RCC->APB1ENR|=1<<28;
//使能电源时钟
010
RCC->APB1ENR|=1<<27;
//使能BKP时钟
011
}
012
013
014
/**
015
*
016
*后备寄存器写入操作
017
*reg:寄存器编号
018
*data:要写入的数值
019
*
020
**/
021
void
Write_Bkp(u8 reg,u16 data)
022
{
023
024
PWR->CR|=1<<8;
//取消备份区写保护
025
026
switch
(reg)
027
{
028
case
1:
029
BKP->DR1=data;
030
break
;
031
case
2:
032
BKP->DR2=data;
033
break
;
034
case
3:
035
BKP->DR3=data;
036
break
;
037
case
4:
038
BKP->DR4=data;
039
break
;
040
case
5:
041
BKP->DR5=data;
042
break
;
043
case
6:
044
BKP->DR6=data;
045
break
;
046
case
7:
047
BKP->DR7=data;
048
break
;
049
case
8:
050
BKP->DR8=data;
051
break
;
052
case
9:
053
BKP->DR9=data;
054
break
;
055
case
10:
056
BKP->DR10=data;
057
break
;
058
}
059
}
060
061
062
u16 Read_Bkp(u8 reg)
063
{
064
u16 data;
065
066
switch
(reg)
067
{
068
case
1:
069
data = BKP->DR1;
070
break
;
071
case
2:
072
data = BKP->DR2;
073
break
;
074
case
3:
075
data = BKP->DR3;
076
break
;
077
case
4:
078
data = BKP->DR4;
079
break
;
080
case
5:
081
data = BKP->DR5;
082
break
;
083
case
6:
084
data = BKP->DR6;
085
break
;
086
case
7:
087
data = BKP->DR7;
088
break
;
089
case
8:
090
data = BKP->DR8;
091
break
;
092
case
9:
093
data = BKP->DR9;
094
break
;
095
case
10:
096
data = BKP->DR10;
097
break
;
098
}
099
100
return
data;
101
}
102
103
//开启入侵检测,检测引脚为GPIOC13 但是不用打开其时钟和设置引脚模式
104
void
Tamper_Init()
105
{
106
107
BKP->CSR |= 3<<0;
//清除事件中断标志位
108
109
BKP->CR |= 1<<1;
//设定为入侵电平为低电平
110
BKP->CSR |= 1<<2;
//允许入侵中断
111
112
BKP->CR |= 1<<0;
//开启入侵检测
113
114
115
}
Library/inc/bkp.h
1
#include <stm32f10x_lib.h>
2
3
void
Bkp_Init(
void
);
4
5
void
Write_Bkp(u8 reg,u16 data);
6
7
u16 Read_Bkp(u8 reg);
8
9
void
Tamper_Init(
void
);
库函数操作
main.c
001
#include "stm32f10x.h"
002
#include "stdio.h"
003
004
005
#define PRINTF_ON 1
006
#define CHECK_CODE 0xAE86
007
008
009
void
RCC_Configuration(
void
);
010
void
GPIO_Configuration(
void
);
011
void
NVIC_Configuration(
void
);
012
void
USART_Configuration(
void
);
013
void
BKP_Configuration(
void
);
014
015
void
PrintBKP(
void
);
016
void
WriteBKP(u16 Data,u8 DRNumber);
017
u8 CheckBKP(
void
);
018
019
int
main(
void
)
020
{
021
RCC_Configuration();
022
GPIO_Configuration();
023
NVIC_Configuration();
024
USART_Configuration();
025
BKP_Configuration();
026
027
028
029
if
(CheckBKP())
030
{
031
printf
(
"\r\n The datas are as their initial status. \r\n"
);
032
WriteBKP(0xA522,2);
033
PrintBKP();
034
}
else
{
035
printf
(
"\r\n The datas have been changed . \r\n"
);
036
WriteBKP(0xA53C,1);
037
PrintBKP();
038
}
039
while
(1);
040
}
041
042
043
044
045
046
void
GPIO_Configuration(
void
)
047
{
048
GPIO_InitTypeDef GPIO_InitStructure;
049
050
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
051
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
052
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
053
GPIO_Init(GPIOA , &GPIO_InitStructure);
054
055
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
056
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
057
GPIO_Init(GPIOA , &GPIO_InitStructure);
058
}
059
060
void
BKP_Configuration(
void
)
061
{
062
PWR_BackupAccessCmd(ENABLE);
063
BKP_ClearFlag();
064
BKP_TamperPinLevelConfig(BKP_TamperPinLevel_Low);
065
BKP_ITConfig(ENABLE);
066
BKP_TamperPinCmd(ENABLE);
067
}
068
069
070
void
RCC_Configuration(
void
)
071
{
072
/* 定义枚举类型变量 HSEStartUpStatus */
073
ErrorStatus HSEStartUpStatus;
074
075
/* 复位系统时钟设置*/
076
RCC_DeInit();
077
/* 开启HSE*/
078
RCC_HSEConfig(RCC_HSE_ON);
079
/* 等待HSE起振并稳定*/
080
HSEStartUpStatus = RCC_WaitForHSEStartUp();
081
/* 判断HSE起是否振成功,是则进入if()内部 */
082
if
(HSEStartUpStatus == SUCCESS)
083
{
084
/* 选择HCLK(AHB)时钟源为SYSCLK 1分频 */
085
RCC_HCLKConfig(RCC_SYSCLK_Div1);
086
/* 选择PCLK2时钟源为 HCLK(AHB) 1分频 */
087
RCC_PCLK2Config(RCC_HCLK_Div1);
088
/* 选择PCLK1时钟源为 HCLK(AHB) 2分频 */
089
RCC_PCLK1Config(RCC_HCLK_Div2);
090
/* 设置FLASH延时周期数为2 */
091
FLASH_SetLatency(FLASH_Latency_2);
092
/* 使能FLASH预取缓存 */
093
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
094
/* 选择锁相环(PLL)时钟源为HSE 1分频,倍频数为9,则PLL输出频率为 8MHz * 9 = 72MHz */
095
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
096
/* 使能PLL */
097
RCC_PLLCmd(ENABLE);
098
/* 等待PLL输出稳定 */
099
while
(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
100
/* 选择SYSCLK时钟源为PLL */
101
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
102
/* 等待PLL成为SYSCLK时钟源 */
103
while
(RCC_GetSYSCLKSource() != 0x08);
104
}
105
/* 打开APB2总线上的GPIOA时钟*/
106
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1, ENABLE);
107
108
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR|RCC_APB1Periph_BKP, ENABLE);
109
110
}
111
112
113
void
USART_Configuration(
void
)
114
{
115
USART_InitTypeDef USART_InitStructure;
116
USART_ClockInitTypeDef USART_ClockInitStructure;
117
118
USART_ClockInitStructure.USART_Clock = USART_Clock_Disable;
119
USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low;
120
USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge;
121
USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable;
122
USART_ClockInit(USART1 , &USART_ClockInitStructure);
123
124
USART_InitStructure.USART_BaudRate = 9600;
125
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
126
USART_InitStructure.USART_StopBits = USART_StopBits_1;
127
USART_InitStructure.USART_Parity = USART_Parity_No;
128
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
129
USART_InitStructure.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;
130
USART_Init(USART1,&USART_InitStructure);
131
132
USART_Cmd(USART1,ENABLE);
133
}
134
135
136
void
NVIC_Configuration(
void
)
137
{
138
NVIC_InitTypeDef NVIC_InitStructure;
139
140
NVIC_InitStructure.NVIC_IRQChannel = TAMPER_IRQn;
141
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
142
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
143
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
144
NVIC_Init(&NVIC_InitStructure);
145
146
}
147
148
void
WriteBKP(u16 Data,u8 DRNumber)
// 还可加入一些加密算法;DRNumber (1-9)
149
{
150
switch
(DRNumber)
151
{
152
case
0x01: BKP_WriteBackupRegister(BKP_DR1,Data);
break
;
153
case
0x02: BKP_WriteBackupRegister(BKP_DR2,Data);
break
;
154
case
0x03: BKP_WriteBackupRegister(BKP_DR3,Data);
break
;
155
case
0x04: BKP_WriteBackupRegister(BKP_DR4,Data);
break
;
156
case
0x05: BKP_WriteBackupRegister(BKP_DR5,Data);
break
;
157
case
0x06: BKP_WriteBackupRegister(BKP_DR6,Data);
break
;
158
case
0x07: BKP_WriteBackupRegister(BKP_DR7,Data);
break
;
159
case
0x08: BKP_WriteBackupRegister(BKP_DR8,Data);
break
;
160
case
0x09: BKP_WriteBackupRegister(BKP_DR9,Data);
break
;
161
default
: BKP_WriteBackupRegister(BKP_DR1,Data);
162
}
163
BKP_WriteBackupRegister(BKP_DR10,CHECK_CODE);
164
}
165
166
u8 CheckBKP(
void
)
167
{
168
if
( BKP_ReadBackupRegister(BKP_DR10) == 0xAE86 )
// 如果此位数据丢失,则BPK数据丢失
169
return
1;
170
else
171
return
0;
172
}
173
174
void
PrintBKP(
void
)
175
{
176
printf
(
"DR1 = 0x%04X\t"
,BKP_ReadBackupRegister(BKP_DR1));
177
printf
(
"DR2 = 0x%04X\t"
,BKP_ReadBackupRegister(BKP_DR2));
178
printf
(
"DR3 = 0x%04X\t"
,BKP_ReadBackupRegister(BKP_DR3));
179
printf
(
"DR4 = 0x%04X\t"
,BKP_ReadBackupRegister(BKP_DR4));
180
printf
(
"DR5 = 0x%04X\t"
,BKP_ReadBackupRegister(BKP_DR5));
181
printf
(
"DR6 = 0x%04X\t"
,BKP_ReadBackupRegister(BKP_DR6));
182
printf
(
"DR7 = 0x%04X\t"
,BKP_ReadBackupRegister(BKP_DR7));
183
printf
(
"DR8 = 0x%04X\t"
,BKP_ReadBackupRegister(BKP_DR8));
184
printf
(
"DR9 = 0x%04X\t"
,BKP_ReadBackupRegister(BKP_DR9));
185
printf
(
"DR10 = 0x%04X\t"
,BKP_ReadBackupRegister(BKP_DR10));
186
187
}
188
189
190
#if PRINTF_ON
191
192
int
fputc
(
int
ch,
FILE
*f)
193
{
194
USART_SendData(USART1,(u8) ch);
195
while
(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET);
196
return
ch;
197
}
198
199
#endif
stm12f10x_it.c
01
#include "stm32f10x_it.h"
02
03
#include "stdio.h"
04
05
extern
void
PrintBKP(
void
);
06
07
void
TAMPER_IRQHandler(
void
)
08
{
09
printf
(
"\r\n A Tamper is coming .\r\n"
);
10
PrintBKP();
11
BKP_ClearITPendingBit();
12
BKP_ClearFlag();
13
14
}
0 0
- stm32 BKP寄存器操作[操作寄存器+库函数]
- stm32 BKP寄存器操作[操作寄存器+库函数]
- stm32 BKP寄存器操作[操作寄存器+库函数]
- STM32寄存器操作和库函数操作区别
- stm32 独立看门狗[操作寄存器+库函数]
- stm32 低功耗设计[操作寄存器+库函数]
- stm32 i2c通信 [操作寄存器+库函数]
- stm32 i2c通信 [操作寄存器+库函数]
- stm32 i2c通信 [操作寄存器+库函数]
- stm32 i2c通信 [操作寄存器+库函数]
- stm32 i2c通信 [操作寄存器+库函数]
- stm32 i2c通信 [操作寄存器+库函数]
- stm32 i2c通信 [操作寄存器+库函数]
- stm32 独立看门狗[操作寄存器+库函数]
- stm32 外部中断嵌套[操作寄存器+库函数]
- stm32 TIM定时器[操作寄存器+库函数]
- stm32 USART 串口通信[操作寄存器+库函数]
- stm32 DMA数据搬运 [操作寄存器+库函数]
- GO语言为结构体排序
- 深呼吸,不要被冲昏了头脑
- 函数的使用
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- stm32 BKP寄存器操作[操作寄存器+库函数]
- Objective-C中的@Property详解
- RS232 DB-9 针串口引脚定义
- Python的Django框架中的Context使用
- 别浪费自己的高学历
- 【HTML+CSS】(div布局)知识学习笔记
- 给oracle数据库表添加表注释和列注释
- 《统计学习方法》笔记(十四)--HMM(1)
- 标示符命名规则