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温湿度传感器来读取空气中温湿度,遇到了几个问题,解决之后也对之前的知识进行了回顾,总结,特整理如下,希望能给也在学习树莓派的小伙伴们带来一些帮助. ...
随机推荐
- Django 创建模型 激活模型 简单的使用模型
创建模型: 在你的开发环境中,已经有一个“项目” —— 已经建立起来,你将开始在上面做一些东西. 你编写的每个Django应用都是一个遵循特定约定的Python包. Django自带一个工具,它可以自 ...
- 数学归纳法·Fibonacci数列
数学归纳法 我们先来看一个例子: 我们让多诺米骨牌倒下的充要条件是: 第一块骨牌倒下: 假设当当前块骨牌倒下时,则他的后面一块也会倒下. 我们把这个例子给抽象出来就可以得到数学归纳法的证明过程: [第 ...
- cin,get,getline
一.cin 1.cin使用空白(空格.制表符和换行符)来确定字符串结束的位置,并且对于换行符,cin会把换行符留在输入队列.cin读取字符串放到数组中,并自动在结尾添加空字符. 例如: ]; cin& ...
- HDU 6395 Sequence 【矩阵快速幂 && 暴力】
任意门:http://acm.hdu.edu.cn/showproblem.php?pid=6395 Sequence Time Limit: 4000/2000 MS (Java/Others) ...
- [19/03/29-星期五] IO技术_File(文件)类(可操作文件,不能操作其里边内容,位于Java.io 包中)&递归遍历
一.概念 java.io.File类:代表文件和目录. 在开发中,读取文件.生成文件.删除文件.修改文件的属性时经常会用到本类. 以pathname为路径创建File对象,如果pathname是相对路 ...
- Spring Boot Web Error Page处理
spring Boot默认是whitelabel error page. 其实我们可以自己处理,由于时间有限,所以就简单说明一下方法. 首先配置 @Configuration public class ...
- mongo删除、添加分片
MongoDB 分片的原理.搭建.应用 一.概念: 分片(sharding)是指将数据库拆分,将其分散在不同的机器上的过程.将数据分散到不同的机器上,不需要功能强大的服务器就可以存储更多的数据和处 ...
- imageNamed和dataWithContentsOfFile的区别(1)
imageNamed和dataWithContentsOfFile的区别 imagecacheuiviewextensionprocessingxcode 最近老是受iphone内存问题的困扰,找了些 ...
- MVC身份验证Attribute简易版
public class MemberValidationAttribute : AuthorizeAttribute { protected override bool AuthorizeCore( ...
- 在ASP.NET Core的startup类中如何使用MemoryCache
问: 下面的代码,在ASP.NET Core的startup类中创建了一个MemoryCache并且存储了三个键值“entryA”,“entryB”,“entryC”,之后想在Controller中再 ...