1. LM75A第一次使用,I2C接口,8脚

2. 打开quartus工程,下面只要是看看代码结构,问题在于多个always语句,逻辑上不太好分清楚,主要看状态机

 module I2C_READ(
clk,
rst_n,
scl,sda,data
); input clk;//总线时钟 50MHz
input rst_n;//异步复位,低电平有效 output scl;//SCL 时钟
inout sda;// SDA 数据总线
output [:] data;//温度数据 reg [:]data_r;//温度数据寄存器
reg scl;//SCL 总线寄存器
reg sda_r;//SDA 总线寄存器
reg sda_link;//SDA 总线数据方向标志
reg [:]scl_cnt;//SCL 时钟产生计数器
reg [:]cnt;//用来标记SCL时钟计数器
reg [:]timer_cnt;//定时器,每隔2s 读取一次温度数据
reg [:]data_cnt;//数据串并转换寄存器
reg [:]address_reg;//器件地址寄存器
reg [:]state;//状态寄存器
//////////////////////////////////////////////////////////////////////////////////
//进程1、2、3:产生SCL 总线时钟
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
scl_cnt <= 'd0;
else if(scl_cnt == 'd199)
scl_cnt <= 'd0;
else
scl_cnt <= scl_cnt + 'b1;
end
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
cnt <= 'd5;
else
case(scl_cnt)
'd49: cnt <= 3'd1;//高电平中间
'd99: cnt <= 3'd2;//下降沿
'd149:cnt <= 3'd3;//低电平中间
'd199:cnt <= 3'd0;//上升沿
default: cnt <= 'd5;
endcase
end
`define SCL_HIG (cnt == 'd1)
`define SCL_NEG (cnt == 'd2)
`define SCL_LOW (cnt == 'd3)
`define SCL_POS (cnt == 'd0)
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
scl <= 'b0;
else if(`SCL_POS)
scl <= 'b1;
else if(`SCL_NEG)
scl <= 'b0;
end
//////////////////////////////////////////////////////////////////////////////////
//进程4:定时器,每隔1s 读取一次温度数据
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
timer_cnt <= 'd0;
else if(timer_cnt == 'd49999999)
timer_cnt <= 'd0;
else
timer_cnt <= timer_cnt + 'b1;
end
//////////////////////////////////////////////////////////////////////////////////
//状态机定义
parameter IDLE = 'b0_0000_0000,
START = 'b0_0000_0010,
ADDRESS = 'b0_0000_0100,
ACK1 = 'b0_0000_1000,
READ1 = 'b0_0001_0000,
ACK2 = 'b0_0010_0000,
READ2 = 'b0_0100_0000,
NACK = 'b0_1000_0000,
STOP = 'b1_0000_0000;
`define DEVICE_ADDRESS 'b1001_0001//器件地址,读操作
//////////////////////////////////////////////////////////////////////////////////
//进程5:状态机描述
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
data_r <= 'd0;
sda_r <= 'b1;
sda_link <= 'b1;
state <= IDLE;
address_reg <= 'd0;
data_cnt <= 'd0;
end
else
case(state)
IDLE:
begin
sda_r <= 'b1;
sda_link <= 'b1;
if(timer_cnt == 'd49999999)
state <= START;
else
state <= IDLE;
end
START://产生起始信号
begin
if(`SCL_HIG)
begin
sda_r <= 'b0;
sda_link <= 'b1;
address_reg <= `DEVICE_ADDRESS;
state <= ADDRESS;
data_cnt <= 'd0;
end
else
state <= START;
end
ADDRESS://主机对器件进行寻址
begin
if(`SCL_LOW)
begin
if(data_cnt == 'd8)//寻址完成,SDA改变方向,器件准备输出应答讯号
begin
state <= ACK1;
data_cnt <= 'd0;
sda_r <= 'b1;
sda_link <= 'b0;
end
else//寻址过程中,SDA对器件作为输入
begin
state <= ADDRESS;
data_cnt <= data_cnt + 'b1;
case(data_cnt)
'd0: sda_r <= address_reg[7];
'd0: sda_r <= address_reg[7];
'd1: sda_r <= address_reg[6];
'd2: sda_r <= address_reg[5];
'd3: sda_r <= address_reg[4];
'd4: sda_r <= address_reg[3];
'd5: sda_r <= address_reg[2];
'd6: sda_r <= address_reg[1];
'd7: sda_r <= address_reg[0];
default: ;
endcase
end
end
else
state <= ADDRESS;
end
ACK1://器件输出应答信号
begin
if(!sda && (`SCL_HIG))
state <= READ1;
else if(`SCL_NEG)
state <= READ1;
else
state <= ACK1;
end
READ1://读器件数据,高字节
begin
if((`SCL_LOW) && (data_cnt == 'd8))//读高字节数据完成,SDA改变方向,主机准备输出应答讯号
begin
state <= ACK2;
data_cnt <= 'd0;
sda_r <= 'b1;
sda_link <= 'b1;
end
else if(`SCL_HIG)//读数据过程中,器件作为输出,这里有疑问,不是应该的等SCL一个时钟吗?SCL_HIG
begin
data_cnt <= data_cnt + 'b1;
case(data_cnt)
'd0: data_r[15] <= sda;
'd1: data_r[14] <= sda;
'd2: data_r[13] <= sda;
'd3: data_r[12] <= sda;
'd4: data_r[11] <= sda;
'd5: data_r[10] <= sda;
'd6: data_r[9] <= sda;
'd7: data_r[8] <= sda;
default: ;
endcase
end
else
state <= READ1;
end
ACK2://主机输出应答讯号
begin
if(`SCL_LOW)
sda_r <= 'b0;
else if(`SCL_NEG)
begin
sda_r <= 'b1;
sda_link <= 'b0;
state <= READ2;
end
else
state <= ACK2;
end
READ2://读低字节数据
begin
if((`SCL_LOW) && (data_cnt == 'd8))
begin
state <= NACK;
data_cnt <= 'd0;
sda_r <= 'b1;
sda_link <= 'b1;
end
else if(`SCL_HIG)
begin
data_cnt <= data_cnt + 'b1;
case(data_cnt)
'd0: data_r[7] <= sda;
'd1: data_r[6] <= sda;
'd2: data_r[5] <= sda;
'd3: data_r[4] <= sda;
'd4: data_r[3] <= sda;
'd5: data_r[2] <= sda;
'd6: data_r[1] <= sda;
'd7: data_r[0] <= sda;
default: ;
endcase
end
else
state <= READ2;
end
NACK://主机非应答
begin
if(`SCL_LOW)
begin
state <= STOP;
sda_r <= 'b0;
end
else
state <= NACK;
end
STOP:
begin
if(`SCL_HIG)
begin
state <= IDLE;
sda_r <= 'b1;
end
else
state <= STOP;
end
default: state <= IDLE;
endcase
end
assign sda = sda_link ? sda_r: 'bz;
assign data = data_r;
endmodule

3. 这个代码需要好好研究下,有疑问的地方,data_cnt <= data_cnt + 1'b1;每次读一位的时候,SCL应该有一个时钟,按照这个时钟去读的,为啥代码使用data_cnt这个变量,感觉不对啊?这里不是很明白

  begin
state <= ADDRESS;
data_cnt <= data_cnt + 'b1;
case(data_cnt)
'd0: sda_r <= address_reg[7];
'd0: sda_r <= address_reg[7];
'd1: sda_r <= address_reg[6];
'd2: sda_r <= address_reg[5];
'd3: sda_r <= address_reg[4];
'd4: sda_r <= address_reg[3];
'd5: sda_r <= address_reg[2];
'd6: sda_r <= address_reg[1];
'd7: sda_r <= address_reg[0];
default: ;
endcase
end

cyclone4驱动LM75A温湿度传感器学习的更多相关文章

  1. STM32驱动DHT11温湿度传感器

    DHT11 是一款湿温度一体化的数字传感器.该传感器包括一个电阻式测湿元件和一个 NTC 测温元件,并与一个高性能 8 位单片机相连接.通过单片机等微处理器简单的电路连接就能够 实时的采集本地湿度和温 ...

  2. STM32—驱动DHT11数字温湿度传感器

    文章目录 DHT11模块简介 DHT11数据传输 DHT11通信时序 代码实现 相关引脚初始化 复位模块 判断响应模块 读取数据包模块 DHT11模块简介 DHT11数字温湿度传感器,用来测量环境的温 ...

  3. STM32应用实例五:与SHT1X温湿度传感器通讯

    在这次项目开发中应用到了SHT1X温湿度传感器,该系列有SHT10.SHT11和SHT15,属于Sersirion温湿度传感器家族中的贴片封装系列.包括一个电容性聚合体测湿敏感元件.一个用能隙材料制成 ...

  4. Arduino和C51开发DHT11温湿度传感器

    技术:51单片机.Arduino.DHT11.温湿度传感器.传感器   概述 学习单片机离不开对传感器的学习,本文主要介绍DHT11温湿度传感器的使用方法,同学也可以了解更多的传感器,这对你以后开发产 ...

  5. 进阶之路(中级篇) - 016 温湿度传感器DHT11

    如果想使用 Arduino 开发板驱动 DHT11 来获取温湿度的时候建议使用第三方的库,这样可以加快程序的开发速度,而且不容易出错,下面的代码我已经安转了第三方的库了.详细的安装方法请参考极客先锋的 ...

  6. 玩转X-CTR100 l STM32F4 l DHT11温湿度传感器

    我造轮子,你造车,创客一起造起来!塔克创新资讯[塔克社区 www.xtark.cn ][塔克博客 www.cnblogs.com/xtark/ ] DHT11数字温湿度传感器是一款含有已校准数字信号输 ...

  7. DHT11温湿度传感器编程思路以及代码的实现(转载)

    源自:https://blog.csdn.net/qq_34952376/article/details/81193938 在我们刚开始进入单片机的学习中,练习写传感器的时序是必不可少的,其实我比较推 ...

  8. Arduino连接SHT10温湿度传感器--返回值不正常解决办法

    如题目,arduino中连接温湿度传感器,用的是一个github开源项目,地址:点击打开,其实这个就是一个封装好的库,下载后把解压的文件夹复制到Arduino目录下的librarys文件夹内,重启Ar ...

  9. 在树莓派上读取DHT11温湿度传感器-python代码实现及常见问题(全面简单易懂)

    最近由于自己的课题需要,想要用在树莓派上使用DHT11温湿度传感器来读取空气中温湿度,遇到了几个问题,解决之后也对之前的知识进行了回顾,总结,特整理如下,希望能给也在学习树莓派的小伙伴们带来一些帮助. ...

随机推荐

  1. WAS上配置数据源连接失败

    问题描述: 在节点 cnshh171Node01 上的服务器 server1 上, 对数据源 testj2cbug 执行的测试连接操作 由于以下异常 java.sql.SQLException: 调用 ...

  2. sql时间格式转换

    sql server2000中使用convert来取得datetime数据类型样式(全) 日期数据格式的处理,两个示例: CONVERT(varchar(16), 时间一, 20) 结果:2007-0 ...

  3. linux常用搜索文件命令

    使用linux系统难免会忘记文件所在的位置,可以使用以下命令对系统中的文件进行搜索.搜索文件的命令为”find“:”locate“:”whereis“:”which“:”type“ 方法/步骤     ...

  4. C/C++心得-理解指针

    上一篇笔者用自己那不是怎么好理解的逻辑介绍了内存和C中的基本数据类型,现在笔者再根据自己重新所学来说说C语言中的指针. 理解指针才能真正的算C语言入门.也许是我大学期间太关注前端UE,也许是当初开始学 ...

  5. Hibernate之CRUD实践

    Hibernate作为一个高度封装的持久层框架,曾经是非常牛逼的,现在虽然应用不是特别广,比如我前公司主要是做OA的,应用的框架就是Spring+SpringMVC+Hibernate. Hibern ...

  6. scp出现ssh port 22: Connection refused 问题解决具体步骤

    [root(0)@sys11 09:20:29 /home/work/Code_release/bj]# scp ./release.sh  root@192.168.161.151:/Users/a ...

  7. Filter实现字符集统一设置

    Filter实现字符集统一设置 其实是对request和response请求进行了拦截 1.创建Filter类,实现javax.Servlet接口 doFilter方法 //设置字符集 request ...

  8. 课时47.datalist标签(了解)

    1.datalist标签 作用:给输入框绑定待选项 2.datalist格式: <datalist> <option>待选项内容</option> </dat ...

  9. 大数据框架-HDFS

    HDFS:分布式文件系统,运行文件通过网络在多台主机分享的文件系统,分块写入(128M),适用于一次写入多次查询,不支持并发写(只能一块一块写),小文件不合适. nameNode(主节点,单个): 保 ...

  10. Oracle 触发器(二)

    Oracle触发器详解   触发器是许多关系数据库系统都提供的一项技术.在oracle系统里,触发器类似过程和函数,都有声明,执行和异常处理过程的PL/SQL块. 8.1 触发器类型 触发器在数据库里 ...