单片机的BKP(Backup)寄存器主要用于数据备份和保护。它可以用来存储一些关键数据,如系统配置、参数设置、校准值等。当单片机掉电或复位时,这些数据可以被保留下来,以便在恢复后继续使用。 本教程是基于沁恒微电子MCU CH32V307VCT6单片机的BKP的代码详解。 后备寄存器(BKP)提供了最大 42个 16 位的后备数据寄存器,最大可以用来存储 84字节的用户数据。在主电源(VDD)掉电后,这些数据仍可以由 VBAT供电而保持,不受待机状态、系统复位或电源复位的影响。此外 BKP 单元还提供了侵入检测管理、RTC 时钟校准及脉冲输出功能。详细的功能请查看用户手册,用户手册已上传。 void BKP_Tamper_Init(void)// BKP的初始化函数 { NVIC_InitTypeDef NVIC_InitStructure={0};//定义一个名为NVIC_InitStructure的变量,类型为NVIC_InitTypeDef结构体,并初始化为0 RCC_APB1PeriphClockCmd( RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE ); //使能PWR(电源控制)和BKP(备份寄存器)的时钟 BKP_TamperPinCmd( DISABLE );//禁用BKP_Tamper引脚 PWR_BackupAccessCmd( ENABLE );//使能对备份寄存器的访问权限 BKP_ClearFlag();//清除备份寄存器的标志位 BKP_WriteBackupRegister( BKP_DR1, 0x9880 );//向备份寄存器中写入数据,分别写入了四个备份寄存器(BKP_DR1, BKP_DR2, BKP_DR3, BKP_DR4)的值 BKP_WriteBackupRegister( BKP_DR2, 0x5678 ); BKP_WriteBackupRegister( BKP_DR3, 0xABCD ); BKP_WriteBackupRegister( BKP_DR4, 0x3456 ); printf( "BKP_DR1:%08x\r\n", BKP->DATAR1 );//打印出备份寄存器中的数据 printf( "BKP_DR2:%08x\r\n", BKP->DATAR2 ); printf( "BKP_DR3:%08x\r\n", BKP->DATAR3 ); printf( "BKP_DR4:%08x\r\n", BKP->DATAR4 ); BKP_TamperPinLevelConfig( BKP_TamperPinLevel_High); //TPAL:0-PC13 set input-pull-down//设置BKP_Tamper引脚的电平为高电平 // BKP_TamperPinLevelConfig( BKP_TamperPinLevel_Low ); //TPAL:1-PC13 input-pull-up NVIC_InitStructure.NVIC_IRQChannel = TAMPER_IRQn;//配置NVIC(嵌套向量中断控制器)相关参数 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//初始化NVIC,将TAMPER_IRQn通道的优先级设置为1 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//设置NVIC_InitStructure结构体中的NVIC_IRQChannelSubPriority子优先级设置为0 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能该中断通道 NVIC_Init( &NVIC_InitStructure );//调用NVIC_Init函数,将NVIC_InitStructure结构体作为参数传入,完成中断控制器的初始化和使能 BKP_ITConfig( ENABLE );//使能BKP中断 BKP_TamperPinCmd( ENABLE );//使能BKP_Tamper引脚 } void BKP_ClearFlag(void) { BKP->TPCSR |= BKP_CTE; } 这是一个用于清除备份寄存器(BKP)标志的函数。在CH32V307系列微控制器中,备份寄存器用于保存一些关键数据,以便在断电后仍能保持数据的持久性。 在这个函数中,使用了位或运算符(|=)来将BKP_CTE与TPCSR寄存器进行按位或操作。BKP_CTE是一个常量,代表需要清除的标志位。通过将该标志位置为1,可以清除相应的标志。
void BKP_WriteBackupRegister(uint16_t BKP_DR, uint16_t Data)//将用户数据写入指定的数据备份寄存器 { __IOuint32_t tmp = 0; tmp = (uint32_t)BKP_BASE; tmp += BKP_DR; *(__IOuint32_t *)tmp = Data; } 这是一个将用户数据写入指定的备份寄存器的函数。在CH32V307系列微控制器中,备份寄存器用于保存一些关键数据,以便在断电后仍能保持数据的持久性。 函数的参数包括BKP_DR和Data。BKP_DR是指定要写入的备份寄存器的编号,而Data是要写入的数据。 在函数中,首先定义了一个临时变量tmp,并将其初始化为BKP_BASE的地址。然后,通过加上BKP_DR,计算出要写入的备份寄存器的地址。 最后,使用指针操作符*将该地址转换为指向32位无符号整数的指针,并将Data的值赋给该指针指向的内存单元,从而将数据写入备份寄存器。
void BKP_ITConfig(FunctionalState NewState) { if(NewState) { BKP->TPCSR |= (1 << 2); } else { BKP->TPCSR &= ~(1 << 2); } } 这是一个用于配置备份寄存器中断的函数。在CH32V307系列微控制器中,备份寄存器可以触发中断,以便在特定条件下执行相应的处理。 函数的参数是一个FunctionalState类型的变量NewState,表示要配置的中断状态,可以是ENABLE或DISABLE。 在函数中,通过if语句判断NewState的值,如果为真(即ENABLE),则将BKP->TPCSR寄存器的第2位设置为1,以使能中断。如果为假(即DISABLE),则将BKP->TPCSR寄存器的第2位设置为0,以禁止中断。 int main(void) { NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置中断优先级分组为4 USART_Printf_Init(115200);//设置波特率为115200 SystemCoreClockUpdate();//更新系统时钟频率 printf("SystemClk:%d\r\n",SystemCoreClock);//打印当前系统时钟频率 设计为96MHZ printf( "ChipID:%08x\r\n", DBGMCU_GetCHIPID() );//调用DBGMCU_GetCHIPID函数获取芯片的唯一标识并打印出来 BKP_Tamper_Init();//调用BKP_Tamper_Init函数,初始化备份寄存器的防篡改功能 while(1); } 以上代码是主要的代码,主函数在串口上打印了系统时钟频率、芯片的唯一标识和备份在寄存器中的数据,下载程序后打开串口助手,得到的串口数据如下图所示。 可以看到打印出来的系统时钟频率为96MHZ,和设计的一样,芯片的唯一标识也成功打印出来,打印出来的备份寄存器数据和写入的备份寄存器数据一致。
建议大家看看用户手册上BKP的寄存器,理解寄存器每一位的作用。代码工程已上传。
|