FPGA模块——IIC协议(读写PCF8591)

FPGA模块——IIC协议(读取PCF8591)

PCF8591/AT8591芯片

低功耗8位CMOS数据采集设备,4路模拟输入,1路模拟输出,分时多路复用,读取数据用串型iic总线接口,最大100khz。
在这里插入图片描述
电路设计:IIC需要外接上拉电阻
在这里插入图片描述

控制字节(iic中写寄存器地址位8b)
这个芯片中是有自己要求的,但是也符合iic协议的时序。
在这里插入图片描述
stop之前最后一步:
写的8位数据就是DAC转换得到的电压值,
读的数据就是ADC转换得到的8位数据

对iic协议的使用

iic协议就看这个之前写的:链接: IIC协议模块

module pcf8591(
    //clock and reset
    input                 clk        ,    // 时钟信号
    input                 rst_n      ,    // 复位信号

    //i2c interface
    output   reg          i2c_rh_wl  ,    // I2C读写控制信号
    output   reg          i2c_exec   ,    // I2C触发执行信号
    output   reg  [15:0]  i2c_addr   ,    // I2C器件内地址
    output   reg  [ 7:0]  i2c_data_w ,    // I2C要写的数据
    input         [ 7:0]  i2c_data_r ,    // I2C读出的数据
    input                 i2c_done   ,    // I2C一次操作完成

    //user interface
    output   reg  [19:0]  num             // 数码管要显示的数据
);

//parameter
parameter    CONTORL_BYTE = 8'b0100_0001; // PCF8591的控制字
parameter    V_REF        = 12'd3300    ; // 3.3V放大1000倍,避免用小数

//reg define
reg    [7:0]    da_data   ;               // DA数据
reg    [7:0]    ad_data   ;               // AD数据
reg    [3:0]    flow_cnt  ;               // 状态流控制
reg    [18:0]   wait_cnt  ;               // 计数等待

//wire define
wire   [19:0]   num_t     ;               // 临时寄存的数据

//*****************************************************
//**                    main code
//*****************************************************

assign num_t = V_REF * ad_data ;

//DA输出数据
always @(posedge clk or negedge rst_n) begin
    if(rst_n == 1'b0) begin
        da_data  <= 8'd0;
    end
    else if(i2c_rh_wl == 1'b0 & i2c_done == 1'b1)begin
        if(da_data == 8'd255)
            da_data<= 8'd0;
        else
            da_data<= da_data + 1'b1;
    end
end

//AD输入数据处理
always @(posedge clk or negedge rst_n) begin
    if(rst_n == 1'b0) begin
        num <= 20'd0;
    end
    else
        num <= num_t >> 4'd8;
end

//AD、DA控制及采样
always @(posedge clk or negedge rst_n) begin
    if(rst_n == 1'b0) begin
        i2c_exec <= 1'b0;
        i2c_rh_wl<= 1'b0;
        i2c_addr <= 8'd0;
        i2c_data_w <=  8'd0;
        flow_cnt   <=  4'd0;
        wait_cnt   <= 17'd0;
    end
    else begin
        i2c_exec <= 1'b0;
        case(flow_cnt)
            'd0: begin
                if(wait_cnt == 17'd100) begin
                    wait_cnt<= 17'd0;
                    flow_cnt<= flow_cnt + 1'b1;
                end
                else
                    wait_cnt<= wait_cnt + 1'b1;
            end
            //DA转换输出
            'd1: begin
                i2c_exec  <= 1'b1;
                i2c_addr  <= CONTORL_BYTE;
                i2c_rh_wl <= 1'b0;
                i2c_data_w<= da_data;
                flow_cnt  <= flow_cnt + 1'b1;
            end
            'd2: begin
                if(i2c_done == 1'b1) begin
                    flow_cnt<= flow_cnt + 1'b1;
                end
            end
            'd3: begin
            //每1秒变化0.1V,需33秒变化完,共256【0~255】次变化,故每次变化计数为:
            //(33/256)*10^6 = 128906
                if(wait_cnt == 17'd128906) begin
                    wait_cnt<= 17'd0;
                    flow_cnt<= flow_cnt + 1'b1;
                end
                else
                    wait_cnt<= wait_cnt + 1'b1;
            end
            //AD转换输入
            'd4: begin
                i2c_exec  <= 1'b1;
                i2c_addr  <= CONTORL_BYTE;
                i2c_rh_wl <= 1'b1;
                flow_cnt  <= flow_cnt + 1'b1;
            end
            'd5: begin
                if(i2c_done == 1'b1) begin
                    ad_data <= i2c_data_r;
                    flow_cnt<= 4'd0;
                end
            end
            default: flow_cnt <= 4'd0;
        endcase
    end
end

endmodule
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云影点灯大师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值