基于FPG的温湿度实时采集与显示

AHT10、OLED,Verilog


前言

这是自己一开始做的,可能有很多不对的地方如若不对希望各位大佬能帮忙指出,也可在评论区探讨,如有侵权请及时告知。

本次所用芯片为

FPGA型号:EP4CE6F17CB 

温湿度传感器型号:AHT10

OLED尺寸及芯片:0.96寸 SSD1306

一、项目介绍

使用 FPGA 驱动温湿度传感器模块 AHT10,获取环境温度值与湿度值,并将温、湿度值显示在 OLED 屏上。

实现功能:

1、AHT10实时采集温湿度数据 显示到OLED上;

2、高温报警装置;

3、按键调节高温报警值;

4、温湿度数据通过uart显示PC端;

5、数码管显示时间。

二、主要模块分析

1.AHT10

 

  1.1 AHT10手册说明

 

 注意:手册上说等待80ms待测完成忙状态为Bit[7]为0,然后读取6字节数据,但是由上图可知6字节数据,中有1字节的状态字,所以是5字节的温湿度数据。

1.2 状态转移图

(iic_master接口及状态转移图都是我们李政老师画以及写的) 

 

1.3 状态说明

POWER:上电等待40ms;

IDLE:等待40ms测量间隔时间(可要可不要);

WRITE:为了对齐时序,发的请求需要拉低否者为出现错误;

WRITE_DONE:发起始位,发请求,发数据;

DONE:这个状态在由READ_DONE跳来时我用来判断读的数据是否有效(判断Bit[7]是否为0);由WAITE_DONE跳来时直接跳WAIT;

WAIT:等待测量的80ms;

READ:为了对其IIC_master时序;

READ_DONE:第一个READ_DONE会发起始位,读控制字,之后就是发应答。

1.4 状态转移条件

power_2_idle:等待完40ms;

idle_2_write:等待完40ms;

write_2_write_done: 'd1;

write_done_2_done:字节计数器计满

done_2_wait:enable2==1;

wait_2_read:等待完80ms;

read_2_read_done: 'd1;一个周期就跳

read_done_2_done:字节计数器计满

done_2_read:状态字bit[7]为1

done_2_idle:状态字bit[7]为0且enable2==0

输出部分的代码

//输出
    always @(posedge Clk or negedge Rst_n)begin
        if(~Rst_n)begin
            TX(1'b0,4'd0,8'd0);
        end 
        else if((state_c == WRITE_DONE) && enable_1 && !done)begin
            case(cnt_byte)
                0   :TX(1'b1,{`CMD_START | `CMD_WRITE},{`I2C_ADR,`WR_BIT});//发起始位,以及让iic_master进入写状态命令,写控制字节
                1   :TX(1'b1,`CMD_WRITE,`INIT_1) ;  //发初始化命令
                2   :TX(1'b1,`CMD_WRITE,`INIT_2) ;
                3   :TX(1'b1,{`CMD_WRITE | `CMD_STOP},`INIT_3) ;
            endcase
        end
        else if((state_c == WRITE_DONE )&& !enable_1 && !done)begin
           case(cnt_byte)
                0   :TX(1'b1,{`CMD_START | `CMD_WRITE},{`I2C_ADR,`WR_BIT});//发起始位,以及让iic_master进入写状态命令,写控制字节
                1   :TX(1'b1,`CMD_WRITE,`MEAS_1) ;  //测量温度命令
                2   :TX(1'b1,`CMD_WRITE,`MEAS_2) ;
                3   :TX(1'b1,{`CMD_WRITE | `CMD_STOP},`MEAS_3) ;
            endcase 
        end
        else if(state_c == READ_DONE && !done)begin
            case(cnt_byte)
                0           :TX(1'b1,{`CMD_START | `CMD_WRITE},{`I2C_ADR,`RD_BIT});//发起始位,以及让iic_master进入读状态命令,读控制字节
                R_LEN - 1   :TX(1'b1,{`CMD_READ | `CMD_STOP},0);//最后一个数据,读数据,发停止位
                default     :TX(1'b1,`CMD_READ,0);//主机回应ack
            endcase 
        end
        else begin
            TX(1'b0,tx_cmd,tx_data);
        end
    end 
//用task发送请求,命令,数据(地址+数据)
    task TX;
        input           req     ;
        input     [3:0] command ;
        input     [7:0] data    ;
        begin
            tx_req  = req     ;
            tx_cmd  = command ;
            tx_data = data    ;
        end
    endtask 

2.OLED

2.1 手册说明 

2.1.1 为了保护OLED显示屏以及延长显示屏的寿命有上电以及断电的顺序

 

 

 具体几个命令手册上我也没看到,可能没注意,反正一共27字节的命令。

 2.1.2 地址

2.1.3 IIC时序数据图

所以我们发数据都是发地址+控制字+数据

2.1.4 OLED结构

 

数据存放是竖着放的,一页中1byte刚好放1列

 

2.1.5 设置寻址模式

    设置内存寻址模式命令

 一共有3种寻址模式,水平寻址模式,垂直寻址模式,页寻址模式(默认寻址模式)

 

    设置起始地址和起始地址

 

 2.2OLED_DRIVER状态转移图

 

2.2.1  对屏幕写0


总结

OLED模块主要是弄清楚寻址模式,起始地址,以及结束地址。规定一个方框,按照寻址模式往方框里面写数据。我是划区域写数据,变的只有我的数据显示的哪两块,我有同学做的是直接一帧一帧的传,这样只需要画一块,也就是屏幕的一整块然后一帧一帧的传数据就行了。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值