FPGA驱动24C04实现读写操作,提供工程源码和技术支持

news2024/11/25 4:39:31

目录

  • 1.24c04芯片手册解读
  • 2.纯verilog的i2c驱动
  • 3.24c04读写状态机设计
  • 4.上板调试验证
  • 5.福利:工程源码获取

1.24c04芯片手册解读

24c04芯片手册很简单,原理图设计页很简单,这里只说代码设计需要注意的点:
1、写操作延时周期大于等于2ms,如下:
在这里插入图片描述
这个其实也很好理解,这毕竟是写一次数据就可以保存200年的东西,你写操作难道不应该多花点时间让期间“固化”完毕吗?
具体在代码层面如何体现呢?
那就是写完一次数据后要求等待至少2ms后才能发起下一次写操作,本设计采用延时4ms的稳妥方案;
2、器件地址,如下:
在这里插入图片描述
常规操作,3个地址引脚的电平决定器件地址,我的板子原理图如下:
在这里插入图片描述
所以器件地址就是7’b1010000;也就是0xa0;
3、穿行时钟,如下:
在这里插入图片描述
100k到400k,用100k最保险,宜小不宜大;本设计也是用的100k;

2.纯verilog的i2c驱动

详细代码不在这里给出,因为粘贴出来会很长,影响阅读体验,私我可得源码慢慢欣赏;
下面给出i2c驱动的顶层接口说明:


rst               //高电平复位
clk               //输入系统时钟
clk_div_cnt       //i2c_scl分配系数:clk_div_cnt=clk/(5*i2c_scl)-1
scl_pad_i         // SCL-line input
scl_pad_o         // SCL-line output (always 1'b0)
scl_padoen_o      // SCL-line output enable (active low)                           
sda_pad_i         // SDA-line input
sda_pad_o         // SDA-line output (always 1'b0)
sda_padoen_o      // SDA-line output enable (active low)
i2c_addr_2byte    // 地址位宽选择:1-->16bit ? 0-->8bit
i2c_read_req      // 发起读操作,高电平有效
i2c_read_req_ack  // 读操作完成反馈高脉冲信号
i2c_write_req     // 发写读操作,高电平有效
i2c_write_req_ack // 写操作完成反馈高脉冲信号
i2c_slave_dev_addr// I2c device address
i2c_slave_reg_addr// I2c register address
i2c_write_data    // I2c write register data
i2c_read_data     // I2c read register data
error             // 读写错误反馈信号

3.24c04读写状态机设计

设计很简单,分为一下几步:
1:上电等待250ms,让24c04准备好;
2:发起一次写操作,并给出写地址和写数据;
3:完成写操作后,写地址和写数据累加,并循环写255次;
4:写完255个数据后,发起读操作,并给出读地址;
5:完成读操作后,读地址累加,并循环读255次;
6:读完255个数据后,再从第一步开始循环;
状态机部分代码如下:

always @(posedge clk) begin
	if(~rstn) begin
		ST                <='d0;
		i2c_read_req      <='d0;
		i2c_write_req     <='d0;
		i2c_slave_reg_addr<='d0;
		w_slave_reg_addr  <='d0;
		r_slave_reg_addr  <='d0;
		i2c_write_data    <='d0;
		write_data_cnt    <='d0;
		read_data_cnt     <='d0;
		r_i2c_write_data  <='d0;
		e2p_cnt           <='d0;
	end
	else begin
		case(ST)
			'd0: begin
				if(e2p_cnt==E2P_DELAY) begin	//上电后延时250ms,让24c04准备好
					ST<='d1;
					e2p_cnt<='d0;
				end
				else e2p_cnt<=e2p_cnt+'d1;
			end
			'd1: begin	
				if(i2c_write_req_ack) begin		//写操作完成,进入等待写周期和地址、数据累加
					i2c_write_req<='d0;
					ST<='d2;
				end
				else begin
					i2c_write_req<='d1;						//发起写操作
					i2c_write_data<=r_i2c_write_data;		//给出写数据
					i2c_slave_reg_addr<=w_slave_reg_addr;	//给出写地址
				end
			end
			'd2: begin	
				if(write_data_cnt=='d255) begin		//写满255个数据后进入读数据状态
					write_data_cnt    <='d0;
					i2c_write_data    <='d0;
					r_i2c_write_data  <='d0;
					w_slave_reg_addr  <='d0;
					i2c_slave_reg_addr<='d0;
					ST<='d4;
				end
				else begin
					if(wr_delay==WR_CYCEL) begin	//延时4ms写周期,写数据和地址累加
						write_data_cnt  <=write_data_cnt+'d1;
						r_i2c_write_data<=r_i2c_write_data+'d1;
						w_slave_reg_addr<=w_slave_reg_addr+'d1;	
						ST<='d3;
					end
				end
			end
			'd3: ST<='d1;	//打一排再循环写,保证写数据和地址在发起写操作前已经更新
			'd4: begin	
				if(i2c_read_req_ack) begin
					i2c_read_req<='d0;
					ST<='d5;
				end
				else begin
					i2c_read_req<='d1;						//发起读操作
					i2c_slave_reg_addr<=r_slave_reg_addr;	//给出读地址
				end					
			end
			'd5: begin	
				if(read_data_cnt=='d255) begin	//读完255个数据后重新开始状态机
					read_data_cnt  <='d0;
					r_slave_reg_addr<='d0;
					i2c_slave_reg_addr<='d0;
					ST<='d0;
				end
				else begin
					read_data_cnt  <=read_data_cnt+'d1;			
					r_slave_reg_addr  <=r_slave_reg_addr+'d1;	//读地址累加
				    ST<='d6;
				end
			end	
			'd6: ST<='d4;
			default: ST<='d0;
		endcase
	end
end

4.上板调试验证

开发板:Xilinx Artix7-35T开发板;
开发环境:vivado2019.1;
ila抓取波形如下:
写操作:
随机抓取写地址为100的波形,此时写地址为100,写数据也应该为100;抓取结果如下:
在这里插入图片描述
再抓读地址为100时的波形,此时读数据也应该是100才对,抓取结果如下:
在这里插入图片描述
可以看到,当读反馈信号i2c_read_req_ack为高时,地址为100,读数据也为100;
我们的读写完全正确。。。

5.福利:工程源码获取

福利:工程代码的获取
代码太大,无法邮箱发送,以某度网盘链接方式发送,
资料如下:获取方式:私。
在这里插入图片描述

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

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

相关文章

嵌入式软件工程师技能树——Linux应用编程+网络编程+驱动开发+操作系统+计算机网络

文章目录Linux驱动开发1、Linux内核组成2、用户空间与内核的通讯方式有哪些&#xff1f;3、系统调用read/write流程4、内核态用户态的区别5、bootloader内核 根文件的关系6、BootLoader的作用7、BootLoader两个启动阶段1、汇编实现&#xff0c;完成依赖于CPU体系架构的设置&…

推荐系统学习笔记--推荐系统简介

由来 互联网的出现和普及给用户带来了大量的信息&#xff0c;满足了用户在信息时代对信息的需求&#xff0c;但随着网络的迅速发展而带来的网上信息量的大幅增长&#xff0c;使得用户在面对大量信息时无法从中获得对自己真正有用的那部分信息&#xff0c;对信息的使用效率反而…

前三季度净亏损8.01亿元,亿咖通海外上市背后的「吉利阴影」

中国智能汽车产业链供应商正在通过SPAC方式在海外上市&#xff0c;或将成为新一轮资本浪潮的焦点。这些企业大多数已经具备一定规模&#xff0c;但仍处于亏损状态。 11月21日&#xff0c;亿咖通&#xff08;ECARX Holdings, Inc.&#xff09;宣布&#xff0c;之前与COVA Acqui…

Windows Terminal 快速配置 oh-my-posh

背景 想美化下windows terminal &#xff0c;选择了oh-my-posh。网上的文章有点多&#xff0c;加上官方的教程对初次使用着并不是太友好&#xff0c;所以自己快速摸索了。记录下过程。 步骤 1&#xff0c;安装oh-my-posh 打开以下链接&#xff0c;安装oh-my-posh Windows …

一个进程只能最多创建2000个线程吗?

我经常听到有人说&#xff0c;为什么不能创建一个包含2000个线程的进程。 原因不是Windows中固有的任何特定限制。相反&#xff0c;程序员没有考虑每个线程使用的地址空间量。 线程由内核模式下的一些内存&#xff08;内核堆栈和对象管理&#xff09;和用户模式下的一些内存&…

互动抽奖背后的随机性与算法实现

背景抽奖&#xff0c;是一种典型的互动玩法形式。无论是大V的粉丝抽奖&#xff0c;还是活动会场的参与抽奖&#xff0c;这种起源于彩票开奖的互动玩法&#xff0c;同时兼顾了高期待感和低预期的特征&#xff0c;让活动在成本控制之余又能有惊喜和引爆点&#xff0c;这样的优势让…

java毕业设计——基于java+Socket+sqlserver的远程监控系统软件设计与实现(毕业论文+程序源码)——远程监控系统

基于javaSocketsqlserver的远程监控系统软件设计与实现&#xff08;毕业论文程序源码&#xff09; 大家好&#xff0c;今天给大家介绍基于javaSocketsqlserver的远程监控系统软件设计与实现&#xff0c;文章末尾附有本毕业设计的论文和源码下载地址哦。 文章目录&#xff1a;…

安全智能分析技术 思路方案

思路方案 在安全领域的研究中我们发现&#xff0c;很多数据预处理的步骤&#xff0c;在不同的场景下中都可以相互 借鉴&#xff0c;甚至可以进行直接复用。例如&#xff0c;对于加密流量相关的数据&#xff0c;当算法工程师 获取到一批加密流量的 pcap 包之后&#xff0c;不论他…

【Linux学习】之将输出重定向到文件或程序

将输出重定向到文件或程序 文章目录将输出重定向到文件或程序1. 标准输入、标准输出和标准错误2. 输出重定向操作符2.1 用法及说明2.2 合并重定向运算符2.3 输出重定向示例2.4 输出重定向实例23. 构建管道3.1 含义3.2 管道示例1. 标准输入、标准输出和标准错误 进程使用称为文…

Ac-IYGEF-NH2,168781-78-0

Ac-IYGEF-amide, excellent small peptide substrate for the protein tyrosine kinase pp60c-src (Km 368 M and Vmax 1.02 mol min⁻ mg⁻). Ac-IYGEF-amide&#xff0c;蛋白酪氨酸激酶pp60c-src的优秀小肽底物(Km 368 μ M, Vmax 1.02 μ mol minmg)。 编号: 150669中文名称…

新冠“阳”后嗓子疼到只能喝粥?千万别错过这几条加速康复建议

你一定很熟悉这张传遍朋友圈的小照片。你周围的亲戚、朋友、同事&#xff0c;甚至你自己&#xff0c;可能已经变成了前几批“小阳人”&#xff0c;正在体验传说中的高热、肌痛、头痛、喉咙痛、持续咳嗽、食物不振、味觉和嗅觉丧失。此时此刻&#xff0c;每个人都想增加身体的战…

学习python技术难吗?

现如今Python这门语言的就业前景会非常好。相对于其他来说&#xff0c;它语法简单易读&#xff0c;消除了初学者对于“编程”这一行为的恐惧&#xff0c;让越来越多的非科班有信心开始通过编写简单的程序&#xff0c;究竟学习python技术难吗&#xff1f;关键在于你多注意小编这…

oracle学习篇(三)

oracle学习篇(三) 1 oracle伪列 1.1 查询rowid 1.1.1 示例代码 -- rowid 行id 添加时就生成了(删除某一列时,id会更随着一起删除,id在添加的时候就固定死了) SELECT rowid,e.* FROM emp e1.1.2 运行截图 1.2 查询rownum 1.2.1 示例代码 -- rownum 行号 查询时根据行数产生…

Jmeter(十六):jmeter场景的运行架构(本地运行和远程运行)配置远程负载机

jmeter场景的运行架构(本地运行和远程运行) 运行方式&#xff1a; GUI运行&#xff1a;通过图形界面方式运行&#xff0c;该运行方式的可视化界面及监听器动态展示 结果都比较消耗负载机资源&#xff0c;建议大并发时不用&#xff0c;一般进行脚本调试&#xff1b; 命令行运行…

LeetCode刷题复盘笔记—一文搞懂动态规划之188. 买卖股票的最佳时机 IV问题(动态规划系列第二十三篇)

今日主要总结一下动态规划的一道题目&#xff0c;188. 买卖股票的最佳时机 IV 题目&#xff1a;188. 买卖股票的最佳时机 IV Leetcode题目地址 题目描述&#xff1a; 给定一个整数数组 prices &#xff0c;它的第 i 个元素 prices[i] 是一支给定的股票在第 i 天的价格。 设计…

带有匹配滤波器的雷达信号调制和脉冲压缩Matlab仿真

up目录 一、理论基础 二、核心程序 三、测试结果 一、理论基础 匹配滤波器&#xff1a; 匹配滤波器是输出端的信号瞬时功率与噪声平均功率的比值最大的线性滤波器也就是说有最大的信噪比。其滤波器的传递函数形式是信号频谱的共轭。在通信系统中&#xff0c;滤波器是其中重…

Selenium3自动化测试【40】Html测试报告

&#x1f4cc; 博客主页&#xff1a; 程序员二黑 &#x1f4cc; 专注于软件测试领域相关技术实践和思考&#xff0c;持续分享自动化软件测试开发干货知识&#xff01; &#x1f4cc; 公号同名&#xff0c;欢迎加入我的测试交流群&#xff0c;我们一起交流学习&#xff01; 目录…

Aspartic acid-PEG-BSA 天冬氨酸-聚乙二醇-牛血清白蛋白

产品名称&#xff1a;天冬氨酸-聚乙二醇-牛血清白蛋白 英文名称&#xff1a;Aspartic acid-PEG-BSA 纯度&#xff1a;95% 存储条件&#xff1a;-20C&#xff0c;避光&#xff0c;避湿 外观:固体或粘性液体&#xff0c;取决于分子量 PEG分子量可选&#xff1a;350、550、750、1k…

Android Kotlin使用APT手写ButterKnife

前言 ButterKnife通过使用BindView注解就可以完成findViewById工作&#xff0c;它的实现原理其实也很简单&#xff0c;通过APT&#xff08;Annotation Processing Too,注解解析器&#xff09;技术&#xff0c;在编译期为我们生成了一个绑定类&#xff0c;而从完成了View的绑定…

OpenAI掌门人Sam Altman:AI的下一个发展阶段

来源&#xff5c;Greylock OneFlow社区编译 翻译&#xff5c;胡燕君、贾川 预告了一整年的GPT-4迟迟没来&#xff0c;人们猜想OpenAI是不是要跳票了&#xff0c;更何况他们之前的得意之作DALL-E也被开源Stable Diffusion打了个措手不及&#xff0c;再不来点深水炸弹业界地位危矣…