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

单片机外围设备-EEPROM

eeprom用iic通信。eeprom有几个特点需要关注:

1、可以单字节读写

2、eeprom按页划分存储,不同型号的eeprom的页大小不一致,往eeprom写数据时,如果写到了该页的末尾,会自动从该页的开头继续写,把之前的数据覆盖,读则不会。

/** Copyright 2017 NXP* All rights reserved.** SPDX-License-Identifier: BSD-3-Clause*//*  Standard C Included Files */
#include <stdio.h>
#include <string.h>
#include "pin_mux.h"
#include "clock_config.h"
#include "board.h"
#include "fsl_debug_console.h"
#include "fsl_lpi2c.h"/******************************************************************************** Definitions******************************************************************************/
#define EEPROM_I2C_MASTER       (LPI2C3)
#define EEPROM_I2C_BAUD         (400000UL)/* Select USB1 PLL (480 MHz) as master lpi2c clock source */
#define LPI2C_CLOCK_SOURCE_SELECT (0U)
/* Clock divider for master lpi2c clock source */
#define LPI2C_CLOCK_SOURCE_DIVIDER (5U)
/* Get frequency of lpi2c clock */
#define LPI2C_CLOCK_FREQUENCY ((CLOCK_GetFreq(kCLOCK_Usb1PllClk) / 8) / (LPI2C_CLOCK_SOURCE_DIVIDER + 1U))
#define LPI2C_MASTER_CLOCK_FREQUENCY LPI2C_CLOCK_FREQUENCY#define AT24C256
#define EEPROM_PAGE_SIZE		64
#define EEPROM_SIZE				(32*1024)
#define EEPROM_ADDR_BYTES		2
#define EEPROM_WRITE_ADDRESS_8_BIT              (0xA2)
#define EEPROM_READ_ADDRESS_8_BIT               (0xA3)/******************************************************************************** Prototypes******************************************************************************//******************************************************************************** Variables******************************************************************************//******************************************************************************** code******************************************************************************/
void EepromDelayUs(uint32_t us)
{uint32_t tcnt;tcnt = us * (CLOCK_GetFreq(kCLOCK_CpuClk) / 1000000);while(tcnt--);
}/******************************************************************************** @brief  eeprom takes time to write data* @param  call after write data to eeprom* @retval
******************************************************************************/
uint8_t EepromWriteWait(uint8_t SlaveAddr8bit)
{status_t reVal = kStatus_Fail;uint32_t delay_count = 1000;do{/* �����Ӧ���־���Ա���һ�μ�� */LPI2C_MasterClearStatusFlags(EEPROM_I2C_MASTER, kLPI2C_MasterNackDetectFlag);/* ��EEPROM����д�����Ѱַ�źţ��Լ���Ƿ���Ӧ */reVal = LPI2C_MasterStart(EEPROM_I2C_MASTER, (SlaveAddr8bit>>1), kLPI2C_Write);/* ����ȴ�����30us���Ż������Ӧ���־*/EepromDelayUs(100);/* ���LPI2C MSR�Ĵ�����NDF��־������ȷ��delay_countû����0������0��Ϊ��ʱ���˳��� */}while(EEPROM_I2C_MASTER->MSR & kLPI2C_MasterNackDetectFlag && delay_count-- );/* �����Ӧ���־����ֹ��һ��ͨѶ���� */LPI2C_MasterClearStatusFlags(EEPROM_I2C_MASTER, kLPI2C_MasterNackDetectFlag);/* ����ֹͣ�źţ���ֹ�´�ͨѶ���� */reVal = LPI2C_MasterStop(EEPROM_I2C_MASTER);/* ����ȴ�����10us��ȷ��ֹͣ�źŷ������*/EepromDelayUs(100);/* ����ʧ�ܻ�ǰ��ĵȴ���ʱ */if(delay_count == 0 || reVal != kStatus_Success){return kStatus_Fail;}return kStatus_Success;
}/*!* @brief I2C Msater Init*/
void I2CMsaterInit(LPI2C_Type *base,uint32_t baud)
{status_t reVal                     = kStatus_Fail;/*Clock setting for LPI2C*/CLOCK_SetMux(kCLOCK_Lpi2cMux, LPI2C_CLOCK_SOURCE_SELECT);CLOCK_SetDiv(kCLOCK_Lpi2cDiv, LPI2C_CLOCK_SOURCE_DIVIDER);lpi2c_master_config_t masterConfig;/** masterConfig.debugEnable = false;* masterConfig.ignoreAck = false;* masterConfig.pinConfig = kLPI2C_2PinOpenDrain;* masterConfig.baudRate_Hz = 100000U;* masterConfig.busIdleTimeout_ns = 0;* masterConfig.pinLowTimeout_ns = 0;* masterConfig.sdaGlitchFilterWidth_ns = 0;* masterConfig.sclGlitchFilterWidth_ns = 0;*/LPI2C_MasterGetDefaultConfig(&masterConfig);/* Change the default baudrate configuration */masterConfig.baudRate_Hz = baud;/* Initialize the LPI2C master peripheral */LPI2C_MasterInit(base, &masterConfig, LPI2C_MASTER_CLOCK_FREQUENCY);
}/*
subaddressSize is 2
*/
int32_t I2CMsaterWriteData(uint8_t SlaveAddr8bit, uint16_t WriteAddr, uint8_t* pBuffer,uint16_t DataSize)
{int32_t reVal;lpi2c_master_transfer_t masterXfer = {0};masterXfer.slaveAddress   = (SlaveAddr8bit>>1);masterXfer.direction      = kLPI2C_Write;masterXfer.subaddress     = (uint32_t)WriteAddr;masterXfer.subaddressSize = EEPROM_ADDR_BYTES;masterXfer.data           = pBuffer;masterXfer.dataSize       = DataSize;masterXfer.flags          = kLPI2C_TransferDefaultFlag;/* Send master non-blocking data to slave */reVal = LPI2C_MasterTransferBlocking(EEPROM_I2C_MASTER, &masterXfer);if (reVal != kStatus_Success){return -1;}return 0;
}/*
subaddressSize is 2
*/
int32_t I2CMsaterReadData(uint8_t SlaveAddr8bit, uint16_t readAddr, uint8_t* pBuffer,uint16_t DataSize)
{int32_t reVal;lpi2c_master_transfer_t masterXfer = {0};/* start + slaveaddress(w) + subAddress + repeated start + slaveaddress(r) + rx data buffer + stop */masterXfer.slaveAddress   = (SlaveAddr8bit>>1);masterXfer.direction      = kLPI2C_Read;masterXfer.subaddress     = (uint32_t)readAddr;masterXfer.subaddressSize = EEPROM_ADDR_BYTES;masterXfer.data           = pBuffer;masterXfer.dataSize       = DataSize;masterXfer.flags          = kLPI2C_TransferDefaultFlag;reVal = LPI2C_MasterTransferBlocking(EEPROM_I2C_MASTER, &masterXfer);if (reVal != kStatus_Success){return -1;}return 0;
}/*******************************************************************************
when NumByteToWrite > EEPROM_PAGE_SIZE ,it will go back to the start address of the page and write continuely
******************************************************************************/
int32_t EepromWriteData(uint8_t SlaveAddr8bit, uint16_t WriteAddr, uint8_t* pBuffer, uint16_t NumByteToWrite)
{status_t reVal = kStatus_Fail;uint16_t firstPageBytes,otherPageBytes,otherPageNum,lastPageBytes;firstPageBytes = EEPROM_PAGE_SIZE - (WriteAddr % EEPROM_PAGE_SIZE);otherPageBytes = (NumByteToWrite > firstPageBytes) ? (NumByteToWrite - firstPageBytes) : 0;if (otherPageBytes==0){reVal = I2CMsaterWriteData(SlaveAddr8bit, WriteAddr, pBuffer, NumByteToWrite);if (reVal != kStatus_Success){return kStatus_Fail;}EepromWriteWait(SlaveAddr8bit);}else{otherPageNum =  otherPageBytes / EEPROM_PAGE_SIZE;lastPageBytes = otherPageBytes % EEPROM_PAGE_SIZE;//write first pagereVal = I2CMsaterWriteData(SlaveAddr8bit, WriteAddr, pBuffer, firstPageBytes);if (reVal != kStatus_Success){return kStatus_Fail;}EepromWriteWait(SlaveAddr8bit);WriteAddr += firstPageBytes;pBuffer += firstPageBytes;if(otherPageNum== 0 ){reVal = I2CMsaterWriteData(SlaveAddr8bit, WriteAddr, pBuffer, lastPageBytes);if (reVal != kStatus_Success){return kStatus_Fail;}EepromWriteWait(SlaveAddr8bit);}else{while(otherPageNum--){reVal = I2CMsaterWriteData(SlaveAddr8bit, WriteAddr, pBuffer, EEPROM_PAGE_SIZE);if (reVal != kStatus_Success){return kStatus_Fail;}EepromWriteWait(SlaveAddr8bit);WriteAddr +=  EEPROM_PAGE_SIZE;pBuffer += EEPROM_PAGE_SIZE;}if(lastPageBytes != 0){reVal = I2CMsaterWriteData(SlaveAddr8bit, WriteAddr, pBuffer, lastPageBytes);if (reVal != kStatus_Success){return kStatus_Fail;}EepromWriteWait(SlaveAddr8bit);}}}return kStatus_Success;
}#define BUFF_SIZE 255
uint8_t TxBuffer1[BUFF_SIZE];
uint8_t RxBuffer1[BUFF_SIZE];
void EerpromTest(void)
{uint16_t i,cnt;cnt = sizeof(TxBuffer1)/sizeof(TxBuffer1[0]);for(i=0;i<cnt;i++){*(TxBuffer1+i) = i;}//test write 1 pageI2CMsaterWriteData(EEPROM_WRITE_ADDRESS_8_BIT,2,TxBuffer1,cnt);EepromWriteWait(EEPROM_WRITE_ADDRESS_8_BIT);I2CMsaterReadData(EEPROM_READ_ADDRESS_8_BIT,0,RxBuffer1,cnt);//test write more than 1 pageEepromWriteData(EEPROM_WRITE_ADDRESS_8_BIT,0,TxBuffer1,cnt);I2CMsaterReadData(EEPROM_READ_ADDRESS_8_BIT,0,RxBuffer1,cnt);
}

相关文章:

单片机外围设备-EEPROM

eeprom用iic通信。eeprom有几个特点需要关注&#xff1a; 1、可以单字节读写 2、eeprom按页划分存储&#xff0c;不同型号的eeprom的页大小不一致&#xff0c;往eeprom写数据时&#xff0c;如果写到了该页的末尾&#xff0c;会自动从该页的开头继续写&#xff0c;把之前的数据…...

YOLO--置信度(超详细解读)

YOLO&#xff08;You Only Look Once&#xff09;算法中的置信度&#xff08;Confidence&#xff09;是一个关键概念&#xff0c;用于评估模型对预测框内存在目标对象的信心程度以及预测框对目标对象位置的准确性。 一、置信度的定义 数值范围&#xff1a;置信度是一个介于0和…...

“解锁物流新纪元:深入探索‘沂路畅通‘分布式协作平台“

"解锁物流新纪元&#xff1a;深入探索沂路畅通分布式协作平台" 在21世纪的数字浪潮中&#xff0c;物流行业作为连接生产与消费的关键纽带&#xff0c;其重要性不言而喻。然而&#xff0c;随着市场规模的持续扩大和消费者需求的日益多样化&#xff0c;传统物流模式已…...

昇思25天学习打卡营第六天|应用实践/计算机视觉/Vision Transformer图像分类

心得 运行模型似乎有点靠天意&#xff1f;每次跑模型之前先来个焚香沐浴&#xff1f;总之今天是机器视觉的最后一课了&#xff0c;尽管课程里强调模型跑得慢&#xff0c;可是我的这次运行&#xff0c;居然很快的就看到结果了。 如果一直看我这个系列文章的小伙伴&#xff0c;…...

vxe-table合并行数据

场景&#xff1a; 混批名称相同合并混批名称&#xff0c;在混批名称相同条件下合并相同的混批类型&#xff1b;在混混批类型相同条件下合并相同的混批值&#xff1b;在混批值相同条件下合并相同的单位 实现根据四个不同的key值&#xff0c;当四个key值对应相等时&#xff0c;合…...

LabVIEW异步和同步通信详细分析及比较

1. 基本原理 异步通信&#xff1a; 原理&#xff1a;异步通信&#xff08;Asynchronous Communication&#xff09;是一种数据传输方式&#xff0c;其中数据发送和接收操作在独立的时间进行&#xff0c;不需要在特定时刻对齐。发送方在任何时刻可以发送数据&#xff0c;而接收…...

【多模态学习笔记二】MINIGPT-4论文阅读

MINIGPT-4:ENHANCING VISION-LANGUAGE UNDERSTANDING WITH ADVANCED LARGE LANGUAGE MODELS 提出的MiniGPT-4使用一个投影层,将冻结的视觉编码器与冻结的先进的LLM Vicuna对齐。我们的工作首次揭示,将视觉特征与先进的大型语言模型正确对齐可以具有GPT-4所展示的许多先进的多…...

Docker基本讲解及演示

Docker安装教程 Docker安装教程 1、Docker介绍 Docker是一个开源的应用容器引擎&#xff0c;允许开发者将应用程序及其依赖项打包成一个轻量级、可移植的容器&#xff0c;然后发布到任何支持 Docker 的环境中运行&#xff0c;无论是开发机、测试机还是生产环境。 Docker基于…...

各类专业技术的pdf电子书

从业多年&#xff0c;收集了海量的pdf电子书籍&#xff0c;感兴趣的私聊。...

【Linux】多线程_9

文章目录 九、多线程10. 线程池 未完待续 九、多线程 10. 线程池 这里我没实现一些 懒汉单例模式 的线程池&#xff0c;并且包含 日志打印 的线程池&#xff1a; Makefile&#xff1a; threadpool:Main.ccg -o $ $^ -stdc11 -lpthread .PHONY:clean clean:rm -f threadpoolT…...

LabVIEW设备检修信息管理系统

开发了基于LabVIEW设计平台开发的设备检修信息管理系统。该系统应用于各种设备的检修基地&#xff0c;通过与基地管理信息系统的连接和数据交换&#xff0c;实现了本地检修工位数据的远程自动化管理&#xff0c;提高了设备的检修效率和安全性。 项目背景 现代设备运维过程中信…...

python爬虫基础:使用lxml库进行HTML解析和数据提取的实践指南

使用lxml库进行HTML解析和数据提取的实践指南 在Python编程中&#xff0c;网页抓取和数据提取是一项常见任务。lxml库因其高效性和强大的XPath支持&#xff0c;成为了处理HTML和XML文档的优选工具。本文将带你了解如何使用lxml来解析HTML文档并提取所需数据。 1. 安装lxml库 …...

大语言模型系列:Transformer

在自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;Transformer模型自2017年由Vaswani等人在论文《Attention Is All You Need》中提出以来&#xff0c;已成为最具影响力的技术之一。这种模型设计的核心是自注意力机制&#xff0c;它允许模型在处理序列数据时&#xf…...

宠物健康新守护:智能听诊器引领科技突破

在宠物护理领域&#xff0c;一项令人瞩目的科技创新正逐渐兴起&#xff0c;那便是智能听诊器。这款革命性的设备以前所未有的准确性和便利性&#xff0c;为宠物主人提供了一种全新的健康监测体验。 只需将智能听诊器轻轻放置在爱宠的身上&#xff0c;它便立即开始工作&#xf…...

KITTI 3D 数据可视化

引言 KITTI 视觉基准测试套件&#xff08;KITTI Vision Benchmark Suite&#xff09;提供了大量用于理解自动驾驶场景的工具。尤其是3D数据可视化在分析和解释传感器&#xff08;如激光雷达&#xff09;与环境的复杂交互中起到了至关重要的作用。本文将详细探讨KITTI数据集中3…...

旅游数据可视化:免费工具让复杂数据变得简单易懂

随着旅游业的蓬勃发展&#xff0c;海量的数据如同繁星点点&#xff0c;记录着每一位旅者的足迹与偏好。然而&#xff0c;如何将这些复杂的数据转化为直观、易懂的信息&#xff0c;为旅游企业精准决策、为消费者提供更加个性化的服务&#xff0c;成为了行业内外共同关注的焦点。…...

数据结构进阶:使用链表实现栈和队列详解与示例(C, C#, C++)

文章目录 1、 栈与队列简介栈&#xff08;Stack&#xff09;队列&#xff08;Queue&#xff09; 2、使用链表实现栈C语言实现C#语言实现C语言实现 3、使用链表实现队列C语言实现C#语言实现C语言实现 4、链表实现栈和队列的性能分析时间复杂度空间复杂度性能特点与其他实现的比较…...

【线程系列之五】线程池介绍C语言

一、基本概念 1.1 概念 线程池&#xff08;Thread Pool&#xff09;是一种基于池化技术管理线程的机制&#xff0c;旨在减少线程创建和销毁的开销&#xff0c;提高系统资源的利用率&#xff0c;以及更好地控制系统中同时运行的线程数量。线程池通过预先创建一定数量的线程&am…...

【学习css3】使用flex和grid实现等高元素布局

过往的实现方法是使用浮动加计算布局来实现&#xff0c;当flex和grid问世时&#xff0c;这一切将变得简单起来 一、简单的两列实现 1、先看页面效果 2、css代码 .container {padding: 10px;width: 100ch;margin: 0 auto;box-shadow: inset 0 0 0 2px #ccc;}.column {margin: 2…...

如何防止Eclipse格式化程序在行注释开头插入空格

格式化前&#xff1a; //foo bar 格式化后&#xff1a; // foo bar 这种看着不是很舒服。如果不让格式化时自动在注释符后面插入空格呢&#xff1f; 要在Eclipse中进行代码格式化时防止在行注释&#xff08;‌//&#xff09;‌后面自动增加空格&#xff0c;‌可以通过调整…...

大话软工笔记—需求分析概述

需求分析&#xff0c;就是要对需求调研收集到的资料信息逐个地进行拆分、研究&#xff0c;从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要&#xff0c;后续设计的依据主要来自于需求分析的成果&#xff0c;包括: 项目的目的…...

python报错No module named ‘tensorflow.keras‘

是由于不同版本的tensorflow下的keras所在的路径不同&#xff0c;结合所安装的tensorflow的目录结构修改from语句即可。 原语句&#xff1a; from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后&#xff1a; from tensorflow.python.keras.lay…...

JAVA后端开发——多租户

数据隔离是多租户系统中的核心概念&#xff0c;确保一个租户&#xff08;在这个系统中可能是一个公司或一个独立的客户&#xff09;的数据对其他租户是不可见的。在 RuoYi 框架&#xff08;您当前项目所使用的基础框架&#xff09;中&#xff0c;这通常是通过在数据表中增加一个…...

NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合

在汽车智能化的汹涌浪潮中&#xff0c;车辆不再仅仅是传统的交通工具&#xff0c;而是逐步演变为高度智能的移动终端。这一转变的核心支撑&#xff0c;来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒&#xff08;T-Box&#xff09;方案&#xff1a;NXP S32K146 与…...

scikit-learn机器学习

# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...

pgsql:还原数据库后出现重复序列导致“more than one owned sequence found“报错问题的解决

问题&#xff1a; pgsql数据库通过备份数据库文件进行还原时&#xff0c;如果表中有自增序列&#xff0c;还原后可能会出现重复的序列&#xff0c;此时若向表中插入新行时会出现“more than one owned sequence found”的报错提示。 点击菜单“其它”-》“序列”&#xff0c;…...

小智AI+MCP

什么是小智AI和MCP 如果还不清楚的先看往期文章 手搓小智AI聊天机器人 MCP 深度解析&#xff1a;AI 的USB接口 如何使用小智MCP 1.刷支持mcp的小智固件 2.下载官方MCP的示例代码 Github&#xff1a;https://github.com/78/mcp-calculator 安这个步骤执行 其中MCP_ENDPOI…...

简单介绍C++中 string与wstring

在C中&#xff0c;string和wstring是两种用于处理不同字符编码的字符串类型&#xff0c;分别基于char和wchar_t字符类型。以下是它们的详细说明和对比&#xff1a; 1. 基础定义 string 类型&#xff1a;std::string 字符类型&#xff1a;char&#xff08;通常为8位&#xff09…...

项目进度管理软件是什么?项目进度管理软件有哪些核心功能?

无论是建筑施工、软件开发&#xff0c;还是市场营销活动&#xff0c;项目往往涉及多个团队、大量资源和严格的时间表。如果没有一个系统化的工具来跟踪和管理这些元素&#xff0c;项目很容易陷入混乱&#xff0c;导致进度延误、成本超支&#xff0c;甚至失败。 项目进度管理软…...

Spring是如何实现无代理对象的循环依赖

无代理对象的循环依赖 什么是循环依赖解决方案实现方式测试验证 引入代理对象的影响创建代理对象问题分析 源码见&#xff1a;mini-spring 什么是循环依赖 循环依赖是指在对象创建过程中&#xff0c;两个或多个对象相互依赖&#xff0c;导致创建过程陷入死循环。以下通过一个简…...