当前位置: 首页 > news >正文

【自学嵌入式:stm32单片机】读写备份寄存器

接线图

image

这是江科大的接线图,我的版本还是使用硬件I2C与OLED屏幕通信,由于用的是硬件I2C2,所以按键键码值只读取GPIO_Pin_1就行,PB11被占用用来发送I2C信号,把相关代码注释即可

代码实现

标准库实现

已开源到:https://gitee.com/qin-ruiqian/jiangkeda-stm32

Key.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
//#include "Serial.h"//初始化按键
void Key_Init(void)
{//打开APB2总线GPIOB外设端口,并开启时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //读取按键,选择上拉输入GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //选的是PB1GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);//Serial_Init();
}//读取按键值
uint8_t Key_GetNum(void)
{uint8_t KeyNum = 0;//Serial_Printf("KeyNumStart:%d\r\n", KeyNum);if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0) //读取PB1口的电平{Delay_ms(20); //消抖while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0); //直到按键松手Delay_ms(20); //消抖KeyNum = 1;}//Serial_Printf("KeyNumEnd:%d\r\n", KeyNum);// if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 0) //读取PB11口的电平// {// 	Delay_ms(20); //消抖// 	while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 0); //直到按键松手// 	Delay_ms(20); //消抖// 	KeyNum = 2;// }return KeyNum;
}

main.c

#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "MYOLED.h"
#include "Key.h"
//#include "Serial.h"uint8_t KeyNum;
uint16_t ArrayWrite[] = {0x1234, 0x5678};
uint16_t ArrayRead[2]; //用于存放写入和读取数组的数组int main(void)
{//Serial_Init();MYOLED_Init();//Serial_Printf("OLED屏幕初始化完成\r\n");Key_Init();//Serial_Printf("按键初始化完成\r\n");MYOLED_ShowString(0,0,"W:");//Serial_Printf("OLED屏幕'W:'显示完成\r\n");MYOLED_ShowString(0,1,"R:");//BKP代码非常少,不进行封装了,直接在主函数中演示//第一步,开启PWR和BKP的时钟//第二部,使用PWR的一个函数,使能对BKP和RTC的访问RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); //开启PWR时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP, ENABLE); //开启BKP时钟PWR_BackupAccessCmd(ENABLE); //使能对BKP和RTC的访问//BKP_WriteBackupRegister(BKP_DR1, 0x1234); //写备份寄存器DR1// MYOLED_ShowHexNum(0,0,BKP_ReadBackupRegister(BKP_DR1),4); //读备份寄存器DR1,并用OLED屏幕显示//每次都读取一下:ArrayRead[0] = BKP_ReadBackupRegister(BKP_DR1);ArrayRead[1] = BKP_ReadBackupRegister(BKP_DR2);MYOLED_ShowHexNum(2,1,ArrayRead[0],4);MYOLED_ShowHexNum(7,1,ArrayRead[1],4);while (1) {KeyNum = Key_GetNum();//Serial_Printf("KeyNum:%d\r\n", KeyNum);if(KeyNum == 1){ArrayWrite[0]++;ArrayWrite[1]++;BKP_WriteBackupRegister(BKP_DR1, ArrayWrite[0]);BKP_WriteBackupRegister(BKP_DR2, ArrayWrite[1]);MYOLED_ShowHexNum(2,0,ArrayWrite[0],4);MYOLED_ShowHexNum(7,0,ArrayWrite[1],4);}ArrayRead[0] = BKP_ReadBackupRegister(BKP_DR1);ArrayRead[1] = BKP_ReadBackupRegister(BKP_DR2);MYOLED_ShowHexNum(2,1,ArrayRead[0],4);MYOLED_ShowHexNum(7,1,ArrayRead[1],4);}
}

HAL库实现

已开源到:https://gitee.com/qin-ruiqian/jiangkeda-stm32-hal
IDE关于RTC的设置如下图:
image

Key.c

/** Key.c**  Created on: Aug 9, 2025*      Author: Administrator*/
#include "stm32f1xx_hal.h"//读取按键值
uint8_t Key_GetNum(void)
{uint8_t KeyNum = 0;if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0){HAL_Delay(20); //消抖while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0); //直到按键松手HAL_Delay(20); //消抖KeyNum = 1;}
//	if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_11) == 0)
//	{
//		HAL_Delay(20); //消抖
//		while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_11) == 0); //直到按键松手
//		HAL_Delay(20); //消抖
//		KeyNum = 2;
//	}return KeyNum;
}

main.c

/* USER CODE BEGIN Header */
/********************************************************************************* @file           : main.c* @brief          : Main program body******************************************************************************* @attention** Copyright (c) 2025 STMicroelectronics.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.********************************************************************************/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "i2c.h"
#include "rtc.h"
#include "gpio.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "MYOLED.h"
#include "Key.h"
/* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD *//* USER CODE END PTD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD *//* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*//* USER CODE BEGIN PV */
uint8_t KeyNum;
uint16_t ArrayWrite[] = {0x1234, 0x5678};
uint16_t ArrayRead[2]; //用于存放写入和读取数组的数组
/* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 *//* USER CODE END 0 *//*** @brief  The application entry point.* @retval int*/
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_I2C2_Init();MX_RTC_Init();/* USER CODE BEGIN 2 */MYOLED_SetI2CHandleBeforeInit(&hi2c2); //一定别忘了加,这里得把句柄传进去MYOLED_Init();MYOLED_ShowString(0,0,"W:");MYOLED_ShowString(0,1,"R:");//每次都读取一下:ArrayRead[0] = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR1);// HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR1, Data);ArrayRead[1] = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR2);MYOLED_ShowHexNum(2,1,ArrayRead[0],4);MYOLED_ShowHexNum(7,1,ArrayRead[1],4);/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){KeyNum = Key_GetNum();if(KeyNum == 1){ArrayWrite[0]++;ArrayWrite[1]++;HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR1, ArrayWrite[0]);HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR2, ArrayWrite[1]);MYOLED_ShowHexNum(2,0,ArrayWrite[0],4);MYOLED_ShowHexNum(7,0,ArrayWrite[1],4);}ArrayRead[0] = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR1);;ArrayRead[1] = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR2);MYOLED_ShowHexNum(2,1,ArrayRead[0],4);MYOLED_ShowHexNum(7,1,ArrayRead[1],4);/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}/*** @brief System Clock Configuration* @retval None*/
void SystemClock_Config(void)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};/** Initializes the RCC Oscillators according to the specified parameters* in the RCC_OscInitTypeDef structure.*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI|RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;RCC_OscInitStruct.HSIState = RCC_HSI_ON;RCC_OscInitStruct.LSIState = RCC_LSI_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB buses clocks*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK){Error_Handler();}PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC;PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK){Error_Handler();}
}/* USER CODE BEGIN 4 *//* USER CODE END 4 *//*** @brief  This function is executed in case of error occurrence.* @retval None*/
void Error_Handler(void)
{/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state */__disable_irq();while (1){}/* USER CODE END Error_Handler_Debug */
}#ifdef  USE_FULL_ASSERT
/*** @brief  Reports the name of the source file and the source line number*         where the assert_param error has occurred.* @param  file: pointer to the source file name* @param  line: assert_param error line source number* @retval None*/
void assert_failed(uint8_t *file, uint32_t line)
{/* USER CODE BEGIN 6 *//* User can add his own implementation to report the file name and line number,ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

实现效果

读取上一次按的结果
image
这次按的结果
image
读取这次按的结果
image

http://www.sczhlp.com/news/50517/

相关文章:

  • nacos学习 - record
  • CSS 布局属性笔记
  • scheme语言的尾递归和命名let语法
  • 多智能体协作为什么这么难:系统频繁失败的原因分析与解决思路
  • 做cps的网络文学网站wordpress编辑器位置
  • 网站开发的几种语言新塘网站建设
  • 微信做淘宝客 网站打不开了淘宝客网站模板
  • 鞍山网站制作人才招聘判断网站是什么系统做的
  • comsol 多个参数进行参数化扫描时,不能有显式依赖关系,只能对比例系数d1par进行参数化扫描,才是对的!
  • schmem语言实现快速幂
  • 长沙优化网站推广网站建设工具的实验心得
  • 陕西做网站公司竞价单页网站策划设计制作
  • 一站式网站开发服务平台wordpress主题安装失败
  • 自己做的网站怎么让别人访问仿美团网站开发
  • 做图网站百度竞价排名案例
  • 手机网站全屏代码新手做网站买服务器
  • 手机高端网站建设平陆县网站建设
  • 网站标题栏做多大建筑工程造价信息网
  • 8.1 模块基础
  • 8.2 循环导入问题解决
  • 上海网站建设培训学校网站的营销方式有哪些
  • 专业做网站和小程序网站建设怎么设置留言界面
  • 凡科网站做门户网怎么样wordpress多级菜单插件
  • 南昌网站建设维护无人在线完整免费高清观看
  • 网站开发 价格差异网上做衣服的网站有哪些
  • 做旅游景区网站网站建设合同 完整版
  • 宁波企业网站建设公司淘宝网页版手机登录
  • 建设部网站施工员查询建设农业网站
  • 做网站行业的动态北京餐饮品牌设计公司
  • 网站建设哪里培训如何用wordpress制作二级目录