STM32存储左右互搏 I2C总线读写EEPROM AD24C02

news2025/2/4 1:13:50

STM32存储左右互搏 I2C总线读写EEPROM AD24C02

在较低容量存储领域,EEPROM是常用的存储介质,不同容量的EEPROM的地址对应位数不同,在发送字节的格式上有所区别。EEPROM是非快速访问存储,因为EEPROM按页进行组织,在连续操作模式,当跨页时访问地址不是跳到下一页到开始,而是跳到当前页的首地址,因此跨页时要重新指定起始地址。而在控制端发送写操作I2C数据后还需要有等待EEPROM内部操作完成的时间才能进行下一次操作。AD24C02是最小容量256个字节的EEPROM, 一页只有8个字节,32页。管脚定位为:

在这里插入图片描述
这里介绍STM32访问 AD24C02的例程。采用STM32CUBEIDE开发平台,以STM32F401CCU6芯片为例,通过STM32 I2C硬件电路实现读写操作,通过UART串口进行控制。

STM32工程配置

首先建立基本工程并设置时钟:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
配置硬件I2C接口:
在这里插入图片描述
在这里插入图片描述
配置UART1作为通讯串口:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
保存并生成初始工程代码:

在这里插入图片描述

STM32工程代码

这里的测试逻辑比较简单:
当串口收到指令0x01时向EEPROM 地址0写入预设的256个字节0x00~0xFF,然后读出并通过串口打印出
当串口收到指令0x02时向EEPROM 地址0写入预设的256个字节0xFF~0x00,然后读出并通过串口打印出

AD24C02的设备默认访问地址为0xA0, 8位(对应256个字节)地址作为发送设备地址后的第一个字节发送。

建立AD24C02.h库头文件

#ifndef INC_AD24C02_H_
#define INC_AD24C02_H_

#include "main.h"

void PY_Delay_us_t(uint32_t Delay);
void AD24C02_Write(uint8_t addr, uint8_t * data, uint32_t len);
void AD24C02_Read(uint8_t addr, uint8_t * data, uint32_t len);

#endif

建立AD24C02.c库源文件:


#include <string.h>
#include <AD24C02.h>

#define Page_Size 8
#define Delay_Param 5
extern I2C_HandleTypeDef hi2c1;
extern uint8_t AD24C02_Default_I2C_Addr ;

void AD24C02_Write(uint8_t addr, uint8_t * data, uint32_t len)
{
	uint8_t AD24C02_I2C_Addr;

	uint32_t addr_page = addr/Page_Size;
	uint32_t addr_index = addr%Page_Size;
	uint32_t TLEN;
    uint8_t TAD[Page_Size+1];
    uint32_t i=0;

    if(len<=(Page_Size-addr_index))
    {
    	TAD[0] = addr ;
    	memcpy(TAD+1, data, len);

    	AD24C02_I2C_Addr = AD24C02_Default_I2C_Addr;
    	HAL_I2C_Master_Transmit(&hi2c1, AD24C02_I2C_Addr, TAD, len+1, 2700);  //Write data
    	PY_Delay_us_t(Delay_Param*1000);
    }
    else
    {
    	TAD[0] = addr ;
    	memcpy(TAD+1, data, (Page_Size-addr_index));

    	AD24C02_I2C_Addr = AD24C02_Default_I2C_Addr;
    	HAL_I2C_Master_Transmit(&hi2c1, AD24C02_I2C_Addr, TAD, (Page_Size-addr_index)+1, 2700);  //Write data
    	PY_Delay_us_t(Delay_Param*1000);

    	TLEN = (len-(Page_Size-addr_index));
    	while( TLEN >= Page_Size )
    	{
    		addr_page += 1;

        	TAD[0] = addr_page*Page_Size;
        	memcpy(TAD+1, data + (Page_Size-addr_index) + i*Page_Size, Page_Size);

        	AD24C02_I2C_Addr = AD24C02_Default_I2C_Addr;
        	HAL_I2C_Master_Transmit(&hi2c1, AD24C02_I2C_Addr, TAD, Page_Size+1, 2700);  //Write data
        	HAL_Delay(Delay_Param);

        	i++;
        	TLEN -= Page_Size;
        	PY_Delay_us_t(Delay_Param*1000);
    	}

    	if(TLEN>0)
    	{
    		addr_page += 1;

        	TAD[0] = addr_page*Page_Size;
        	memcpy(TAD+1, data + (Page_Size-addr_index) + i*Page_Size, TLEN);

        	AD24C02_I2C_Addr = AD24C02_Default_I2C_Addr;
        	HAL_I2C_Master_Transmit(&hi2c1, AD24C02_I2C_Addr, TAD, TLEN+1, 2700);  //Write data
        	PY_Delay_us_t(Delay_Param*1000);
    	}


    }


}


void AD24C02_Read(uint8_t addr, uint8_t * data, uint32_t len)
{
	uint8_t AD24C02_I2C_Addr;

	AD24C02_I2C_Addr = AD24C02_Default_I2C_Addr ;

	uint8_t RA[1];
	RA[0] = addr;

	HAL_I2C_Master_Transmit(&hi2c1, AD24C02_I2C_Addr, &RA[0], 1, 2700); //Write address for read
	HAL_I2C_Master_Receive(&hi2c1, AD24C02_I2C_Addr, data, len, 2700); //Read data

}

完成的main.c文件代码如下:

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2023 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.
  *
  ******************************************************************************
  */
//Written by Pegasus Yu in 2023
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <string.h>
#include "AD24C02.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
__IO float usDelayBase;
void PY_usDelayTest(void)
{
  __IO uint32_t firstms, secondms;
  __IO uint32_t counter = 0;

  firstms = HAL_GetTick()+1;
  secondms = firstms+1;

  while(uwTick!=firstms) ;

  while(uwTick!=secondms) counter++;

  usDelayBase = ((float)counter)/1000;
}

void PY_Delay_us_t(uint32_t Delay)
{
  __IO uint32_t delayReg;
  __IO uint32_t usNum = (uint32_t)(Delay*usDelayBase);

  delayReg = 0;
  while(delayReg!=usNum) delayReg++;
}

void PY_usDelayOptimize(void)
{
  __IO uint32_t firstms, secondms;
  __IO float coe = 1.0;

  firstms = HAL_GetTick();
  PY_Delay_us_t(1000000) ;
  secondms = HAL_GetTick();

  coe = ((float)1000)/(secondms-firstms);
  usDelayBase = coe*usDelayBase;
}

void PY_Delay_us(uint32_t Delay)
{
  __IO uint32_t delayReg;

  __IO uint32_t msNum = Delay/1000;
  __IO uint32_t usNum = (uint32_t)((Delay%1000)*usDelayBase);

  if(msNum>0) HAL_Delay(msNum);

  delayReg = 0;
  while(delayReg!=usNum) delayReg++;
}
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
I2C_HandleTypeDef hi2c1;

UART_HandleTypeDef huart1;

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_I2C1_Init(void);
static void MX_USART1_UART_Init(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
uint8_t cmd=0;          //for status control
uint8_t * RData;        //USB rx data pointer
uint32_t RDataLen;      //USB rx data length
uint8_t * TData;        //USB tx data pointer
uint32_t TDataLen;      //USB tx data length

uint8_t AD24C02_Default_I2C_Addr =  0xA0; //Pin A2=A1=0

uint32_t AD24C02_Access_Addr = 0;   //AD24C02 access address (8-bit)

uint8_t testdata[256];

uint8_t URX;
/* 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_I2C1_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
  PY_usDelayTest();
  PY_usDelayOptimize();

  HAL_UART_Receive_IT(&huart1, &URX, 1);

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
		if(cmd==1)
		{
			cmd=0;

			  for(uint32_t j=0; j<256; j++)
			  {
				   testdata[j] = j;
			  }

				AD24C02_Access_Addr = 0;  //Set access address here
				AD24C02_Write(AD24C02_Access_Addr, testdata, 256); //Write data

				memset(testdata, 0, 256);

				AD24C02_Read(AD24C02_Access_Addr, testdata, 256); //Read data
				HAL_UART_Transmit(&huart1, testdata, 256, 2700);

		}

		if(cmd==2)
		{
			cmd=0;

			  for(uint32_t j=0; j<256; j++)
			  {
				   testdata[j] = 255-j;
			  }

				AD24C02_Access_Addr = 0;  //Set access address here
				AD24C02_Write(AD24C02_Access_Addr, testdata, 256); //Write data

				memset(testdata, 0, 256);

				AD24C02_Read(AD24C02_Access_Addr, testdata, 256); //Read data
				HAL_UART_Transmit(&huart1, testdata, 256, 2700);
		}

		PY_Delay_us_t(100);
    /* 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};

  /** Configure the main internal regulator output voltage
  */
  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);

  /** 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.PLLM = 25;
  RCC_OscInitStruct.PLL.PLLN = 336;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
  RCC_OscInitStruct.PLL.PLLQ = 7;
  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();
  }
}

/**
  * @brief I2C1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_I2C1_Init(void)
{

  /* USER CODE BEGIN I2C1_Init 0 */

  /* USER CODE END I2C1_Init 0 */

  /* USER CODE BEGIN I2C1_Init 1 */

  /* USER CODE END I2C1_Init 1 */
  hi2c1.Instance = I2C1;
  hi2c1.Init.ClockSpeed = 400000;
  hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
  hi2c1.Init.OwnAddress1 = 0;
  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c1.Init.OwnAddress2 = 0;
  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  if (HAL_I2C_Init(&hi2c1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN I2C1_Init 2 */

  /* USER CODE END I2C1_Init 2 */

}

/**
  * @brief USART1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_USART1_UART_Init(void)
{

  /* USER CODE BEGIN USART1_Init 0 */

  /* USER CODE END USART1_Init 0 */

  /* USER CODE BEGIN USART1_Init 1 */

  /* USER CODE END USART1_Init 1 */
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART1_Init 2 */

  /* USER CODE END USART1_Init 2 */

}

/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 */

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}

/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart==&huart1)
	{
      cmd = URX;
      HAL_UART_Receive_IT(&huart1, &URX, 1);


	}

}
/* 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 */

STM32范例测试

上述范例的测试效果如下:
指令0x01写读:
在这里插入图片描述
指令0x02写读:
在这里插入图片描述

STM32例程下载

STM32F401CCU6 I2C总线读写EEPROM AD24C02例程

–End–

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/762049.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据库查询速度上不去的查询和分析

主要原因 数据库查询速度上不去、阻塞是指在并发访问 MySQL 数据库时,某个事务占用了资源并且长时间不释放,导致其他事务无法执行或执行缓慢的情况。MySQL 阻塞可能会导致数据库性能下降,甚至出现死锁等问题,需要马上进行处理。在 MySQL中,线程阻塞可能是由于以下原因导致…

vite 启动项目 报错 spawnargs: [ ‘--service=0.12.15‘, ‘--ping‘ ]

当前项目使用的是 vue3-antd-admin 框架 vue3-antd-admin 框架 详细地址 我们运行项目的时候发现报以下错误&#xff0c;npm i 了也不行, node:events:504throw er; // Unhandled error event^Error: spawn C:\Users\DELL\Desktop\vue3-antd-admin-master\node_modules\esbu…

阿里国际、敦煌、速卖通、沃尔玛、TEMU做测评补单核心关键点,看完你就会了

现在不管是做国内电商还是跨境电商&#xff0c;测评补单一直都有人在做&#xff0c;也确确实实的给卖家们带来了突破&#xff0c;不管是订单&#xff0c;留评&#xff0c;权重等等都有很大的提升&#xff0c;可以说有电商的地方就有测评补单&#xff0c;这是刚需。但是就像前人…

【C语言】深入理解C语言数据类型:从结构体到共用体和枚举的全面解析

目录 一、结构体概述及定义 1、概念 2、定义方式 方式1&#xff1a;先定义结构体类型&#xff0c;再定义结构体变量 方式2&#xff1a;定义结构体类型的同时定义结构体变量 方式3&#xff1a;定义一次性结构体 二、结构体变量的初始化 1、一般初始化 2、清空结构体变量…

【正点原子STM32连载】 第五十六章 DSP测试实验摘自【正点原子】STM32F103 战舰开发指南V1.2

1&#xff09;实验平台&#xff1a;正点原子stm32f103战舰开发板V4 2&#xff09;平台购买地址&#xff1a;https://detail.tmall.com/item.htm?id609294757420 3&#xff09;全套实验源码手册视频下载地址&#xff1a; http://www.openedv.com/thread-340252-1-1.html# 第五…

欧姆龙cp11以太网设置

捷米特JM-ETH-CP转以太网模块控&#xff0c;用于欧姆龙 CP1L/ CP1E/ CP1H 系列 PLC 的以太网数据采集&#xff0c;非常方便构建生产管理系统。 支持 FINS/UDP、FINS/TCP 以太网协议通信&#xff0c;支持上位机软件&#xff08;组态王、MCGS、力控、KepWare OPC 服务器等&#…

leetcode2373. 矩阵中的局部最大值

https://leetcode.cn/problems/largest-local-values-in-a-matrix/ 给你一个大小为 n x n 的整数矩阵 grid 。 生成一个大小为 (n - 2) x (n - 2) 的整数矩阵 maxLocal &#xff0c;并满足&#xff1a; maxLocal[i][j] 等于 grid 中以 i 1 行和 j 1 列为中心的 3 x 3 矩阵中…

【Android】报错java.lang.reflect.InvocationTargetException解决办法

报错信息&#xff1a;java.lang.reflect.InvocationTargetException反射层调用方法失败 结果图 原因 InvocationTargetException异常由Method.invoke(obj, args…)方法抛出。(反射异常) 当被调用的方法的内部抛出了异常而没有被捕获时&#xff0c;将由此异常接收&#xff01;&…

Stable Diffusion如何生成高质量的图-prompt写法介绍

文章目录 Stable Diffusion使用尝试下效果prompt的编写技巧prompt 和 negative promptPrompt格式Prompt规则细节优化Guidance Scale 总结 Stable Diffusion Stable Diffusion是一个开源的图像生成AI系统,由Anthropic公司开发。它基于 Transformer模型架构,可以通过文字描述生成…

查询每年最新的数据

1.最近在工作中遇到了一个需求,要求查询出每个党组织每年最新的数据 2.使用的sql语句为: SELECTCREATED_TIME,party_org_id,id FROMbranch_book WHERECREATED_TIME IN ( SELECT MAX( CREATED_TIME ) AS CREATED_TIME FROM branch_book GROUP BY DATE_FORMAT( year, %Y ), pa…

移动云发布医疗行业白皮书,构建全民健康数字化枢纽

医疗卫生改革正在深入推进&#xff0c;全民健康信息化建设也在加速进行。医疗云作为医疗卫生数字化转型的基础性平台&#xff0c;正引起越来越多的关注和探讨。近日&#xff0c;由中国移动集团政企事业部牵头发起&#xff0c;移动云联合IDC中国重磅发布《建设医疗云平台&#x…

Threejs——十四、关于深度冲突、重叠、以及加载模型进度条效果实现(附完整代码)

深度冲突 两个模型重叠的模型&#xff0c;通过浏览器旋转预览&#xff0c;会发现模型旋转的时候会发生闪烁。 这种情况&#xff0c;主要是两个模型重合&#xff0c;电脑分不清谁在前谁在后&#xff0c;这种情况&#xff0c;可以理解为深度冲突Z-fighting。 function addBox()…

Pytorch基本使用——NLP数据集构建总结

构建NLP数据集&#xff0c;分为如下几步&#xff1a; 1.单词分割形式 2.词汇表 3.利用词汇表word2idx映射&#xff0c;制作数据集 4.打包 ✨ 1.单词分割 有两种表示方式&#xff0c;一种是word-level&#xff0c;另外一种是char-level。 &#x1f30a; 1.1 word-level token…

可爱小猫猫【InsCode Stable Diffusion美图活动一期】

一、 Stable Diffusion 模型在线使用地址&#xff1a;https://inscode.csdn.net/inscode/Stable-Diffusion 二、模型版本及相关配置&#xff1a; 模型&#xff1a;chilloutmix_NiPrunedFp32fix Lora&#xff1a;cat_20230627113759 采样迭代步数&#xff08;steps&#xff09;:…

十三、前端包管理工具详解

一、代码共享方案 我们已经学习了在JavaScript中可以通过模块化的方式将代码划分成一个个小的结构&#xff1a; 在以后的开发中我们就可以通过模块化的方式来封装自己的代码&#xff0c;并且封装成一个工具&#xff1b; 这个工具我们可以让同事通过导入的方式来使用&#xf…

jetson系列开发板生成.engine部署

jetson系列开发板 生成engine 1. 下载 tensorrtx 至 NX git clone -b yolov5-v5.0 https://github.com/wang-xinyu/tensorrtx.git2. 修改 yololayer.h 中的参数 labels.txt 中有几类就将 CLASS_NUM 修改为几。 static constexpr int CLASS_NUM 80; 3. 编译 tensorrtx/yolov…

OLED拼接屏出现坏点怎么办?专家提供的修复方法与建议

OLED拼接屏作为一种高级显示技术&#xff0c;广泛应用于商业展示、会议室和监控中心等场所。 然而&#xff0c;由于制造过程中的缺陷或长时间使用导致的原因&#xff0c;OLED拼接屏可能出现屏幕坏点问题。本文将详细介绍OLED拼接屏屏幕坏点的修复方法与注意事项&#xff0c;帮…

高效编程:如何优雅地判断数组中所有对象的值不为空?

前言 在前端开发中&#xff0c;判断数组中所有对象的值是否都不为空是一个常见的任务。这个任务可能涉及到多个对象和多个属性&#xff0c;因此需要一种简洁而高效的方法来处理。本文将介绍三种不同的方法&#xff0c;帮助你轻松应对这个问题。 方法一&#xff1a;使用 every()…

原生js实现将图片内容复制到剪贴板

核心代码 /*复制图片*/ copyImg(dom) {/* 警告&#xff1a;dom不能是img标签&#xff0c;建议用DIV标签包裹img标签&#xff0c;否者会报错&#xff01;不支持复制背景图&#xff01; */dom.style.userSelect auto;let selection getSelection(), range document.createRan…

【AT89C52单片机项目】数字密码锁设计

实验目的 使用单片机设计数字密码锁。 实验仪器 一套STC89C52RC开发板套件&#xff0c;包括STC89C52RC开发板&#xff0c;以及USB烧录线。 设计要求 1、有设置密码、开锁工作模式&#xff1b; 2、可以每次都设置密码&#xff0c;也可以设置一次密码多次使用。 实验原理 …