STM32HAL库-针对芯片内部EEprom读写操作介绍

2023-11-16

目录

 

概述

一、使用方法

二、STM32CubeMx配置

三、Examples

四、运行结果

五、总结


概述

     本篇文章介绍如何使用STM32HAL库,操作芯片内部EEprom读写数据,类似操作Flash,可实现掉电保存数据功能。
(注:有些型号才有内部EEprom,没有的话,只能使用内部FLASH模拟EEprom,或者外挂EEprom芯片)

硬件:STM32L051C8T6最小系统板
软件:Keil 5.29  + STM32CubeMX6.2.1

 


 

一、使用方法

          通过参阅《STM32数据手册》得知,通过目录找到芯片中的内部eeprom章节,如下所示:


在《STM32中文参考手册》pdf文档中找到,第3.3小节:嵌入式闪存,对应的页数57。

这里我使用的是STM32L051C8T6的eeprom是512byte,通过手册得知是属于小容量,所以只需看地址分配图与每一页对应的大小(字节)即可。
想更详细的了解,请阅读《STM32数据手册》。

 

二、STM32CubeMx配置


三、Examples

打开STM32CubeMx生成的keil工程,新建Bsp文件夹,同时分别新建bsp_eeprom.c与bsp_eeprom.h文件,并把这两个文件,添加keil工程中来即可。

添加头文件路径

1、bsp_eeprom.h文件

/*-------------------------------------------------*/
/*                                                */
/*            实现内部eeprom功能的头文件            */
/*                                                 */
/*-------------------------------------------------*/

#ifndef __EEPROM_H
#define __EEPROM_H

#include "stm32l0xx.h"  //包含需要的头文件

#define DATA_EEPROM_START_ADDR     0x08080000   //起始地址
#define USER_DATA_EEPROM_ADDR			 DATA_EEPROM_START_ADDR + 0x00000000		//用户地址
#define DATA_EEPROM_BYTE_SIZE			 0x01FF				//空间
#define DATA_EEPROM_END_ADDR     	 DATA_EEPROM_START_ADDR + DATA_EEPROM_BYTE_SIZE  //结束地址
#define iEEPROM_CHECK_NUM 				 2


HAL_StatusTypeDef EEPROM_WriteData(uint32_t Address, uint32_t *wData, uint32_t len); 
HAL_StatusTypeDef EEPROM_ReadData(uint32_t Address, uint32_t *rData, uint32_t len);

HAL_StatusTypeDef EEPROM_WRITE_Verify_CHECK(uint32_t Address, uint32_t *wData, uint32_t len);
HAL_StatusTypeDef EEPROM_Read_Verify_CHECK(uint32_t Address, uint32_t *rData, uint32_t len);

#endif

2、bsp_eeprom.c文件

/*-------------------------------------------------*/
/*                                                */
/*            实现内部eeprom功能的源文件            */
/*                                                 */
/*-------------------------------------------------*/

#include "bsp_eeprom.h"     //包含需要的头文件
#include <string.h>
#include "usart.h"     //包含需要的头文件
#include "stdio.h"


/*-------------------------------------------------*/
/*函数名:内部eeprom擦除功能                          */
/*参  数:Address:擦除地址                        */
/*参  数:wData:擦除数据缓冲区                     */
/*参  数:len:擦除数据总长                         */
/*返回值:无                                       */
/*-------------------------------------------------*/
HAL_StatusTypeDef EEPROM_EraseData(uint32_t start, uint32_t NumberSectors)
{
	uint32_t i;
	uint32_t NbrOfPages = 0;
	uint32_t Address = start;
	HAL_StatusTypeDef status = HAL_OK;
	
	printf("EEPROM_EraseData len:%d\r\n", NumberSectors);
	
	NbrOfPages = (DATA_EEPROM_END_ADDR - Address)/FLASH_PAGE_SIZE;
	if(NumberSectors > NbrOfPages)	return (HAL_ERROR);
	
	for(i=0; i<NumberSectors; i++){                   //for循环,需要写入多少数据,就循环几次
		status = HAL_FLASHEx_DATAEEPROM_Erase(Address + i * 4);
	}
	if (status != HAL_OK)
	{
		printf("Erase Fail!!!\r\n");     //串口提示写入错误
		return (HAL_ERROR);
	}	
	printf("Erase Success.\r\n\r\n");
	return HAL_OK;
}

/*-------------------------------------------------*/
/*函数名:内部eeprom写功能                          */
/*参  数:Address:写入地址                        */
/*参  数:wData:写入数据缓冲区                     */
/*参  数:len:写入数据总长                         */
/*返回值:无                                       */
/*-------------------------------------------------*/
HAL_StatusTypeDef EEPROM_WriteData(uint32_t Address, uint32_t *wData, uint32_t len)
{		
	uint32_t i;
	//uint32_t *Data = 0;

	HAL_FLASHEx_DATAEEPROM_Unlock();			//解锁 
	
	EEPROM_EraseData(Address, len);
	
	printf("Write Address:%d\r\n", Address);
	
	printf("Write Data:\r\n");
	for(i=0; i<len; i++)							//for循环,需要写入多少数据,就循环几次
	{
		printf("wData[%d]=%08x\r\n",i,wData[i]);
#if 0		
		HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_WORD, Address + i * 4, *(wData+i)); //字节:FLASH_TYPEPROGRAM_WORD
#else			
		
		if(HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_WORD, Address, *(uint32_t*)(wData+i)) == HAL_OK)	//调用写数据函数,如果返回的不是FLASH_COMPLETE,表示写入出错,进入if
		{
			if (*(uint32_t*)Address != *(uint32_t*)(wData+i))
      {
				printf("Write Error!!!\r\n");     //串口提示写入错误
    	  HAL_FLASHEx_DATAEEPROM_Lock();
        /* FLASHEx_DATAEEPROM content doesn't match SRAM content */
        return(HAL_ERROR);
      }
			Address += 4;									  //地址递增4,因为一次写一个字,是4个字节
		}
#endif
	}
	printf("Write Success.\r\n\r\n"); 
	
	HAL_FLASHEx_DATAEEPROM_Lock();         //上锁
	return HAL_OK;
}

/*-------------------------------------------------*/
/*函数名:内部eeprom读功能                        */
/*参  数:Address:读取地址                        */
/*参  数:rData:保存数据缓冲区                     */
/*参  数:len:读取数据总长                         */
/*返回值:无                                       */
/*-------------------------------------------------*/
HAL_StatusTypeDef EEPROM_ReadData(uint32_t Address, uint32_t *rData, uint32_t len)
{		
	uint32_t i;	
	uint32_t *wAddr = 0;
	
	wAddr = (uint32_t *)(Address);   					//转换地址,地址从0x08080000开始
	printf("Read Address:%d\r\n", Address);
	
	//printf("Read Data:\r\n"); 
	for(i=0;i<len;i++){                                     //for循环,需要读取多少数据,就循环几次                      
		*rData++ = *wAddr++;                                  //每次读取的数据保存到rData缓冲区	
		//printf("rData[%d]=%08x\r\n",i,rData[i]);
	}
	printf("Read Complete.\r\n");
	return HAL_OK;
}


/*-------------------------------------------------*/
/*函数名:带有校验操作的内部eeprom写功能                          */
/*参  数:Address:写入地址                        */
/*参  数:wData:写入数据缓冲区                     */
/*参  数:len:写入数据总长                         */
/*返回值:无                                       */
/*-------------------------------------------------*/
HAL_StatusTypeDef EEPROM_WRITE_Verify_CHECK(uint32_t Address, uint32_t *wData, uint32_t len)
{		
	uint32_t buff[len];
	uint32_t i;
	for (i=0; i < iEEPROM_CHECK_NUM; i++)
	{
		EEPROM_WriteData(Address, wData, len);
		EEPROM_ReadData(Address, buff, len);
		if (memcmp(wData, buff, len)==0)
		{
			printf("\r\nWRITE_Verify Completing Comparative\r\n\r\n"); 
			return HAL_OK;
		}
	}
	return HAL_ERROR;
}

/*-------------------------------------------------*/
/*函数名:带有校验操作的内部eeprom读功能                        */
/*参  数:Address:读取地址                        */
/*参  数:rData:保存数据缓冲区                     */
/*参  数:len:读取数据总长                         */
/*返回值:无                                       */
/*-------------------------------------------------*/
HAL_StatusTypeDef EEPROM_Read_Verify_CHECK(uint32_t Address, uint32_t *rData, uint32_t len)
{		
  uint32_t buff0[len];
	uint32_t buff1[len];
	uint8_t i,j;
	
//	printf("len:%d\r\n", len);
//	printf("Address:%d\r\n", Address);
	
	for (i=0; i<iEEPROM_CHECK_NUM; i++)
	{
		printf("First  read Verify\r\n");
		EEPROM_ReadData(Address, buff0, len);
		printf("Second read Verify\r\n"); 
		EEPROM_ReadData(Address, buff1, len);
 
		if (memcmp(buff0, buff1, len)==0)
		{
			printf("Read_Verify Completing Comparative\r\n"); 
			for (j=0; j<len; j++)
			{
				*rData++ = buff0[j];
			}
			return HAL_OK;
		}
	}
	return HAL_ERROR;

}

3、mian.c文件

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "bsp_eeprom.h"
#include "stdio.h"
#include "string.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 */
//uint8_t wData[10] = "0x5a5a5a5a";   //需要写入的数据
//uint8_t rData[1];                   //用于保存读取数据的缓冲区


typedef	__PACKED_STRUCT{
	uint32_t Device_id;								// 设备号
	uint32_t Hardware_Version;				// 硬件版本信息
	uint32_t Application_Version;		  // APP软件版本
}DEVInfoTypeDef;

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* 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 */
void test_eeprom(void)
{

	DEVInfoTypeDef DevInfo_read = {0};
	
	DEVInfoTypeDef DevInfo_default = {
	    .Device_id			    = 0x10000111,
		.Hardware_Version 		= 0x10000111,
		.Application_Version 	= 0x10000111
  };
	
	DEVInfoTypeDef DevInfo_update= {
	    .Device_id				= 0x20000222,
		.Hardware_Version 		= 0x20000222,
		.Application_Version 	= 0x20000222
  };
	
	uint32_t page = sizeof(DevInfo_default) / 4;
	
	printf("*******************Internal EEPROM test***************\r\n\r\n"); 					 //串口提示信息
	printf("****************No verification function**************\r\n\r\n");
	
	//printf("page:%d\r\n", page);
	
	memset(&DevInfo_read, 0, sizeof(DevInfo_read));	//清空结构体内容
	EEPROM_WriteData(USER_DATA_EEPROM_ADDR, (uint32_t *)&DevInfo_default, page);     		    //内部EEprom写入数据
	HAL_Delay(200);	                 				 //延时
	EEPROM_ReadData(USER_DATA_EEPROM_ADDR, (uint32_t *)&DevInfo_read, page);      	        	//内部EEprom读取数据	
	printf("Device_id:0x%08lX, Hardware_Version:0x%08lX, Application_Version:0x%08lX \r\n",
						DevInfo_read.Device_id,           DevInfo_read.Hardware_Version,
						DevInfo_read.Application_Version);

    memset(&DevInfo_read, 0, sizeof(DevInfo_read));	//清空结构体内容
	EEPROM_WriteData(USER_DATA_EEPROM_ADDR, (uint32_t *)&DevInfo_update, page);     		      //内部EEprom写入数据
	HAL_Delay(200);	                 				 //延时
	EEPROM_ReadData(USER_DATA_EEPROM_ADDR, (uint32_t *)&DevInfo_read, page);      	        	//内部EEprom读取数据

	printf("Device_id:0x%08lX, Hardware_Version:0x%08lX, Application_Version:0x%08lX \r\n",
						DevInfo_read.Device_id,           DevInfo_read.Hardware_Version,
						DevInfo_read.Application_Version);
						
//	EEPROM_ReadData(USER_DATA_EEPROM_ADDR, (uint32_t *)&DevInfo_read, page);      	        	//内部EEprom读取数据

//	printf("Device_id:0x%08lX, Hardware_Version:0x%08lX, Application_Version:0x%08lX \r\n",
//						DevInfo_read.Device_id,           DevInfo_read.Hardware_Version,
//						DevInfo_read.Application_Version);					
	
	printf("\r\n****************Add validation function**************\r\n\r\n");
	
	memset(&DevInfo_read, 0, sizeof(DevInfo_read));	//清空结构体内容
	EEPROM_WRITE_Verify_CHECK(USER_DATA_EEPROM_ADDR, (uint32_t *)&DevInfo_default, page);     		    //内部EEprom写入数据
	HAL_Delay(200);	                 				 //延时
	EEPROM_Read_Verify_CHECK(USER_DATA_EEPROM_ADDR, (uint32_t *)&DevInfo_read, page);      	        	//内部EEprom读取数据	
	printf("Device_id:0x%08lX, Hardware_Version:0x%08lX, Application_Version:0x%08lX \r\n",
						DevInfo_read.Device_id,           DevInfo_read.Hardware_Version,
						DevInfo_read.Application_Version);

    memset(&DevInfo_read, 0, sizeof(DevInfo_read));	//清空结构体内容
	EEPROM_WRITE_Verify_CHECK(USER_DATA_EEPROM_ADDR, (uint32_t *)&DevInfo_update, page);     		      //内部EEprom写入数据
	HAL_Delay(200);	                 				 //延时
	EEPROM_Read_Verify_CHECK(USER_DATA_EEPROM_ADDR, (uint32_t *)&DevInfo_read, page);      	        	//内部EEprom读取数据

	printf("Device_id:0x%08lX, Hardware_Version:0x%08lX, Application_Version:0x%08lX \r\n",
						DevInfo_read.Device_id,           DevInfo_read.Hardware_Version,
						DevInfo_read.Application_Version);
}

/* 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_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
	test_eeprom();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
		HAL_Delay(1000);
		HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
    /* 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};

  /** Configure the main internal regulator output voltage
  */
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_8;
  RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_2;
  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_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
  {
    Error_Handler();
  }
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1;
  PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
  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 */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

四、运行结果

1、无校验运算

2、校验运算运行结果

 

传送门->代码

 

五、总结

      好了,就介绍到此,通过该案例,可以在一些产品上做掉电保存功能,和一些数据保存等功能。

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32HAL库-针对芯片内部EEprom读写操作介绍 的相关文章

  • 【沧海拾昧】Proteus8仿真stm32:ADC转换程序

    C0102 沧海茫茫千钟粟 且拾吾昧一微尘 沧海拾昧集 CuPhoenix 阅前敬告 沧海拾昧集仅做个人学习笔记之用 所述内容不专业不严谨不成体系 如有问题必是本集记录有谬 切勿深究 目录 一 原理图绘制 二 多位七段数码管 三 ADC引脚
  • STM32 基于Keil IDE 开发引用 Astyle 第三方工具格式化插件

    目录 概述 一 使用方法 二 STM32CubeMx配置 三 Examples 四 运行结果 五 总结 概述 本篇文章介绍如何使用Keil IDE 引用Astyle 第三方工具格式化代码 官网 http astyle sourceforge
  • STM32-TIM4-定时器中断

    include project h include timer h TIM4 Init 2000 72 定时2ms 定时器中断的定时时间设定 定时器只需要配置时钟 TIM和NVIC即可 void TIM4 Init u16 period u
  • OLED显示小数

    OLED显示小数并不是很难的 在通用的OLED库中是没有显示小数的 需要自己去写 写的方法大致是这样的 写出0到9的ACSLL值 只需要将小数点后面的位数 一位一位的写数字对应的ACSLL值即可 其中小数点 也是写同样对应的ACSLL值 只
  • STM32-定时器系列(一)基本定时器

    相信学过51单片机的小伙伴们使用过定时刷新数码管吧 那也一定想过 我们在STM32中也想要实现定时刷新数码管 这该怎么实现呢 下面小编就带大家走进STM32的定时器模块吧 一 什么是定时器 定时器是一种计时的工具 它具有延时 频率测量 PW
  • MQTT服务器搭建及客户端通信实例

    MQTT服务器 EMQX v3 客户端1 PC Windows10操作系统 客户端2 IOT BOARD RT Thread与正点原子联合开发的STM32L475核心芯片的开发板 1 搭建服务器 在EMQ官网https www emqx i
  • 【STM32】

    失败了也挺可爱 成功了就超帅 文章目录 前言 1 JTAG SWD引脚 2 禁用JTAG功能 2 1 标准库 2 2 HAL库 3 禁用SWD JTAG功能 3 1 标准库 3 2 HAL库 总结 前言 最近在画板子耍 我LED灯选用的 P
  • STM32L051C8T6 HAL库 + nRF24L01 收发案例(硬件SPI通讯)

    目录 概述 1 硬件平台 STM32L051C8T6 NRF24L01 1 原理图 2 STM32CubeMx工具配置如下 2 代码部分 1 nrf24L01 c文件 2 nrf24L01 h文件 3 usart c文件 2 1发送部分如下
  • STM32引用“CmBacktrace”: ARM Cortex-M 系列 MCU 错误追踪库

    目录 概述 一 使用方法 0 CmBacktrace 是什么 1 为什么选择 CmBacktrace 2 CmBacktrace 如何使用 2 1 演示 2 2 Demo 2 3 移植说明 2 4 API 说明 2 5 常见问题 2 6 许
  • STM32HAL 移植 cJSON开源库 (裸机开发神器)

    目录 概述 一 使用方法 二 STM32CubeMx配置 三 Examples 四 运行结果 五 总结 概述 本篇文章介绍如何使用STM32引用 cJSON开源库 JSON格式在互联网数据交互时常用的一个格式 现嵌入式物联网方向 经常使用到
  • STM32的PWM相关函数TIM_SetCompare1的一定理解

    void TIM SetCompare1 TIM TypeDef TIMx uint16 t Compare1 Check the parameters assert param IS TIM LIST8 PERIPH TIMx Set t
  • STM32-ADC电压采样实验(寄存器版)

    STM32F10X系列支持三路ADC 其ADC通道及对应IO口如下表所示 其能接受的电压输入范围一般为0 3 3V VREF VIN VREF 因此 如果需要测量超出0 3 3v量程范围的电压数据 需要在外围硬件增加分压电阻 将电路转换到0
  • #STM32 GPIO编程详解

    硬件环境 stm32f407zet6 软件环境 mdk5 1 GPIO概述 GPIO 翻译为通用输入输出 也就是软件可编程引脚 也就是MCU通过控制GPIO来完成一系列的功能 GPIO属于引脚 但引脚还包含电源 晶振 下载 boot 复位等
  • STM32HAL库-移植mbedtls开源库示例(一)

    目录 概述 一 使用方法 二 STM32CubeMx配置 三 Examples 四 运行结果 五 总结 概述 本篇文章介绍如何使用STM32HAL库 移植mbedtls开源库支持mqtt证书加密示例 GitHub https github
  • STM32 ADC 多通道16路电压采集

    下面介绍一种利用STM32单片机制作的16路多通道ADC采集电路图和源程序 采用USB接口与电脑连接 实则USB转串口方式 所以上位机可以用串口作为接口 电路图中利用LM324作为电压跟随器 起到保护单片机引脚的作用 直接在电脑USB取点
  • USART串口协议和USART串口外设(USART串口发送&串口发送和接收)

    1 通信接口 A 基本概念 通信的目的 将一个设备的数据传送到另一个设备 扩展硬件系统 通信协议 制定通信的规则 通信双方按照协议规则进行数据收发 异步 需要双方约定一个频率 B 数据通信方式 按数据通信方式分类 可分为串行通信和并行通信两
  • Stm32待机模式的进入与唤醒

    1 基础介绍 1 1 单片机的 低功耗模式 像是手机的待机模式 不同于正常运行模式 处于一种省电省资源的状态 1 2 在运行情况下 HCLK为cpu提供时钟 cortex m3内核执行程序的代码 如果处于中断事件的等待时 可以进入低功耗模式
  • Eclipse搭建stm32+jlink开发环境全攻略

    Eclipse搭建stm32 jlink开发环境全攻略 初级篇 前言 为什么需要这样的开发环境 免费 跨平台 自由度高 Eclipse代码提示功能强大 MDK弱爆了 注 本人原创 转载注明作者 by 秋之前 email xia mengli
  • STM32HAL库-针对芯片内部EEprom读写操作介绍

    目录 概述 一 使用方法 二 STM32CubeMx配置 三 Examples 四 运行结果 五 总结 概述 本篇文章介绍如何使用STM32HAL库 操作芯片内部EEprom读写数据 类似操作Flash 可实现掉电保存数据功能 注 有些型号
  • STM32HAL 移植MultiButton小巧简单事件驱动型按键驱动框架(裸机版本)

    目录 概述 一 使用方法 特性 按键事件 Examples 二 STM32CubeMx配置 三 Examples 四 运行结果 五 总结 概述 本篇文章介绍如何使用STM32移植 MultiButton开源框架 引用官网简述如下 Multi

随机推荐

  • nodejs如何添加html文件上传,通过nodejs实现文件的上传

    通过nodejs实现文件的上传 主要内容 本文将用来讲述如何通过nodejs进行文件上传 将会涉及到以下知识点 通过express模块进行服务器的搭建 通过multer模块将上传的文件保存到指定目录 通过fs path模块将文件改名 添加后
  • SGMII协议解析

    什么是SGMII 先说什么是GMII MII MII是ethernet协议里面MAC层和PHY层之间的接口标准 MII是4bits的数据位宽 支持10 100M的数据传输 GMII前面G表示Gigabit 代表支持1000M的传输速率 需要
  • conda环境中安装1秒安装秘籍

    无论是pip或者mim安装指令 只需要加上一个参数就能1秒安装完成 pip install opencv python i https mirror baidu com pypi simple 体验完后 点个赞吧
  • SpringBoot学习(三)——SpringBoot的配置

    一 入口类 通常而言 Spring Boot都会拥有一个名为 Application的入口类 如FirstApplication 而该入口类中会有一个main方法 这个main方法起始就是一个标准的Java应用的入口方法 在main方法中使
  • Clark变换和Park变换在三相系统和单相系统中的应用

    1 引言 Clark变换和Park变换在三相系统中应用广泛 并且在单相系统中也有应用 但是以往的资料都是仅分析单相的坐标变换或者三相的坐标变换 并没有总结三相和单相的联系 本文将以坐标变换矩阵为载体 分析坐标变换在单相和三相系统中的应用 2
  • Linux基础命令-echo输出信息

    文章目录 前言 一 echo命令介绍 二 命令语法及参数 三 参考实例 总结 前言 初学linux都会接触到这个echo命令 因为这个echo的用处实在太大了 不管说日常使用上还是写shell脚本中 都是需要用到的 echo命令可以输出用户
  • 分层+TCP三次+四次+TCP和UDP区别+UDP实现可靠传输

    目录 OSI与TCP IP各层的结构与功能 都有哪些协议 TCP 三次握手 三次握手流程 tcp为什么要三次握手 而不能二次握手 四次挥手 为什么要四次挥手 TCP UDP 协议的区别 TCP 协议如何保证可靠传输 滑动窗口和流量控制 拥塞
  • 【错误记录】psql: FATAL: role [User] does not exist

    错误记录 psql FATAL role User does not exist 这是因为 psql 默认是连接的当前用户名的数据库 字面意思就是当前用户名的数据库不存在 当然 PostgreSQL 默认会创建有三个数据库 postgres
  • ESP32-USB Serial/JTAG Controller使用

    ESP32 USB Serial JTAG Controller使用 概述 CDC ACM功能描述 环境说明 硬件查询方式使用 关键函数说明 示例代码 官方中断方式使用 关键函数说明 包含头文件 安装卸载驱动 收发数据 示例程序 概述 ES
  • SignalR应用场景

    SignalR 是一个用于实时通信和即时通讯的开发库 它可以在多种应用场景中提供实时性能和功能 以下是一些适合使用 SignalR 的应用场景 即时聊天应用程序 SignalR 可以用于构建即时聊天应用程序 包括个人聊天 群组聊天和在线客服
  • 第 8 章 Jenkins – 设置Build Job

    通过下面的练习 在Jenkins创建一个job 并获取一个简单的HelloWorld应用程序 编译并运行这个Java程序 step 1 进入Jenkins控制面板然后点击 NewItem step 2 在这个页面 输入Item name 在
  • 小知识-pycharm的debug如何跳过for循环

    pycharm的debug如何跳过for循环
  • ATLAS 加入服务器未响应,路由器设置出现服务器未响应

    路由器设置出现服务器未响应 内容精选 换一换 两者主要有以下区别 一般操作系统的默认路由优先使用主网卡 如果出现使用扩展网卡导致网络不通现象通常是路由配置问题 默认主网卡具备与云公共服务区 PaaS DNS等服务所在区域 互通能力 扩展网卡
  • Apollo源码安装的问题及解决方法

    问题一 在进行git clone时 会报错Failed to connect to github com port 443 Timed out 经过实践后推荐以下两种方法 方法一 在原地址前加https ghproxy com 原地址 gi
  • 关于在VUE中使用html2canvas+jspdf方案将HTML页面导出为PDF遇到的坑

    首先网上有很多教程 我就简单记录下 主要是记录我遇到的问题 首先 npm install html2canvas jspdf s 然后在main js中引入 引入html转pdf的js import htmlToPdf from asset
  • hive中get_json_object函数

    原数据 表名 explode test 列名 sale info source 7fresh monthSales 4900 userCount 1900 score 9 9 source jdmart monthSales 7900 us
  • Spring Boot 2.6集成knife4j,解决Failed to start bean ‘documentationPluginsBootstrapper‘

    本次学习参考 官方文档 本次示例采用Spring Boot 2 6 3 完整的pom xml文件
  • 「通信原理」格雷码的生成与破译

    通信原理 格雷码的生成与破译 格雷码 gray code 相邻两数之间只有一个bit发生了改变 因此相比于自然编码的二进制系统 格雷编码的更不容易出错 使用卡诺图化简布尔代数式的时候 也会用到格雷码 本文将介绍三种格雷码的生成与破译方法 即
  • 现代密码学案例研究之索尼PS3破解

    ECDSA案例研究之索尼PS3被破解 背景介绍 ECDSA算法介绍 破解算法介绍 Reference 索尼因为PlayStation 3糟糕的加密实现而受到了黑客的破解 那么事情是怎么样的呢 设计了哪些密码学的算法呢 背景介绍 在2010年
  • STM32HAL库-针对芯片内部EEprom读写操作介绍

    目录 概述 一 使用方法 二 STM32CubeMx配置 三 Examples 四 运行结果 五 总结 概述 本篇文章介绍如何使用STM32HAL库 操作芯片内部EEprom读写数据 类似操作Flash 可实现掉电保存数据功能 注 有些型号