cyclone4驱动LM75A温湿度传感器学习
1. LM75A第一次使用,I2C接口,8脚
2. 打开quartus工程,下面只要是看看代码结构,问题在于多个always语句,逻辑上不太好分清楚,主要看状态机
1 module I2C_READ( 2 clk, 3 rst_n, 4 scl,sda,data 5 ); 6 7 input clk;//总线时钟 50MHz 8 input rst_n;//异步复位,低电平有效 9 10 output scl;//SCL 时钟 11 inout sda;// SDA 数据总线 12 output [15:0] data;//温度数据 13 14 reg [15:0]data_r;//温度数据寄存器 15 reg scl;//SCL 总线寄存器 16 reg sda_r;//SDA 总线寄存器 17 reg sda_link;//SDA 总线数据方向标志 18 reg [7:0]scl_cnt;//SCL 时钟产生计数器 19 reg [2:0]cnt;//用来标记SCL时钟计数器 20 reg [25:0]timer_cnt;//定时器,每隔2s 读取一次温度数据 21 reg [3:0]data_cnt;//数据串并转换寄存器 22 reg [7:0]address_reg;//器件地址寄存器 23 reg [8:0]state;//状态寄存器 24 // 25 //进程1、2、3:产生SCL 总线时钟 26 always@(posedge clk or negedge rst_n) 27 begin 28 if(!rst_n) 29 scl_cnt <= 8'd0; 30 else if(scl_cnt == 8'd199) 31 scl_cnt <= 8'd0; 32 else 33 scl_cnt <= scl_cnt + 1'b1; 34 end 35 always@(posedge clk or negedge rst_n) 36 begin 37 if(!rst_n) 38 cnt <= 3'd5; 39 else 40 case(scl_cnt) 41 8'd49: cnt <= 3'd1;//高电平中间 42 8'd99: cnt <= 3'd2;//下降沿 43 8'd149:cnt <= 3'd3;//低电平中间 44 8'd199:cnt <= 3'd0;//上升沿 45 default: cnt <= 3'd5; 46 endcase 47 end 48 `define SCL_HIG (cnt == 3'd1) 49 `define SCL_NEG (cnt == 3'd2) 50 `define SCL_LOW (cnt == 3'd3) 51 `define SCL_POS (cnt == 3'd0) 52 always@(posedge clk or negedge rst_n) 53 begin 54 if(!rst_n) 55 scl <= 1'b0; 56 else if(`SCL_POS) 57 scl <= 1'b1; 58 else if(`SCL_NEG) 59 scl <= 1'b0; 60 end 61 // 62 //进程4:定时器,每隔1s 读取一次温度数据 63 always@(posedge clk or negedge rst_n) 64 begin 65 if(!rst_n) 66 timer_cnt <= 26'd0; 67 else if(timer_cnt == 26'd49999999) 68 timer_cnt <= 26'd0; 69 else 70 timer_cnt <= timer_cnt + 1'b1; 71 end 72 // 73 //状态机定义 74 parameter IDLE = 9'b0_0000_0000, 75 START = 9'b0_0000_0010, 76 ADDRESS = 9'b0_0000_0100, 77 ACK1 = 9'b0_0000_1000, 78 READ1 = 9'b0_0001_0000, 79 ACK2 = 9'b0_0010_0000, 80 READ2 = 9'b0_0100_0000, 81 NACK = 9'b0_1000_0000, 82 STOP = 9'b1_0000_0000; 83 `define DEVICE_ADDRESS 8'b1001_0001//器件地址,读操作 84 // 85 //进程5:状态机描述 86 always@(posedge clk or negedge rst_n) 87 begin 88 if(!rst_n) 89 begin 90 data_r <= 16'd0; 91 sda_r <= 1'b1; 92 sda_link <= 1'b1; 93 state <= IDLE; 94 address_reg <= 15'd0; 95 data_cnt <= 4'd0; 96 end 97 else 98 case(state) 99 IDLE: 100 begin 101 sda_r <= 1'b1; 102 sda_link <= 1'b1; 103 if(timer_cnt == 26'd49999999) 104 state <= START; 105 else 106 state <= IDLE; 107 end 108 START://产生起始信号 109 begin 110 if(`SCL_HIG) 111 begin 112 sda_r <= 1'b0; 113 sda_link <= 1'b1; 114 address_reg <= `DEVICE_ADDRESS; 115 state <= ADDRESS; 116 data_cnt <= 4'd0; 117 end 118 else 119 state <= START; 120 end 121 ADDRESS://主机对器件进行寻址 122 begin 123 if(`SCL_LOW) 124 begin 125 if(data_cnt == 4'd8)//寻址完成,SDA改变方向,器件准备输出应答讯号 126 begin 127 state <= ACK1; 128 data_cnt <= 4'd0; 129 sda_r <= 1'b1; 130 sda_link <= 1'b0; 131 end 132 else//寻址过程中,SDA对器件作为输入 133 begin 134 state <= ADDRESS; 135 data_cnt <= data_cnt + 1'b1; 136 case(data_cnt) 137 4'd0: sda_r <= address_reg[7]; 138 4'd0: sda_r <= address_reg[7]; 139 4'd1: sda_r <= address_reg[6]; 140 4'd2: sda_r <= address_reg[5]; 141 4'd3: sda_r <= address_reg[4]; 142 4'd4: sda_r <= address_reg[3]; 143 4'd5: sda_r <= address_reg[2]; 144 4'd6: sda_r <= address_reg[1]; 145 4'd7: sda_r <= address_reg[0]; 146 default: ; 147 endcase 148 end 149 end 150 else 151 state <= ADDRESS; 152 end 153 ACK1://器件输出应答信号 154 begin 155 if(!sda && (`SCL_HIG)) 156 state <= READ1; 157 else if(`SCL_NEG) 158 state <= READ1; 159 else 160 state <= ACK1; 161 end 162 READ1://读器件数据,高字节 163 begin 164 if((`SCL_LOW) && (data_cnt == 4'd8))//读高字节数据完成,SDA改变方向,主机准备输出应答讯号 165 begin 166 state <= ACK2; 167 data_cnt <= 4'd0; 168 sda_r <= 1'b1; 169 sda_link <= 1'b1; 170 end 171 else if(`SCL_HIG)//读数据过程中,器件作为输出,这里有疑问,不是应该的等SCL一个时钟吗?SCL_HIG 172 begin 173 data_cnt <= data_cnt + 1'b1; 174 case(data_cnt) 175 4'd0: data_r[15] <= sda; 176 4'd1: data_r[14] <= sda; 177 4'd2: data_r[13] <= sda; 178 4'd3: data_r[12] <= sda; 179 4'd4: data_r[11] <= sda; 180 4'd5: data_r[10] <= sda; 181 4'd6: data_r[9] <= sda; 182 4'd7: data_r[8] <= sda; 183 default: ; 184 endcase 185 end 186 else 187 state <= READ1; 188 end 189 ACK2://主机输出应答讯号 190 begin 191 if(`SCL_LOW) 192 sda_r <= 1'b0; 193 else if(`SCL_NEG) 194 begin 195 sda_r <= 1'b1; 196 sda_link <= 1'b0; 197 state <= READ2; 198 end 199 else 200 state <= ACK2; 201 end 202 READ2://读低字节数据 203 begin 204 if((`SCL_LOW) && (data_cnt == 4'd8)) 205 begin 206 state <= NACK; 207 data_cnt <= 4'd0; 208 sda_r <= 1'b1; 209 sda_link <= 1'b1; 210 end 211 else if(`SCL_HIG) 212 begin 213 data_cnt <= data_cnt + 1'b1; 214 case(data_cnt) 215 4'd0: data_r[7] <= sda; 216 4'd1: data_r[6] <= sda; 217 4'd2: data_r[5] <= sda; 218 4'd3: data_r[4] <= sda; 219 4'd4: data_r[3] <= sda; 220 4'd5: data_r[2] <= sda; 221 4'd6: data_r[1] <= sda; 222 4'd7: data_r[0] <= sda; 223 default: ; 224 endcase 225 end 226 else 227 state <= READ2; 228 end 229 NACK://主机非应答 230 begin 231 if(`SCL_LOW) 232 begin 233 state <= STOP; 234 sda_r <= 1'b0; 235 end 236 else 237 state <= NACK; 238 end 239 STOP: 240 begin 241 if(`SCL_HIG) 242 begin 243 state <= IDLE; 244 sda_r <= 1'b1; 245 end 246 else 247 state <= STOP; 248 end 249 default: state <= IDLE; 250 endcase 251 end 252 assign sda = sda_link ? sda_r: 1'bz; 253 assign data = data_r; 254 endmodule
3. 这个代码需要好好研究下,有疑问的地方,data_cnt <= data_cnt + 1'b1;每次读一位的时候,SCL应该有一个时钟,按照这个时钟去读的,为啥代码使用data_cnt这个变量,感觉不对啊?这里不是很明白
1 begin 2 134 state <= ADDRESS; 3 135 data_cnt <= data_cnt + 1'b1; 4 136 case(data_cnt) 5 137 4'd0: sda_r <= address_reg[7]; 6 138 4'd0: sda_r <= address_reg[7]; 7 139 4'd1: sda_r <= address_reg[6]; 8 140 4'd2: sda_r <= address_reg[5]; 9 141 4'd3: sda_r <= address_reg[4]; 10 142 4'd4: sda_r <= address_reg[3]; 11 143 4'd5: sda_r <= address_reg[2]; 12 144 4'd6: sda_r <= address_reg[1]; 13 145 4'd7: sda_r <= address_reg[0]; 14 146 default: ; 15 147 endcase 16 148 end
转载于:https://www.cnblogs.com/429512065qhq/p/8093270.html
cyclone4驱动LM75A温湿度传感器学习相关推荐
- ⑦ ESP8266 开发学习笔记_By_GYC 【ESP8266 驱动 DHT11 温湿度传感器】
目录 一.准备材料 二.硬件连接 三.软件编程 1.修改工程名 2.添加组件 3.编程 4.反馈结果 5.核心代码 四.总结 ⑦ ESP8266 开发学习笔记_By_GYC [ESP8266 驱动 D ...
- NORDIC52832 TWI(I2C) 特点 (2)驱动CHT8305C 温湿度传感器
1. nRF52832 TWI特点 本章描述的是 TWIM (带 EasyDMA 的 TWI 主机) ),本章中的 TWI 均指的是 TWIM 即 TWI 主机. nRF 52832 片内集成的 TW ...
- STM32驱动 HTU21D温湿度传感器
STM32驱动 HTU21D温湿度传感器 温湿度传感器模块HTU21D产品简介 基于法国Humirel公司高性能的湿度感应元件制成,新一代HTU21D温度和湿度传感器在尺寸与智能方面建立了新的标准:它 ...
- 51单片机驱动AHT10温湿度传感器
51单片机驱动AHT10温湿度传感器 AHT10温湿度传感器 AHT10参数 工作原理 数据转换 驱动 接线 驱动代码 实验结果 AHT10温湿度传感器 AHT10是新一代温湿度传感器,传感器输出经过 ...
- STM32F1驱动AM2302温湿度传感器
先来个AM2302的自我介绍: AM2302数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器.它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性与卓 ...
- STM32F103使用硬件IIC驱动SHT30温湿度传感器
文章目录 前言 一.SHT30温湿度传感器原理图 二.代码部分 1.SHT30.c文件 2.SHT30.h文件 总结 前言 SHT30是一种常见的温湿度传感器,该传感器广泛应用于各种场景,小米的温湿度 ...
- 【STM32】【STM32CubeMX】STM32CubeMX的使用之四:IIC总线协议驱动SHT30温湿度传感器
文章目录 0.前言 1.传感器介绍 1.1.传感器简介 1.2.传感器板原理图 1.3.传感器引脚定义 1.4.数据采集工作流程 1.4.1.单次数据采集模式 1.4.2.周期型数据采集模式 1.5. ...
- [单片机芯片]CH32V307驱动单总线温湿度传感器DHT22
手头有一个DHT22温湿度传感器和CH32V307开发板,可玩性极强.DHT22是已校准的数字温湿度传感器,用于检测环境温湿度,采用DHT22(AM2302),标准单总线接口.拥有比常见的DHT11更 ...
- STM32模拟IIC驱动sht30温湿度传感器
最近有在使用sht30这个传感器,相比于新手常用的dht11传感器,sht30更精确,自己花了半小时调好了 所以拿出来分享给大家. sht30外观 驱动不是自己写的, 是采用CSDN上的一位朋友的 , ...
- STC89C52驱动DHT11温湿度传感器测试笔记
经常有在视频中看到网友应用DHT11采集温湿度,其次它与sht11这片温湿度传感就一字之差,臆想着它俩是否是互换代用,上某宝查一查发现这价格很亲民,果断的下单了一片去尝试着搞通它,快递收到后因为时间问 ...
最新文章
- Towards Real-time Semantic RGB-D SLAM in Dynamic Environments(动态语义SLAM)
- 中科院陆汝钤获吴文俊人工智能最高成就奖,百度王海峰获吴文俊人工智能杰出贡献奖...
- oracle的日志分析工具,oracle日志分析工具LogMiner使用(实战)
- Ubuntu16.04安装nginx
- 简易 责任链的两种实现方式
- request.getcontextPath() 理解
- 连接思科无线经常出现获取不到地址_思科(cisco)路由器登录IP地址默认密码说明...
- 抓取Web网页数据分析
- Visio2019安装
- 深入理解vsto,开发word插件的利器
- css 居中对齐在实现方式
- php ms5解密,「phpmd5解密」解析php混淆加密解密的手段
- Unity3D教程:iTween插件的介绍和用法
- PostMan中文设置
- etl构建数据仓库五步法_ETL构建数据仓库五步法
- 《起跑吧,Opa》 -- 中译本 第一章 初识Opa
- CUDA编程--邻近点查询
- 程序员圈 内的 鄙视链
- 靴子落地,火山引擎官宣进军云市场
- java计算机毕业设计学习社区管理系统源码+数据库+系统+lw文档+部署
热门文章
- html输入正确用户名和密码,为什么输入正确用户名和密码还会提示“用户名或密码错误”?...
- iOS AVCapture前置摄像头不显示镜像翻转
- ios 企业签 plist 安装 通用模板
- 网狐大联盟服务器环境搭建完整教程
- PAT-ADVANCED1013——Battle Over Cities
- 自定义Unity调色板
- PyTorch 1.x 常用知识
- 两代 2011/2014 Mac Mini 硬盘SSD性能提升研究。(SSD固态硬盘研究)
- 易学笔记-系统分析师考试-第9章 系统规划/9.5 成本效益分析技术/9.5.3 投资回收期和投资回报率
- python模拟键盘上键和回车_python + selenium 模拟键盘升级版PyUserInput