单片机外围设备-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有几个特点需要关注: 1、可以单字节读写 2、eeprom按页划分存储,不同型号的eeprom的页大小不一致,往eeprom写数据时,如果写到了该页的末尾,会自动从该页的开头继续写,把之前的数据…...
YOLO--置信度(超详细解读)
YOLO(You Only Look Once)算法中的置信度(Confidence)是一个关键概念,用于评估模型对预测框内存在目标对象的信心程度以及预测框对目标对象位置的准确性。 一、置信度的定义 数值范围:置信度是一个介于0和…...
“解锁物流新纪元:深入探索‘沂路畅通‘分布式协作平台“
"解锁物流新纪元:深入探索沂路畅通分布式协作平台" 在21世纪的数字浪潮中,物流行业作为连接生产与消费的关键纽带,其重要性不言而喻。然而,随着市场规模的持续扩大和消费者需求的日益多样化,传统物流模式已…...
昇思25天学习打卡营第六天|应用实践/计算机视觉/Vision Transformer图像分类
心得 运行模型似乎有点靠天意?每次跑模型之前先来个焚香沐浴?总之今天是机器视觉的最后一课了,尽管课程里强调模型跑得慢,可是我的这次运行,居然很快的就看到结果了。 如果一直看我这个系列文章的小伙伴,…...
vxe-table合并行数据
场景: 混批名称相同合并混批名称,在混批名称相同条件下合并相同的混批类型;在混混批类型相同条件下合并相同的混批值;在混批值相同条件下合并相同的单位 实现根据四个不同的key值,当四个key值对应相等时,合…...
LabVIEW异步和同步通信详细分析及比较
1. 基本原理 异步通信: 原理:异步通信(Asynchronous Communication)是一种数据传输方式,其中数据发送和接收操作在独立的时间进行,不需要在特定时刻对齐。发送方在任何时刻可以发送数据,而接收…...
【多模态学习笔记二】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是一个开源的应用容器引擎,允许开发者将应用程序及其依赖项打包成一个轻量级、可移植的容器,然后发布到任何支持 Docker 的环境中运行,无论是开发机、测试机还是生产环境。 Docker基于…...
各类专业技术的pdf电子书
从业多年,收集了海量的pdf电子书籍,感兴趣的私聊。...
【Linux】多线程_9
文章目录 九、多线程10. 线程池 未完待续 九、多线程 10. 线程池 这里我没实现一些 懒汉单例模式 的线程池,并且包含 日志打印 的线程池: Makefile: threadpool:Main.ccg -o $ $^ -stdc11 -lpthread .PHONY:clean clean:rm -f threadpoolT…...
LabVIEW设备检修信息管理系统
开发了基于LabVIEW设计平台开发的设备检修信息管理系统。该系统应用于各种设备的检修基地,通过与基地管理信息系统的连接和数据交换,实现了本地检修工位数据的远程自动化管理,提高了设备的检修效率和安全性。 项目背景 现代设备运维过程中信…...
python爬虫基础:使用lxml库进行HTML解析和数据提取的实践指南
使用lxml库进行HTML解析和数据提取的实践指南 在Python编程中,网页抓取和数据提取是一项常见任务。lxml库因其高效性和强大的XPath支持,成为了处理HTML和XML文档的优选工具。本文将带你了解如何使用lxml来解析HTML文档并提取所需数据。 1. 安装lxml库 …...
大语言模型系列:Transformer
在自然语言处理(NLP)领域,Transformer模型自2017年由Vaswani等人在论文《Attention Is All You Need》中提出以来,已成为最具影响力的技术之一。这种模型设计的核心是自注意力机制,它允许模型在处理序列数据时…...
宠物健康新守护:智能听诊器引领科技突破
在宠物护理领域,一项令人瞩目的科技创新正逐渐兴起,那便是智能听诊器。这款革命性的设备以前所未有的准确性和便利性,为宠物主人提供了一种全新的健康监测体验。 只需将智能听诊器轻轻放置在爱宠的身上,它便立即开始工作…...
KITTI 3D 数据可视化
引言 KITTI 视觉基准测试套件(KITTI Vision Benchmark Suite)提供了大量用于理解自动驾驶场景的工具。尤其是3D数据可视化在分析和解释传感器(如激光雷达)与环境的复杂交互中起到了至关重要的作用。本文将详细探讨KITTI数据集中3…...
旅游数据可视化:免费工具让复杂数据变得简单易懂
随着旅游业的蓬勃发展,海量的数据如同繁星点点,记录着每一位旅者的足迹与偏好。然而,如何将这些复杂的数据转化为直观、易懂的信息,为旅游企业精准决策、为消费者提供更加个性化的服务,成为了行业内外共同关注的焦点。…...
数据结构进阶:使用链表实现栈和队列详解与示例(C, C#, C++)
文章目录 1、 栈与队列简介栈(Stack)队列(Queue) 2、使用链表实现栈C语言实现C#语言实现C语言实现 3、使用链表实现队列C语言实现C#语言实现C语言实现 4、链表实现栈和队列的性能分析时间复杂度空间复杂度性能特点与其他实现的比较…...
【线程系列之五】线程池介绍C语言
一、基本概念 1.1 概念 线程池(Thread Pool)是一种基于池化技术管理线程的机制,旨在减少线程创建和销毁的开销,提高系统资源的利用率,以及更好地控制系统中同时运行的线程数量。线程池通过预先创建一定数量的线程&am…...
【学习css3】使用flex和grid实现等高元素布局
过往的实现方法是使用浮动加计算布局来实现,当flex和grid问世时,这一切将变得简单起来 一、简单的两列实现 1、先看页面效果 2、css代码 .container {padding: 10px;width: 100ch;margin: 0 auto;box-shadow: inset 0 0 0 2px #ccc;}.column {margin: 2…...
如何防止Eclipse格式化程序在行注释开头插入空格
格式化前: //foo bar 格式化后: // foo bar 这种看着不是很舒服。如果不让格式化时自动在注释符后面插入空格呢? 要在Eclipse中进行代码格式化时防止在行注释(//)后面自动增加空格,可以通过调整…...
ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放
简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...
Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...
前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...
中医有效性探讨
文章目录 西医是如何发展到以生物化学为药理基础的现代医学?传统医学奠基期(远古 - 17 世纪)近代医学转型期(17 世纪 - 19 世纪末)现代医学成熟期(20世纪至今) 中医的源远流长和一脉相承远古至…...
2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)
安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...
uniapp 开发ios, xcode 提交app store connect 和 testflight内测
uniapp 中配置 配置manifest 文档:manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号:4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...
Qt 事件处理中 return 的深入解析
Qt 事件处理中 return 的深入解析 在 Qt 事件处理中,return 语句的使用是另一个关键概念,它与 event->accept()/event->ignore() 密切相关但作用不同。让我们详细分析一下它们之间的关系和工作原理。 核心区别:不同层级的事件处理 方…...
