当前位置:   article > 正文

FPGA读取SHT31温湿度传感器(附驱动代码及tb)

FPGA读取SHT31温湿度传感器(附驱动代码及tb)

一、芯片基本信息

SHT30 是瑞士盛世瑞恩生产出品的一个温湿度传感器,该SHT3X是一个系列,一共有SHT30/SHT31/SHT35这三个品类, SHT30——低成本版本,±3% RH精度;SHT31——标准版本,±2% RH精度;RH精度SHT35——高端版本,±1.5% RH;

一般生活内监测用SHT30即可。

SHT30性能参数如下:

温度检测范围:5-60℃

湿度:20%-80%RH

宽电压:2.4-5.5v供电

多种测量模式,具备单次检测/循环检测功能,类似单片机的AD采样

具备温湿度检测自动应答功能(4Hz),这个对于单片机休眠唤醒很有帮助。可以省去RTC唤醒。

具备自检测功能,通过开启加热功能,主动改变设备温度,去确认温湿度传感器是否正常,这个对于无人值守非常有意义。

超低功耗:测量时800uA,待机2uA,更强大的是设备自己具备低功耗管理,无需单片机接入,电池供电必备。

精度越高,对于PCB的走线和设备安装位置要求越高,虽然只有8pin,但是布线不好,安装位置不对,也许还不如热敏电阻的精度。

首先对芯片中对于程序编程有意义的重要信息进行提取:

引脚

IIC总线挂载芯片区分

不同模式下的时序配置

根据实际需求选择合适的模式,来进行程序的设计和对应的寄存器配置。

1、Measurement Commands for Single Shot Data Acquisition Mode

2、Readout of Measurement Results for Single Shot Mode

3、Readout of Measurement Results for Periodic Mode

其他

1、软复位命令

2、检验和

3、温度数据计算

二、驱动设计

1- 设计时序

要注意驱动程序中的一些时序信息参数要求,芯片的设计满足的范围,FPGA驱动程序控制时主要注意建立保持时间满足该款芯片的设计指标。具体可以在程序仿真和ILA/逻辑分析仪测试时确定自身驱动程序是否需要优化。

2- 程序控制流程

由于涉及到CRC校验和的情况,对于SHT31温度传感器的设定需要进行控制

根据该时序图的配置模式为设计参考:

IIC的程序调用状态机为以下几个部分(IIC的驱动程序这里不做赘述,百度可复制粘贴 >.^ ):

start → send_byte(0x88) / {7’h44,7’h00}→ wait_ack → send_byte(0x2c) → wait_ack → send_byte(0x06) → wait_ack → stop → delay_us(200) → start → send_byte(0x89) / {7’h44,7’h01} → wait_ack → read_byte(tem[15:8]) → wait_ack → read_byte(temp[7:0]) → send_ack → read_byte(crc) → send_ack → read_byte(hum[15:8]) → send_ack → read_byte(hum[7:0]) → send_ack → read_byte(crc) → send_nack → stop

对于后面的数据不用的,比如只要温度数据,可以直接主机发送NACK结束数据的采集。、

IIC驱动的状态机的顺序如下:

3- 单芯片温湿度数据测试

为了验证程度代码以及芯片的控制方式是否合理,先采用单芯片模式对一个芯片进行控制。

对于中途的仿真和连接芯片后的示波器信号读取后,对细节问题进行优化修改后,测试结果:

① 仿真测试情况

为了验证状态机的设计合理性和调用驱动时是否有错误,需要利用tb仿真文件对代码进行验证。

② ILA数据读取测试情况

③ 示波器测试情况

④ 温湿度数据计算验证

在没有写浮点数值近似处理计算模块前,验证ILA获取的温湿度数据数值是否正常,采用计算机计算即可,ILA上对温湿度数据的显示数值修改为手册中计算的十进制格式。

对第②步中的温湿度数值代入计算后:

所以测试的温湿度计算结果为: 21.9℃ , 40.3% RH。符合实际情况。

4- 双芯片温湿度测试

通过硬件电源接入还是GND接入可使得一组IIC总线上最多能挂载两个芯片,通过以上对单芯片的温湿度数据读取测试中,完善细节后,修改为双芯片控制的配置。

① 仿真测试情况

注意在仿真中需要分别模拟从机芯片SHT31给ACK信号,和不给ACK信号的结果。

给ACK信号时,两个芯片的数据读取整个过程共计消耗2ms的时间(仿真中的数据模拟真实情况下,不同于上述单芯片仿真时为了尽快产生仿真结果模拟缩小后的时间,这里我称 “仿真相对论效应 ” )。

从机给NACK信号时,在芯片1为NACK的时候,对芯片2进行访问控制:

② ILA 测试情况

连接上硬件模块后,ILA抓取实际的信号数据值。

三、可能的风险问题及分析

如果ILA测试中发现一个芯片有ACK然后有数据,一个芯片没ACK或者数据结果全为高(65535)时,需要排查硬件芯片上是否虚焊或者其他可能性,包括代码BUG(如SDA的结束拉高是否进入休眠状态等,在进入休眠状态后又启动的问题)。

四、参考代码(只是参考,限于能力毕竟瞎写的)

1- 顶层程序

  1. `timescale 1ns / 1ps
  2. //
  3. // Company:
  4. // Engineer:
  5. //
  6. // Create Date: 2023/01/11 13:45:18
  7. // Design Name: taotao
  8. // Module Name: TOP
  9. // Project Name:
  10. // Target Devices:
  11. // Tool Versions:
  12. // Description:
  13. //
  14. // Dependencies:
  15. //
  16. // Revision:
  17. // Revision 0.01 - File Created
  18. // Additional Comments:
  19. //
  20. //
  21. module TOP(
  22. input clk_p,clk_n , // 200M
  23. input rst ,
  24. output SCL_A ,
  25. inout SDA_A
  26. );
  27. wire clk_50m ;
  28. wire clk_10m ;
  29. wire locked ;
  30. wire key_ready_vio;
  31. wire [15:0] rd_data1 ;
  32. wire [15:0] rd_data2 ;
  33. clk_wiz_0 clk_wiz_0_inst
  34. (
  35. // Clock out ports
  36. .clk_out1_50m(clk_50m), // output clk_out1_50m
  37. .clk_out2_10m(clk_10m), // output clk_out2_10m
  38. // Status and control signals
  39. .reset(rst), // input reset
  40. .locked(locked), // output locked
  41. // Clock in ports
  42. .clk_in1_p(clk_p), // input clk_in1_p
  43. .clk_in1_n(clk_n)); // input clk_in1_n
  44. IOBUF #(
  45. .DRIVE(12), // Specify the output drive strength
  46. .IBUF_LOW_PWR("TRUE"), // Low Power - "TRUE", High Performance = "FALSE"
  47. .IOSTANDARD("DEFAULT"), // Specify the I/O standard
  48. .SLEW("SLOW") // Specify the output slew rate
  49. ) IOBUF_iic_sdio_A (
  50. .O (sda_i_A), // Buffer output
  51. .IO (SDA_A), // Buffer inout port (connect directly to top-level port)
  52. .I (sda_o_A), // Buffer input
  53. .T (~sda_cs_A) // 3-state enable input, high=input, low=output
  54. );
  55. vio_0 vio_0_inst (
  56. .clk(clk_50m), // input wire clk
  57. .probe_out0(key_ready_vio) // output wire [0 : 0] probe_out0
  58. );
  59. SHT31_IIC_driver(
  60. . clk ( clk_50m ) , // 50M for SCL 6.66K
  61. . rst ( rst ) ,
  62. . I2C_SCL ( SCL_A ) ,
  63. . I2C_SDA_out ( sda_o_A ) ,
  64. . I2C_SDA_in ( sda_i_A ) ,
  65. . I2C_SDA_oe ( sda_cs_A ) ,
  66. . ready ( key_ready_vio ) , // write and read ready
  67. // . tem ( rd_data1 ) ,
  68. // . hum ( rd_data2 ) ,
  69. . dout_ack ( ) , // write data acknowledge by slave device
  70. . din_valid ( )
  71. );
  72. endmodule

2- 驱动程序

  1. `timescale 1ns / 1ps
  2. //
  3. // Company:
  4. // Engineer:
  5. //
  6. // Create Date: 2023/01/10 18:50:40
  7. // Design Name: taotao
  8. // Module Name: I2C_transmitter
  9. // Project Name:
  10. // Target Devices:
  11. // Tool Versions:
  12. // Description:
  13. //
  14. // Dependencies:
  15. //
  16. // Revision:
  17. // Revision 0.01 - File Created
  18. // Additional Comments:
  19. //
  20. //
  21. module SHT31_IIC_driver(
  22. input clk , // 50M-SCL to give scl 66.66K
  23. input rst ,
  24. output reg I2C_SCL ,
  25. output reg I2C_SDA_out ,
  26. input I2C_SDA_in ,
  27. output reg I2C_SDA_oe ,
  28. input ready , // write and read ready
  29. output reg [15:0] tem1 ,
  30. output reg [15:0] tem2 ,
  31. output reg dout_ack , // write data acknowledge by slave device
  32. // output reg [7:0] din , // for detailed data, it can be changed and given name as belows reg regcognization
  33. output reg din_valid
  34. // input [6:0] dev_addr , // device address
  35. // input [7:0] reg_addr , // register address
  36. // input rdh_wrl , // 1 is read, 0 is write
  37. // input [7:0] dout , // write data
  38. // input [3:0] dout_length , // the number of bytes of write and read data
  39. );
  40. reg [7:0] din ;
  41. reg [7:0] tem_h1 ;
  42. reg [7:0] tem_h2 ;
  43. reg [7:0] tem_l1 ;
  44. reg [7:0] tem_l2 ;
  45. reg [7:0] hum_h ;
  46. reg [7:0] hum_l ;
  47. reg [7:0] crc_tem ;
  48. reg [7:0] crc_hum ;
  49. // reg [15:0] tem ;
  50. reg [15:0] hum ;
  51. // SCL clock generator, 100MHz => 200kHz
  52. reg [11:0] I2C_SCL_counter;
  53. reg I2C_SCL_en; // enable signal, SCL only driven when this one asserted
  54. reg I2C_SCL_d;
  55. wire I2C_SCL_posedge;
  56. wire I2C_SCL_negedge;
  57. //reg [3:0] dout_length = 4'd1;
  58. reg [6:0] dev_addr1 = 7'h44 ;
  59. reg [6:0] dev_addr2 = 7'h45 ;
  60. reg addr_transfer = 1'b0 ;
  61. reg delay_en = 1'b0;
  62. //ila_8 sht_31_inst (
  63. // .clk(clk), // input wire clk
  64. // .probe0( I2C_SCL ), // input wire [0:0] probe0
  65. // .probe1( I2C_SDA_out), // input wire [0:0] probe1
  66. // .probe2( I2C_SDA_in ), // input wire [0:0] probe2
  67. // .probe3( I2C_SDA_oe ), // input wire [0:0] probe3
  68. // .probe4( ready ), // input wire [0:0] probe4
  69. // .probe5( dout_ack ), // input wire [0:0] probe5
  70. // .probe6(din_valid), // input wire [0:0] probe6
  71. // .probe7 (rst ), // input wire [0:0] probe7
  72. // .probe8 (din ), // input wire [7:0] probe8
  73. // .probe9 (tem_h1 ), // input wire [7:0] probe9
  74. // .probe10(tem_l1 ), // input wire [7:0] probe10
  75. // .probe11(tem_h2 ), // input wire [7:0] probe11
  76. // .probe12(tem_l2 ), // input wire [7:0] probe12
  77. // .probe13({addr_transfer,delay_en,crc_hum[7:2]}), // input wire [7:0] probe13
  78. // .probe14(crc_hum), // input wire [7:0] probe14
  79. // .probe15(tem1 ), // input wire [15:0] probe15
  80. // .probe16(tem2 ) // input wire [15:0] probe16
  81. //);
  82. //reg [7:0] reg_addr ;
  83. //reg rdh_wrl ;
  84. always @(posedge clk) begin
  85. if(rst | ~(I2C_SCL_en)) begin
  86. I2C_SCL_counter <= 12'd0;
  87. I2C_SCL <= 1'b1;
  88. end
  89. else if(I2C_SCL_counter < 12'd300) begin // 50M-SCL 100k
  90. // else if(I2C_SCL_counter < 12'd1500) begin // 50M-SCL 20k
  91. // else if(I2C_SCL_counter < 12'd150) begin // 50M-SCL 200K
  92. I2C_SCL_counter <= I2C_SCL_counter + 12'd1;
  93. end
  94. else begin
  95. I2C_SCL_counter <= 12'd0;
  96. I2C_SCL <= ~I2C_SCL;
  97. end
  98. end
  99. // detection of falling edge of SCL
  100. always @(posedge clk) begin
  101. I2C_SCL_d <= I2C_SCL;
  102. end
  103. assign I2C_SCL_negedge = ({I2C_SCL_d,I2C_SCL}==2'b10) ? 1'b1 : 1'b0;
  104. assign I2C_SCL_posedge = ({I2C_SCL_d,I2C_SCL}==2'b01) ? 1'b1 : 1'b0;
  105. // ready rising edge detection
  106. reg ready_d;
  107. wire ready_posedge;
  108. always @(posedge clk) begin
  109. ready_d <= ready;
  110. end
  111. assign ready_posedge = ({ready_d, ready}==2'b01) ? 1'b1 : 1'b0;
  112. // state machine
  113. //parameter [3:0] IDLE = 0;
  114. //parameter [3:0] START = 1;
  115. //parameter [3:0] ADDR_DEV_WRITE = 2;
  116. //parameter [3:0] ADDR_REG = 3;
  117. //parameter [3:0] REPEAT_START = 4;
  118. //parameter [3:0] ADDR_DEV_READ = 5;
  119. //parameter [3:0] WRITE = 6;
  120. //parameter [3:0] READ = 7;
  121. //parameter [3:0] ENDING = 8;
  122. localparam IDLE = 5'd00 ,
  123. START_1 = 5'd01 ,
  124. SEND_ADDR_W = 5'd02 , //0x88
  125. ACK_1 = 5'd03 ,
  126. SEND_COM_H = 5'd04 , //0x2c
  127. ACK_2 = 5'd05 ,
  128. SEND_COM_L = 5'd06 , //0x06
  129. ACK_3 = 5'd07 ,
  130. STOP = 5'd08 ,
  131. DELAY_1 = 5'd09 , //500ms
  132. START_2 = 5'd10 ,
  133. SEND_ADDR_R = 5'd11 , //0x89
  134. ACK_4 = 5'd12 ,
  135. READ_TEM_H = 5'd13 ,
  136. ACK_5 = 5'd14 ,
  137. READ_TEM_L = 5'd15 ,
  138. ACK_6 = 5'd16 ,
  139. READ_CRC_1 = 5'd17 ,
  140. ACK_7 = 5'd18 ,
  141. READ_HUM_H = 5'd19 ,
  142. ACK_8 = 5'd20 ,
  143. READ_HUM_L = 5'd21 ,
  144. ACK_9 = 5'd22 ,
  145. READ_CRC_2 = 5'd23 ,
  146. NACK = 5'd24 ,
  147. END_STOP = 5'd25 ,
  148. ENDING = 5'd26 ,
  149. DELAY = 5'd27 ;
  150. reg [4:0] state;
  151. reg [4:0] next_state;
  152. reg [3:0] I2C_SCL_count;
  153. reg [7:0] dout_buf;
  154. reg [3:0] dout_count;
  155. reg [7:0] din_buf;
  156. reg [7:0] din_buf1;
  157. reg [7:0] din_buf2;
  158. reg [12:0] end_count;
  159. reg [27:0] delay_cnt = 28'd0 ;
  160. always @(posedge clk or posedge rst) begin
  161. if(rst) begin
  162. state <= IDLE;
  163. end
  164. else begin
  165. state <= next_state;
  166. end
  167. end
  168. always @(posedge clk) begin
  169. case(state)
  170. IDLE: begin
  171. dout_ack <= 1'b0;
  172. I2C_SCL_count <= 4'd0;
  173. din <= 8'h00;
  174. din_valid <= 1'b0;
  175. I2C_SDA_out <= 1'b1;
  176. I2C_SDA_oe <= 1'b0;
  177. // next_state <= START_1;
  178. dout_buf <= 8'h00;
  179. I2C_SCL_en <= 1'b0;
  180. dout_count <= 4'd0;
  181. end_count <= 13'd0;
  182. if(addr_transfer) begin
  183. if(delay_cnt >= 28'd25000) begin // 500us
  184. // if(delay_cnt >= 28'd2500) begin // 50us for simulation
  185. delay_cnt <= 28'd0;
  186. next_state <= START_1;
  187. end else begin
  188. delay_cnt <= delay_cnt + 1'b1;
  189. // next_state <= IDLE; // �����ڴ˴����Ӹ���䣬������ظ�ִ�и�״̬
  190. end
  191. end else begin
  192. next_state <= START_1;
  193. end
  194. end
  195. START_1: begin
  196. if(ready_posedge || addr_transfer) begin
  197. next_state <= SEND_ADDR_W;
  198. I2C_SDA_out <= 1'b0;
  199. I2C_SDA_oe <= 1'b0;
  200. I2C_SCL_en <= 1'b1;
  201. if(!addr_transfer) begin
  202. dout_buf <= {dev_addr1, 1'b0}; // the first step is always write register address
  203. end else if(addr_transfer) begin
  204. dout_buf <= {dev_addr2, 1'b0};
  205. end
  206. // dout_buf <= {dev_addr2, 1'b0}; // IIC does not support get both data at the same time
  207. end
  208. end
  209. SEND_ADDR_W: begin
  210. if(I2C_SCL_negedge && (I2C_SCL_count < 4'd8) ) begin
  211. I2C_SCL_count <= I2C_SCL_count + 4'd1;
  212. {I2C_SDA_out, dout_buf} <= {dout_buf, 1'b0};
  213. I2C_SDA_oe <= 1'b0;
  214. end
  215. else if(I2C_SCL_negedge && (I2C_SCL_count == 4'd8)) begin
  216. I2C_SCL_count <= I2C_SCL_count + 4'd1;
  217. I2C_SDA_oe <= 1'b1;
  218. // I2C_SDA_out<= 1'b1;
  219. end
  220. else if(I2C_SCL_posedge && (I2C_SCL_count == 4'd9)) begin
  221. I2C_SCL_count <= 4'd0;
  222. // dout_buf <= 8'h24;
  223. dout_buf <= 8'h2c;
  224. if(~I2C_SDA_in) begin // acknowledged by device and turn to ADDR_REG state
  225. next_state <= SEND_COM_H;
  226. end
  227. else begin // not acknowledged, go to ENDING
  228. next_state <= ENDING;
  229. if(addr_transfer) begin
  230. addr_transfer <= 1'b0;
  231. end else if(!addr_transfer) begin
  232. addr_transfer <= 1'b1;
  233. end
  234. end
  235. end
  236. end
  237. SEND_COM_H: begin
  238. if(I2C_SCL_negedge && (I2C_SCL_count < 4'd8) ) begin
  239. I2C_SCL_count <= I2C_SCL_count + 4'd1;
  240. {I2C_SDA_out, dout_buf} <= {dout_buf, 1'b0};
  241. I2C_SDA_oe <= 1'b0;
  242. end
  243. else if(I2C_SCL_negedge && (I2C_SCL_count == 4'd8)) begin
  244. I2C_SCL_count <= I2C_SCL_count + 4'd1;
  245. I2C_SDA_oe <= 1'b1;
  246. // I2C_SDA_out<= 1'b1;
  247. end
  248. else if(I2C_SCL_posedge && (I2C_SCL_count == 4'd9)) begin
  249. I2C_SCL_count <= 4'd0;
  250. // dout_buf <= 8'h0B;
  251. dout_buf <= 8'h06;
  252. if(~I2C_SDA_in) begin // acknowledged by device and turn to ADDR_REG state
  253. next_state <= SEND_COM_L;
  254. end
  255. else begin // not acknowledged, go to ENDING
  256. next_state <= ENDING;
  257. end
  258. end
  259. end
  260. SEND_COM_L: begin
  261. if(I2C_SCL_negedge && (I2C_SCL_count < 4'd8) ) begin
  262. I2C_SCL_count <= I2C_SCL_count + 4'd1;
  263. {I2C_SDA_out, dout_buf} <= {dout_buf, 1'b0};
  264. I2C_SDA_oe <= 1'b0;
  265. end
  266. else if(I2C_SCL_negedge && (I2C_SCL_count == 4'd8)) begin
  267. I2C_SCL_count <= I2C_SCL_count + 4'd1;
  268. I2C_SDA_oe <= 1'b1;
  269. end
  270. else if(I2C_SCL_posedge && (I2C_SCL_count == 4'd9)) begin
  271. I2C_SCL_count <= 4'd0;
  272. if( ~I2C_SDA_in) begin // acknowledged by device and turn to read state
  273. next_state <= STOP;
  274. // I2C_SDA_oe <= 1'b0;
  275. // I2C_SDA_out <= 1'b1;
  276. if(!addr_transfer) begin
  277. dout_buf <= {dev_addr1, 1'b1}; // the first step is always write register address
  278. end else if(addr_transfer) begin
  279. dout_buf <= {dev_addr2, 1'b1};
  280. end
  281. end
  282. // else if(~rdh_wrl && ~I2C_SDA_in) begin // acknowledged by device and turn to write state
  283. // next_state <= WRITE;
  284. // dout_buf <= dout;
  285. // end
  286. else begin // not acknowledged, go to ENDING
  287. next_state <= ENDING;
  288. end
  289. // I2C_SDA_oe <= 1'b0;
  290. end
  291. end
  292. STOP: begin
  293. // not stopped by master
  294. if(I2C_SCL_negedge) begin
  295. I2C_SDA_oe <= 1'b0;
  296. I2C_SDA_out <= 1'b0;
  297. end
  298. else if(I2C_SCL_posedge) begin // delay 10us to make sda high
  299. I2C_SCL_en <= 1'b0;
  300. delay_en <= 1'b1;
  301. // I2C_SDA_out <= 1'b1;
  302. // delay a while and pull down the SDA, indicating repeat start
  303. end else if(delay_cnt >= 28'd400) begin
  304. delay_cnt <= 1'd0;
  305. I2C_SDA_out <= 1'b1;
  306. delay_en <= 1'b0;
  307. end else if(delay_en) begin
  308. delay_cnt <= delay_cnt + 1'b1;
  309. end else if(~I2C_SCL_en && (end_count < 13'd5000)) begin //100us
  310. end_count <= end_count + 13'd1;
  311. end else if(~I2C_SCL_en) begin
  312. end_count <= 13'd0;
  313. I2C_SCL_en <= 1'b1;
  314. I2C_SDA_out <= 1'b0;
  315. next_state <= SEND_ADDR_R;
  316. end else begin
  317. // delay_cnt <= delay_cnt + 1'b1;
  318. end
  319. end
  320. // SEND_COM_L: begin
  321. // if(I2C_SCL_negedge && (I2C_SCL_count < 4'd8) ) begin
  322. // I2C_SCL_count <= I2C_SCL_count + 4'd1;
  323. // {I2C_SDA_out, dout_buf} <= {dout_buf, 1'b0};
  324. // I2C_SDA_oe <= 1'b0;
  325. // end
  326. // else if(I2C_SCL_negedge && (I2C_SCL_count == 4'd8)) begin
  327. // I2C_SCL_count <= I2C_SCL_count + 4'd1;
  328. // I2C_SDA_oe <= 1'b1;
  329. I2C_SDA_out<= 1'b1;
  330. // end
  331. // else if(I2C_SCL_posedge && (I2C_SCL_count == 4'd9)) begin
  332. // I2C_SCL_count <= 4'd0;
  333. // if(~I2C_SDA_in) begin // acknowledged by device and turn to ADDR_REG state
  334. // next_state <= STOP;
  335. I2C_SDA_out <= 1'b1;
  336. // I2C_SDA_oe <= 1'b0;
  337. // end
  338. // else begin // not acknowledged, go to ENDING
  339. // next_state <= ENDING;
  340. // end
  341. // end
  342. // end
  343. // STOP: begin
  344. // dout_ack <= 1'b0;
  345. // I2C_SCL_count <= 4'd0;
  346. // din <= 8'h00;
  347. // din_valid <= 1'b0;
  348. // I2C_SDA_out <= 1'b1;
  349. // I2C_SDA_oe <= 1'b0;
  350. // next_state <= DELAY_1;
  351. // dout_buf <= 8'h00;
  352. // I2C_SCL_en <= 1'b0;
  353. // dout_count <= 4'd0;
  354. // end_count <= 8'd0;
  355. // end
  356. // DELAY_1:begin
  357. if(delay_cnt >= 28'd25_000_000) begin // 500ms
  358. if(delay_cnt >= 28'd25000) begin // 500us for tb simulation
  359. // if(delay_cnt >= 28'd2500) begin // 50us for tb simulation
  360. // delay_cnt <= 28'd0;
  361. // next_state <= START_2;
  362. // end else begin
  363. // delay_cnt <= delay_cnt + 1'd1;
  364. // end
  365. // end
  366. // START_2: begin
  367. // next_state <= SEND_ADDR_R;
  368. // dout_buf <= {dev_addr, 1'b1}; // the first step is always write register address
  369. // I2C_SDA_out <= 1'b0;
  370. // I2C_SDA_oe <= 1'b0;
  371. // I2C_SCL_en <= 1'b1;
  372. // end
  373. SEND_ADDR_R: begin
  374. if(I2C_SCL_negedge && (I2C_SCL_count < 4'd8) ) begin
  375. I2C_SCL_count <= I2C_SCL_count + 4'd1;
  376. {I2C_SDA_out, dout_buf} <= {dout_buf, 1'b0};
  377. I2C_SDA_oe <= 1'b0;
  378. end
  379. else if(I2C_SCL_negedge && (I2C_SCL_count == 4'd8)) begin
  380. I2C_SCL_count <= I2C_SCL_count + 4'd1;
  381. I2C_SDA_oe <= 1'b1; // master send ack to slaver
  382. end
  383. else if(I2C_SCL_posedge && (I2C_SCL_count == 4'd9)) begin
  384. I2C_SCL_count <= 4'd0;
  385. if(~I2C_SDA_in) begin // acknowledged by device and turn to ADDR_REG state
  386. next_state <= READ_TEM_H;
  387. // I2C_SDA_oe <= 1'b1;
  388. end
  389. else begin // not acknowledged, go to ENDING
  390. next_state <= STOP;
  391. end
  392. end
  393. end
  394. READ_TEM_H: begin
  395. if(I2C_SCL_posedge && (I2C_SCL_count < 4'd8) ) begin
  396. I2C_SCL_count <= I2C_SCL_count + 4'd1;
  397. // din_buf <= {din_buf[6:0], I2C_SDA_in};
  398. din_valid <= 1'b0;
  399. I2C_SDA_oe <= 1'b1;
  400. if(!addr_transfer) begin
  401. din_buf1 <= {din_buf1[6:0], I2C_SDA_in};
  402. end else if(addr_transfer) begin
  403. din_buf2 <= {din_buf2[6:0], I2C_SDA_in};
  404. end
  405. end
  406. else if(I2C_SCL_negedge && (I2C_SCL_count == 4'd8)) begin
  407. I2C_SCL_count <= I2C_SCL_count + 4'd1;
  408. din_valid <= 1'b1;
  409. I2C_SDA_oe <= 1'b0;
  410. I2C_SDA_out <= 1'b0; // send ack to salver
  411. if(!addr_transfer) begin
  412. din <= din_buf1; // because not assure this data, should give it detailed name like tem_h
  413. tem_h1 <= din_buf1;
  414. end else if(addr_transfer) begin
  415. din <= din_buf2; // because not assure this data, should give it detailed name like tem_h
  416. tem_h2 <= din_buf2;
  417. end
  418. end
  419. else if(I2C_SCL_negedge && (I2C_SCL_count == 4'd9)) begin
  420. I2C_SCL_count <= 4'd0;
  421. I2C_SDA_oe <= 1'b1;
  422. // if(dout_count == (dout_length - 4'd1) ) begin // already read enough, go to next
  423. next_state <= READ_TEM_L;
  424. dout_count <= 4'd0;
  425. // end
  426. // else begin // need more data, continue in READ state
  427. // next_state <= READ_TEM_H;
  428. // dout_count <= dout_count + 4'd1;
  429. // end
  430. end
  431. else begin
  432. din_valid <= 1'b0;
  433. end
  434. end
  435. READ_TEM_L:begin
  436. if(I2C_SCL_posedge && (I2C_SCL_count < 4'd8) ) begin
  437. I2C_SCL_count <= I2C_SCL_count + 4'd1;
  438. din_valid <= 1'b0;
  439. I2C_SDA_oe <= 1'b1;
  440. if(!addr_transfer) begin
  441. din_buf1 <= {din_buf1[6:0], I2C_SDA_in};
  442. end else if(addr_transfer) begin
  443. din_buf2 <= {din_buf2[6:0], I2C_SDA_in};
  444. end
  445. end
  446. else if(I2C_SCL_negedge && (I2C_SCL_count == 4'd8)) begin
  447. I2C_SCL_count <= I2C_SCL_count + 4'd1;
  448. din_valid <= 1'b1;
  449. I2C_SDA_oe <= 1'b0;
  450. I2C_SDA_out <= 1'b1; // send nack to salver ,and end to get temp
  451. if(!addr_transfer) begin
  452. din <= din_buf1; // because not assure this data, should give it detailed name like tem_h
  453. tem_l1 <= din_buf1;
  454. end else if(addr_transfer) begin
  455. din <= din_buf2; // because not assure this data, should give it detailed name like tem_h
  456. tem_l2 <= din_buf2;
  457. end
  458. end
  459. else if(I2C_SCL_negedge && (I2C_SCL_count == 4'd9)) begin
  460. I2C_SCL_count <= 4'd0;
  461. // I2C_SDA_oe <= 1'b1;
  462. // next_state <= READ_CRC_1; // enough for temp
  463. I2C_SDA_oe <= 1'b0;
  464. I2C_SDA_out <= 1'b0;
  465. next_state <= END_STOP;
  466. dout_count <= 4'd0;
  467. if(!addr_transfer) begin
  468. tem1 <= {tem_h1,tem_l1}; // to build this temperature after get the data of tem_h and tem_l
  469. addr_transfer <= 1'b1;
  470. end else if(addr_transfer) begin
  471. tem2 <= {tem_h2,tem_l2};
  472. addr_transfer <= 1'b0;
  473. end
  474. end
  475. else begin
  476. din_valid <= 1'b0;
  477. end
  478. end
  479. READ_CRC_1:begin
  480. if(I2C_SCL_posedge && (I2C_SCL_count < 4'd8) ) begin
  481. I2C_SCL_count <= I2C_SCL_count + 4'd1;
  482. din_buf <= {din_buf[6:0], I2C_SDA_in};
  483. din_valid <= 1'b0;
  484. I2C_SDA_oe <= 1'b1;
  485. end
  486. else if(I2C_SCL_negedge && (I2C_SCL_count == 4'd8)) begin
  487. I2C_SCL_count <= I2C_SCL_count + 4'd1;
  488. // din <= din_buf;
  489. crc_tem <= din_buf;
  490. din_valid <= 1'b1;
  491. I2C_SDA_oe <= 1'b0;
  492. I2C_SDA_out <= 1'b0; // send ack to salver
  493. end
  494. else if(I2C_SCL_negedge && (I2C_SCL_count == 4'd9)) begin
  495. I2C_SCL_count <= 4'd0;
  496. I2C_SDA_oe <= 1'b1;
  497. next_state <= READ_HUM_H;
  498. dout_count <= 4'd0;
  499. end
  500. else begin
  501. din_valid <= 1'b0;
  502. end
  503. end
  504. READ_HUM_H:begin
  505. if(I2C_SCL_posedge && (I2C_SCL_count < 4'd8) ) begin
  506. I2C_SCL_count <= I2C_SCL_count + 4'd1;
  507. din_buf <= {din_buf[6:0], I2C_SDA_in};
  508. din_valid <= 1'b0;
  509. I2C_SDA_oe <= 1'b1;
  510. end
  511. else if(I2C_SCL_negedge && (I2C_SCL_count == 4'd8)) begin
  512. I2C_SCL_count <= I2C_SCL_count + 4'd1;
  513. // din <= din_buf;
  514. hum_h <= din_buf;
  515. din_valid <= 1'b1;
  516. I2C_SDA_oe <= 1'b0;
  517. I2C_SDA_out <= 1'b0; // send ack to salver
  518. end
  519. else if(I2C_SCL_negedge && (I2C_SCL_count == 4'd9)) begin
  520. I2C_SCL_count <= 4'd0;
  521. I2C_SDA_oe <= 1'b1;
  522. next_state <= READ_HUM_L;
  523. dout_count <= 4'd0;
  524. end
  525. else begin
  526. din_valid <= 1'b0;
  527. end
  528. end
  529. READ_HUM_L:begin
  530. if(I2C_SCL_posedge && (I2C_SCL_count < 4'd8) ) begin
  531. I2C_SCL_count <= I2C_SCL_count + 4'd1;
  532. din_buf <= {din_buf[6:0], I2C_SDA_in};
  533. din_valid <= 1'b0;
  534. I2C_SDA_oe <= 1'b1;
  535. end
  536. else if(I2C_SCL_negedge && (I2C_SCL_count == 4'd8)) begin
  537. I2C_SCL_count <= I2C_SCL_count + 4'd1;
  538. // din <= din_buf;
  539. hum_l <= din_buf;
  540. din_valid <= 1'b1;
  541. I2C_SDA_oe <= 1'b0;
  542. I2C_SDA_out <= 1'b0; // send ack to salver
  543. end
  544. else if(I2C_SCL_negedge && (I2C_SCL_count == 4'd9)) begin
  545. I2C_SCL_count <= 4'd0;
  546. I2C_SDA_oe <= 1'b1;
  547. next_state <= READ_CRC_2;
  548. dout_count <= 4'd0;
  549. hum <= {hum_h,hum_l}; // to build this temperature after get the data of hum_h and hum_l
  550. end
  551. else begin
  552. din_valid <= 1'b0;
  553. end
  554. end
  555. READ_CRC_2:begin
  556. if(I2C_SCL_posedge && (I2C_SCL_count < 4'd8) ) begin
  557. I2C_SCL_count <= I2C_SCL_count + 4'd1;
  558. din_buf <= {din_buf[6:0], I2C_SDA_in};
  559. din_valid <= 1'b0;
  560. I2C_SDA_oe <= 1'b1;
  561. end
  562. else if(I2C_SCL_negedge && (I2C_SCL_count == 4'd8)) begin
  563. I2C_SCL_count <= I2C_SCL_count + 4'd1;
  564. // din <= din_buf;
  565. crc_hum <= din_buf;
  566. din_valid <= 1'b1;
  567. I2C_SDA_oe <= 1'b0;
  568. I2C_SDA_out <= 1'b1; // send nack to salver
  569. end
  570. else if(I2C_SCL_negedge && (I2C_SCL_count == 4'd9)) begin
  571. I2C_SCL_count <= 4'd0;
  572. I2C_SDA_oe <= 1'b0;
  573. I2C_SDA_out <= 1'b0;
  574. next_state <= END_STOP;
  575. dout_count <= 4'd0;
  576. end
  577. else begin
  578. din_valid <= 1'b0;
  579. end
  580. end
  581. END_STOP:begin
  582. if(I2C_SCL_posedge) begin
  583. I2C_SCL_en <= 1'b0;
  584. I2C_SDA_oe <= 1'b0;
  585. delay_en <= 1'b1;
  586. // I2C_SDA_out <= 1'b1;
  587. // delay a while and pull down the SDA, indicating repeat start
  588. end else if(delay_cnt >= 28'd400) begin
  589. delay_cnt <= 1'd0;
  590. I2C_SDA_out <= 1'b1;
  591. delay_en <= 1'b0;
  592. end else if(delay_en) begin
  593. delay_cnt <= delay_cnt + 1'b1;
  594. // delay a while and pull up the SDA, indicating the end
  595. end else if(~I2C_SCL_en && (end_count < 13'd250)) begin
  596. end_count <= end_count + 13'd1;
  597. end
  598. else if(~I2C_SCL_en) begin
  599. I2C_SDA_oe <= 1'b0;
  600. I2C_SDA_out <= 1'b1;
  601. next_state <= IDLE;
  602. end_count <= 13'd0;
  603. end
  604. end
  605. // DELAY : begin
  606. // delay_cnt <= delay_cnt + 1'd1;
  607. if(delay_cnt >= 28'd25000) begin // 500us
  608. // if(delay_cnt >= 28'd100) begin // 50us for simulation
  609. // delay_cnt <= 28'd0;
  610. // next_state <= IDLE;
  611. // end else begin
  612. // next_state <= DELAY;
  613. // end
  614. // end
  615. ENDING: begin
  616. if(I2C_SCL_posedge) begin
  617. I2C_SCL_en <= 1'b0;
  618. I2C_SDA_oe <= 1'b0;
  619. delay_en <= 1'b1;
  620. // I2C_SDA_out <= 1'b1;
  621. // delay a while and pull down the SDA, indicating repeat start
  622. end else if(delay_cnt >= 28'd400) begin
  623. delay_cnt <= 1'd0;
  624. I2C_SDA_out <= 1'b1;
  625. delay_en <= 1'b0;
  626. end else if(delay_en) begin
  627. delay_cnt <= delay_cnt + 1'b1;
  628. // delay a while and pull up the SDA, indicating the end
  629. end else if(~I2C_SCL_en && (end_count < 13'd250)) begin
  630. end_count <= end_count + 13'd1;
  631. end
  632. else if(~I2C_SCL_en) begin
  633. I2C_SDA_out <= 1'b1;
  634. next_state <= IDLE;
  635. end
  636. end
  637. endcase
  638. end
  639. //ila_0_druver your_instance_name (
  640. // .clk(clk), // input wire clk
  641. // .probe0 (I2C_SCL ), // input wire [0:0] probe0
  642. // .probe1 (I2C_SDA_out ), // input wire [0:0] probe1
  643. // .probe2 (I2C_SDA_in ), // input wire [0:0] probe2
  644. // .probe3 (I2C_SDA_oe ), // input wire [0:0] probe3
  645. // .probe4 ( dev_addr ), // input wire [6:0] probe4
  646. // .probe5 ( reg_addr ), // input wire [7:0] probe5
  647. // .probe6 ( rdh_wrl ), // input wire [0:0] probe6
  648. // .probe7 ( ready ), // input wire [0:0] probe7
  649. // .probe8 ( dout ), // input wire [7:0] probe8
  650. // .probe9 ( dout_ack ), // input wire [0:0] probe9
  651. // .probe10 ( dout_length ), // input wire [3:0] probe10
  652. // .probe11 ( din ), // input wire [7:0] probe11
  653. // .probe12 ( din_valid ) // input wire [0:0] probe12
  654. //);
  655. endmodule

3- 仿真程序

  1. `timescale 1ns / 1ps
  2. //
  3. // Company:
  4. // Engineer:
  5. //
  6. // Create Date: 2022/12/22 16:42:31
  7. // Design Name: taotao
  8. // Module Name: tb_sht31_i2c
  9. // Project Name:
  10. // Target Devices:
  11. // Tool Versions:
  12. // Description:
  13. //
  14. // Dependencies:
  15. //
  16. // Revision:
  17. // Revision 0.01 - File Created
  18. // Additional Comments:
  19. //
  20. //
  21. module tb_sht31_i2c();
  22. reg clk ;
  23. reg rst ;
  24. reg I2C_SDA_in ;
  25. reg ready ;
  26. initial begin
  27. clk = 1'b0 ;
  28. rst = 1'b1 ;
  29. I2C_SDA_in = 1'b1 ;
  30. ready = 1'b0 ;
  31. #200
  32. rst = 1'b0 ;
  33. #500
  34. ready = 1'b1 ;
  35. #200
  36. ready = 1'b0 ;
  37. #100
  38. I2C_SDA_in = 1'b0 ; // if ack
  39. // I2C_SDA_in = 1'b1 ; // if nack
  40. end
  41. always #10 clk = ~clk;
  42. SHT31_IIC_driver SHT31_IIC_driver_inst(
  43. .clk ( clk ) ,
  44. .rst ( rst ) ,
  45. .I2C_SCL ( I2C_SCL ) ,
  46. .I2C_SDA_out ( I2C_SDA_out ) ,
  47. .I2C_SDA_in ( I2C_SDA_in ) ,
  48. .I2C_SDA_oe ( I2C_SDA_oe ) ,
  49. .ready ( ready ) , // write and read ready
  50. .dout_ack ( dout_ack ) , // write data acknowledge by slave device
  51. // .din ( din ) ,
  52. .din_valid ( din_valid )
  53. );
  54. endmodule

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/359533
推荐阅读
相关标签
  

闽ICP备14008679号