在FPGA中使用Verilog实现I2C通信

2023-05-16

按照I2C标准的官方时序

FPGA之I2C的实现
可以看出时序看起来很简单,不过它严格的按照时序要求来传送数据,马虎不得的,特别是起始和停止的条件,起始必须要时钟线SCL为高电平时数据线SDA拉低;而停止时必须要时钟线SCL为高电平时数据线SDA拉高;中间的数据的每一位传送都是必须要求在时钟线SCL为高定平时完成;

Verilog HDL程序采用基于状态机的时序设计实现,I2C速度为100KHz,本人开发板的晶振20Mhz。代码有点长,就截取状态机部分好了

`define DEVICE_WRITE 8'b1010_1010 //the data;
reg[7:0] db_r;  


parameter  IDLE  = 4'd0;
parameter  START1  = 4'd1;
parameter  DATA  = 4'd2;
parameter  ACK1  = 4'd3;
parameter  STOP1  = 4'd11;
parameter  STOP2  = 4'd12;

reg[3:0] cstate; 
reg sda_r;  
reg sda_link;  
reg[3:0] num; 


always @ (posedge clk or negedge rst_n) begin
 if(!rst_n) begin
   cstate <= IDLE;
   sda_r <= 1'b1;  
   sda_link <= 1'b0;  //input
   num <= 4'd0;
  end
 else   
  case (cstate)
   IDLE: begin
      sda_link <= 1'b1;   //output
      sda_r <= 1'b1; 
      db_r <= `DEVICE_WRITE; 
      cstate <= START1;  
     end
   START1: begin
     if(`SCL_HIG) begin  
      sda_r <= 1'b0;  
      cstate <= DATA;
      num <= 4'd0;  
      end
     else cstate <= START1;
    end
   DATA: begin
     if(`SCL_LOW) begin
       if(num == 4'd8) begin 
         num <= 4'd0;   
         sda_r <= 1'b1;
         sda_link <= 1'b0;  //(input)
         cstate <= ACK1;
        end
       else begin
         cstate <= DATA;
         num <= num+1'b1;
         case (num)
          4'd0: sda_r <= db_r[7];
          4'd1: sda_r <= db_r[6];
          4'd2: sda_r <= db_r[5];
          4'd3: sda_r <= db_r[4];
          4'd4: sda_r <= db_r[3];
          4'd5: sda_r <= db_r[2];
          4'd6: sda_r <= db_r[1];
          4'd7: sda_r <= db_r[0];
          default: ;
         endcase
        end
      end
     else cstate <= DATA;
    end
   ACK1: begin
     if(`SCL_NEG) begin 
       cstate <= STOP1;   
      end
     else cstate <= ACK1;  
    end
   STOP1: begin
     if(`SCL_LOW) begin
       sda_link <= 1'b1;
       sda_r <= 1'b0;
       cstate <= STOP1;
      end
     else if(`SCL_HIG) begin
       sda_r <= 1'b1; 
       cstate <= STOP2;
      end
     else cstate <= STOP1;
    end
   STOP2: begin
     if(`SCL_LOW) sda_r <= 1'b1;
     else if(cnt_20ms==20'hffff0) cstate <= IDLE;
     else cstate <= STOP2;
    end
   default: cstate <= IDLE;
   endcase
end

assign sda = sda_link ? sda_r:1'bz;

经过综合,给激励源并仿真后截图

FPGA之I2C的实现

可以看出,时序完全正确,还要注意的就是传完8位数据之后读取的响应位ACK;

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

在FPGA中使用Verilog实现I2C通信 的相关文章

  • 如何生成异步复位verilog总是阻塞凿子

    Chisel 始终生成敏感度列表中仅包含时钟的块 always posedge clk begin end 是否可以将模块配置为使用异步重置并生成这样的始终块 always posedge clk or posedge reset begi
  • docker 容器内的 I2C

    我正在尝试在 docker 容器内的树莓派上使用 i2c 引脚 我使用 RUN 安装所有模块 但是当我使用 CMD 运行我的 python 程序时 我收到一条错误消息 Trackback most recent call last file
  • 使用 Verilator 和 VPI 读取寄存器数组

    所以我在我的verilog中定义了以下寄存器 reg 31 0 register mem 0 15 verilator public 我的目标是从我的 verilator c 代码中读取存储在其中的 16 个值中的每一个 我发现有关 VPI
  • Verilog 最佳实践 - 递增变量

    我绝不是 Verilog 专家 我想知道是否有人知道这些增加值的方法中哪一种更好 抱歉 如果这个问题太简单了 Way A 在组合逻辑块中 可能在状态机中 some condition count next count 1 然后在一个连续块中
  • 如何获取值数组作为 plusargs?

    如何获取值数组作为参数 我需要从命令行获取一组未定义大小的命令 如何将这些参数放入数组或队列中 Eg CMDS READ WRITE READ N WRITE 它应该被带到一个数组中 value plusargs不支持数组 但支持字符串 看
  • 您可以使用类 C 语言对 FPGA 进行编程吗? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 在大学里 我用类似 C 的语言编写了 FPGA 不过 我也知道人们通常使用 Verilog 或 VHD
  • 在verilog中将wire值转换为整数

    我想将电线中的数据转换为整数 例如 wire 2 0 w 3 b101 我想要一个将其转换为 5 并将其存储在整数中的方法 我怎样才能以比这更好的方式做到这一点 j 1 for i 0 i lt 2 i i 1 begin a a w i
  • if 语句导致 Verilog 中的锁存推断?

    我正在编写用于合成算法的 Verilog 代码 我对哪些情况可能导致推断锁存器有点困惑 下面是这样的一段代码 虽然它在模拟中工作得很好 但我担心它可能会导致硬件问题 always b1 or b2 b1 map b2 map m1 map
  • 使用 C++ 和 i2c 工具从虚拟 i2c 写入和读取

    我正在尝试使用 C 写入和读取 I2C 总线 我的I2C总线是虚拟的 第一件事是加载内核模块i2c stub 我可以通过 bash 完成所有事情 现在我将其移植到 C 我可以打开i2c总线 获取特定地址的i2c总线 但无法读写 我正在虚拟化
  • VHDL 中的 BRAM_INIT

    我正在模拟基于处理器的设计 其中程序存储器内容保存在 BRAM 中 我正在使用 VHDL 推断 BRAM 实现程序存储器 我试图避免使用 CoreGen 因为我想保持设计的可移植性 最终该设计将进入 FPGA 我想看看是否有一种方法可以使用
  • 如何将时钟门映射到技术库单元

    我的设计中有以下时钟门 module my clkgate clko clki ena Clock gating latch triggered on the rising clki edge input clki input ena ou
  • MCP23017 I2C 设备驱动程序探测函数未调用

    我正在使用以下 I2C GPIO设备驱动 https github com torvalds linux blob master drivers gpio gpio mcp23s08 c访问 MCP23017 GPIO 使用 insmod
  • 我们可以在 C 或 SystemVerilog 中使用 ifdef MACROS 中的条件吗?

    我想要那样的东西 ifdef N O gt N I define GREATER 1 else define LESSER 1 endif 但做不到 有什么解决方案或阅读吗 我很努力地想要做到这一点 但是却做不到 Verilog 不提供这样
  • 对象 <名称> 未声明

    这是我的代码 据我所知 LEDs被定义为 module sevenseg LEDs in output reg 6 0 LEDs input 3 0 in always in begin case in 0 LEDs 7 b1000000
  • 是否有通用 I2C 命令来查看设备是否仍然存在于总线上?

    是否有通用的 I2C 命令来查看设备在初始化一次后是否仍然存在于总线上 例如 OLED 显示器 我问这个的原因是为了避免主程序由于库代码中存在无限循环而冻结 当设备断开连接时 例如 Wire 库 在 MCU 启动时 我想检查设备是否可用 并
  • 如何从 Spartan 6 写入 Nexys 3 FPGA 板上的 Micron 外部蜂窝 RAM?

    我到处都查过了 数据表 Xilinx 网站 digilent 等等 但什么也没找到 我能够使用 Adept 工具来验证我的蜂窝 RAM 是否正常运行 但我找不到任何库存 VHDL 代码作为控制器来写入数据和从中读取数据 帮助 找到了此链接
  • 如何在Verilog中将二维数组中的所有位设置为0?

    我构建了一个 8 2bits 数组来表示 Verilog 中的一块内存 reg 1 0 m 0 7 该存储器有一个复位信号 如果复位为1 则该存储器中的所有位都应重置为0 但是我不知道如何以简洁的方式设置m的所有位 因为如果有数百个内存中有
  • 在 Verilog 程序中使用连续分配?

    在 Verilog 程序中使用连续赋值是否可能和 或有用 例如 是否有任何理由将assign里面一个always堵塞 例如这段代码 always begin assign data in Data end 此外 是否可以用这种方法生成顺序逻
  • Verilog 按位或 ("|") 单子

    我见过 Verilog 代码 其中使用了按位或运算符 目的是什么 例如 address 15 14 0 or address 15 14 io din ramrd 不能省略 吗在这些情况下 在这种情况下 它充当归约运算符 例如 4 b100
  • 如何转换温度传感器得到的值?

    我在ST工作Temperature sensor hts221 我用I2C与传感器的命令通信 我从文档中看到类似以下文字 enter code here Temperature data are expressed as TEMP OUT

随机推荐

  • ROS中D435i的安装使用

    目录 D435i 安装ROS接口安装使用 Python接口安装opencv安装 xff08 相机标定 使用的依赖 xff09 D435i标定安装依赖标定发生的错误 D435i使用使用find object 2d检测2D物体 xff08 平面
  • win10远程桌面登录虚拟机Ubuntu

    在公司实习没事干 xff0c 想着折腾一下虚拟机 xff0c 于是用Windows win10 下的mstsc登陆一下虚拟机上的Ubuntu 14 04 桌面环境 顺便区别一下一般用telnet远程连接和使用桌面共享连接的区别 xff1a
  • octet和byte的差异

    在不严谨的前提下 xff0c byte和octet都表示为8 bits xff0c 但是严格意义上来讲 xff0c octet才是严格意义上的8 bits xff0c 而历史上的byte其实可以表示为4 bits 10 bits xff0c
  • 算法移植到STM32单片机中会遇到的一些问题

    最近完成了一些算法 xff0c 需要移植到STM32F4系列的板子上用作实际工程 xff0c 其中遇到了许多的问题 xff0c 下面记录一些调试bug的经验记录 1 编译没有问题 xff0c 但是调试运行时却会进入到某一函数无法运行 xff
  • 由chmod改系统文件权限引ssh登录报ssh_exchange_identification: read: Connection reset by peer无法登陆问题

    root用户下在给某个文件夹下的所有文件改权限的时候 xff0c 用了chmod R 命令 xff0c 咋一看这个命令没啥很正常 xff0c 也能执行 xff0c 但是后面的提示让人感觉很不对劲 xff0c 因为yang下文件没这么多 xf
  • mysql中find_in_set()函数的使用

    在做电商项目时 xff0c 不知你有没有遇到这样的一种情况 xff0c mysql数据库中商品表tb product里面有个字段type xff0c 它存储的是商品类型 xff0c 比如 1 xff1a 热门推荐2 xff1a 精选推荐3
  • shell设置变量与脚本返回值

    Linux中的本地变量和环境变量 本地变量 查看本地变量 set 设置本地变量 x 61 34 123 34 环境变量 查看环境变量 env 设置环境变量 x 61 34 123 34 export x 注意 xff1a 变量与等号 等号与
  • Docker 环境准备好这些,工作就完成了一半

    Docker官网yum源 xff1a http yum dockerproject org repo main 支持不同版本 1 span class token punctuation span 关闭防火墙 systemctl stop
  • 习题5-7 使用函数求余弦函数的近似值 (15 分)

    本题要求实现一个函数 xff0c 用下列公式求cos x 的近似值 xff0c 精确到最后一项的绝对值小于e xff1a cos x 61 x 0 0 x 2 2 43 x 4 4 x 6 6 43 函数接口定义 xff1a double
  • 6-12 二叉搜索树的操作集 (30 分)

    本题要求实现给定二叉搜索树的5种常用操作 函数接口定义 xff1a BinTree Insert BinTree BST ElementType X BinTree Delete BinTree BST ElementType X Posi
  • C++ CAS 操作

    C 43 43 中的 CAS 操作用于操作原子变量 xff0c 它是 atomic lt T gt 的成员函数 span class token macro property span class token directive hash
  • 习题6-6 使用函数输出一个整数的逆序数 (20 分)

    本题要求实现一个求整数的逆序数的简单函数 函数接口定义 xff1a int reverse int number 其中函数reverse须返回用户传入的整型number的逆序数 裁判测试程序样例 xff1a include lt stdio
  • 数据结构之各种常用结构体总结

    一 线性表 define MaxSize 100 表长度初始定义 typedef struct ElemType data MaxSize 或者指示动态分配数组的指针Elemtype data int length 数组最大容量和长度 Sq
  • 习题2.7 弹球距离 (15 分)

    设有一个球从高度为h米的地方落下 xff0c 碰到地面后又弹到高度为原来p倍的位置 xff0c 然后又落下 xff0c 再弹起 xff0c 再落下 请编写函数求初始高度为h的球下落后到基本停下来 xff08 高度小于给定阈值TOL xff0
  • 习题7-3 判断上三角矩阵 (15 分)

    上三角矩阵指主对角线以下的元素都为0的矩阵 xff1b 主对角线为从矩阵的左上角至右下角的连线 本题要求编写程序 xff0c 判断一个给定的方阵是否上三角矩阵 输入格式 xff1a 输入第一行给出一个正整数T xff0c 为待测矩阵的个数
  • python计算黑白图像像素值

    span class token function import span numpy as np span class token function import span cv2 span class token comment 读入图
  • python将文件夹中图像生成file list

    按行排列 xff0c 图像路径 span class token function import span os span class token function import span argparse span class token
  • Markdown插入图片 详细例子(本地图片,网络图片,base64) Windows

    网上一番搜索 xff0c 领略到基本所有回答 xff0c 都是一样的 xff0c 简简单单的介绍 而且 xff0c TMD xff0c 插入图片答案的本地路径 xff0c 都是回答的是Linux或Mac OS系统的路径 xff0c 诸如 x
  • Pixhawk学习笔记(2)——问题汇总

    1 遥控器校准时 xff0c 拨动摇杆 xff0c 上位机通道数据不变化 解决方法 xff1a PPM编码器上有一个跳线需短接 xff0c 短接后才可通过编码器对遥控器接收机供电 供电前PPM编码器模块上蓝灯快闪 xff0c 供电后变为慢闪
  • 在FPGA中使用Verilog实现I2C通信

    按照I2C标准的官方时序 可以看出时序看起来很简单 xff0c 不过它严格的按照时序要求来传送数据 xff0c 马虎不得的 xff0c 特别是起始和停止的条件 xff0c 起始必须要时钟线SCL为高电平时数据线SDA拉低 xff1b 而停止