使用verilog完成对IIC总线的编写,采用三段式状态机,完成测试

您所在的位置:网站首页 iic主从切换 使用verilog完成对IIC总线的编写,采用三段式状态机,完成测试

使用verilog完成对IIC总线的编写,采用三段式状态机,完成测试

2023-09-24 08:08| 来源: 网络整理| 查看: 265

一、IIC总线开始状态 IIC开始状态 IIC总线开始状态应该是SCL在高电平的期间,SDA出现下降沿,表示为开始状态

二、IIC总线结束状态 IIC结束状态 IIC总线结束状态应该是在SCL为高电平期间,SDA出现上升沿,表示结束状态

三、数据传输状态 写数据状态 在这里插入图片描述 读数据状态

总线数据传输 IIC总线对于数据传输的要求为在SCL为低电平的情况下进行数据的改变,因此为了避免产生误差,选择在SCL低电平的中间位置进行数据的写入,在SCL为高电平的时候进行数据的保持

四、读写状态的状态转换图 写状态状态转移图 读状态状态转移图 五、测试结果

写状态开始状态 写状态开始状态 写状态写入从机地址 写状态写入从机地址 写状态写入寄存器地址 写状态写入寄存器地址 写状态写入数据 写状态写入数据 写状态停止状态 写状态停止状态 读状态第一个开始信号 读状态第一个开始信号 读状态第一次写从机地址 读状态第一次写从机地址 读状态写入寄存器地址 读状态写入寄存器地址 读状态第一次停止 读状态第一次停止 读状态第二次开始 读状态第二次开始 读状态第二次写入从机地址 读状态第二次写入从机地址] 读状态读数据 读状态读数据 读状态第二次停止 读状态第二次停止 测试过程中我选择的从机地址是7’h3c,寄存器地址是8‘h00,写入的数据是8’h10,根据测试结果可以看到不仅成功的将数据写入到了寄存器之中,并且将写入的数据读取了出来,完成了整体的设计

六、代码

`timescale 1ns / 1ps // // Company: // Engineer: // // Create Date: 2021/09/14 19:45:40 // Design Name: // Module Name: IIC_CODE // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // // module IIC_Code( input wire clk_i, input wire rst_i, input wire send_i, //IIC开始信号 input wire wr_i, //读写控制信号,1为写,0为读 input wire [6:0] Slv_Addr_i, //从机的地址数据 input wire [7:0] Reg_Addr_i, //寄存器的地址数据 input wire [7:0] Data_i, //将要写入的数据 output reg IIC_Busy_o, //IIC工作标志信号 output reg [7:0] IIC_Read_Data_o, //IIC读出来的数据 inout wire sda, inout wire scl ); parameter DIV = 2500; //分频计数器的分频系数 parameter T1 = DIV / 4; //第一个标志位 parameter T2 = DIV *3/4; //第二个标志位 reg [11:0] cnt_clk; //clk计数器 reg [3:0] cnt_scl; //scl计数器,表示传送数据的位数 reg sda_tri; //三态控制信号 reg sda_o; //sda总线传输数据的寄存器 reg scl_o; //scl时钟总线 reg [4:0] current_state; //当前状态 reg [4:0] next_state; //下个状态 assign sda = sda_tri ? 1'bz : sda_o; assign scl = scl_o; parameter IDLE = 5'd0; parameter W_START = 5'd1; parameter W_SLV_ADDR = 5'd2; parameter W_WR = 5'd3; parameter W_ACK1 = 5'd4; parameter W_REG_ADDR = 5'd5; parameter W_ACK2 = 5'd6; parameter W_DATA = 5'd7; parameter W_ACK3 = 5'd8; parameter W_STOP = 5'd9; parameter R_START1 = 5'd10; parameter R_SLV_ADDR1 = 5'd11; parameter R_WR1 = 5'd12; parameter R_ACK1 = 5'd13; parameter R_REG_ADDR = 5'd14; parameter R_ACK2 = 5'd15; parameter R_STOP1 = 5'd16; parameter R_START2 = 5'd17; parameter R_SLV_ADDR2 = 5'd18; parameter R_WR2 = 5'd19; parameter R_ACK3 = 5'd20; parameter R_DATA = 5'd21; parameter R_ACK4 = 5'd22; parameter R_STOP2 = 5'd23; always@(posedge clk_i) begin if(rst_i == 1'b1) current_state


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3