cyclone4驱动LM75A温湿度传感器学习
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温湿度传感器学习的更多相关文章
- STM32驱动DHT11温湿度传感器
DHT11 是一款湿温度一体化的数字传感器.该传感器包括一个电阻式测湿元件和一个 NTC 测温元件,并与一个高性能 8 位单片机相连接.通过单片机等微处理器简单的电路连接就能够 实时的采集本地湿度和温 ...
- STM32—驱动DHT11数字温湿度传感器
文章目录 DHT11模块简介 DHT11数据传输 DHT11通信时序 代码实现 相关引脚初始化 复位模块 判断响应模块 读取数据包模块 DHT11模块简介 DHT11数字温湿度传感器,用来测量环境的温 ...
- STM32应用实例五:与SHT1X温湿度传感器通讯
在这次项目开发中应用到了SHT1X温湿度传感器,该系列有SHT10.SHT11和SHT15,属于Sersirion温湿度传感器家族中的贴片封装系列.包括一个电容性聚合体测湿敏感元件.一个用能隙材料制成 ...
- Arduino和C51开发DHT11温湿度传感器
技术:51单片机.Arduino.DHT11.温湿度传感器.传感器 概述 学习单片机离不开对传感器的学习,本文主要介绍DHT11温湿度传感器的使用方法,同学也可以了解更多的传感器,这对你以后开发产 ...
- 进阶之路(中级篇) - 016 温湿度传感器DHT11
如果想使用 Arduino 开发板驱动 DHT11 来获取温湿度的时候建议使用第三方的库,这样可以加快程序的开发速度,而且不容易出错,下面的代码我已经安转了第三方的库了.详细的安装方法请参考极客先锋的 ...
- 玩转X-CTR100 l STM32F4 l DHT11温湿度传感器
我造轮子,你造车,创客一起造起来!塔克创新资讯[塔克社区 www.xtark.cn ][塔克博客 www.cnblogs.com/xtark/ ] DHT11数字温湿度传感器是一款含有已校准数字信号输 ...
- DHT11温湿度传感器编程思路以及代码的实现(转载)
源自:https://blog.csdn.net/qq_34952376/article/details/81193938 在我们刚开始进入单片机的学习中,练习写传感器的时序是必不可少的,其实我比较推 ...
- Arduino连接SHT10温湿度传感器--返回值不正常解决办法
如题目,arduino中连接温湿度传感器,用的是一个github开源项目,地址:点击打开,其实这个就是一个封装好的库,下载后把解压的文件夹复制到Arduino目录下的librarys文件夹内,重启Ar ...
- 在树莓派上读取DHT11温湿度传感器-python代码实现及常见问题(全面简单易懂)
最近由于自己的课题需要,想要用在树莓派上使用DHT11温湿度传感器来读取空气中温湿度,遇到了几个问题,解决之后也对之前的知识进行了回顾,总结,特整理如下,希望能给也在学习树莓派的小伙伴们带来一些帮助. ...
随机推荐
- spring集成ehcache本地缓存
1.maven依赖 <!-- ehcache 相关依赖 --> <dependency> <groupId>net.sf.ehcache</groupId&g ...
- 七.部署war包到Tomcat(基于Centos安装)
1.把war包上传至tomcat的webapps目录下面 2.启动Tomcat,在Tomcat的bin目录下面,运行startup.sh 3.访问项目,如下成功打开项目
- TraceWrite waittype
今天上午突然开发人员叫起来说数据库非常慢,马上连上数据查看. 使用sp_who2和下面脚本可以看到大量的TraceWrite 等待事件.我的第一反应就是有人启用的Profiler在生产服务器上抓数据了 ...
- BZOJ1037:[ZJOI2008]生日聚会Party(DP)
Description 今天是hidadz小朋友的生日,她邀请了许多朋友来参加她的生日party.hidadz带着朋友们来到花园中,打算坐成一排玩游戏. 为了游戏不至于无聊,就座的方案应满足如下条件: ...
- [转]Javascript 取小数点后面N位
用Javascript取float型小数点后两位,例22.127456取成22.13,如何做? 1. 最笨的办法....... [我就怎么干的.........] } 2. 正则表达式效果不错 &l ...
- HDU 1078 FatMouse and Cheese ( DP, DFS)
HDU 1078 FatMouse and Cheese ( DP, DFS) 题目大意 给定一个 n * n 的矩阵, 矩阵的每个格子里都有一个值. 每次水平或垂直可以走 [1, k] 步, 从 ( ...
- C# 6.0 的?.运算符
What is it? Here’s the scenario Consider getting the grandchild of a parent object like this: var g1 ...
- Oracle12C创建用户遇到ora-6509
引用自:http://blog.itpub.net/29357786/viewspace-1995055/ ORACLE 12C创建用户之ORA-65096 2016年2月25日,一北京北方人瑞教育咨 ...
- Inconsistant light map between PC and Mobile under Unity3D
Author: http://www.cnblogs.com/open-coder/p/3898159.html The light mapping effects between PC and Mo ...
- C++分享笔记:扑克牌的洗牌发牌游戏设计
笔者在大学二年级期间,做过的一次C++程序设计:扑克牌的洗牌发牌游戏.具体内容是:除去大王和小王,将52张扑克牌洗牌,并发出5张牌.然后判断这5张牌中有几张相同大小的牌,是否是一条链,有几个同花等. ...