• FPGA project : dht11 温湿度传感器


    没有硬件,过几天上板测试

     

     

     

    1. module dht11(
    2. input wire sys_clk ,
    3. input wire sys_rst_n ,
    4. input wire key ,
    5. inout wire dht11 ,
    6. output wire ds ,
    7. output wire oe ,
    8. output wire shcp ,
    9. output wire stcp
    10. );
    11. // 例化连线
    12. wire key_out_w ;
    13. wire [19:00] data_w ;
    14. wire sign_w ;
    15. wire [ 5: 0] point_w ;
    16. wire en_w ;
    17. key_filter key_filter_insert(
    18. .sys_clk ( sys_clk ) ,
    19. .sys_rst_n ( sys_rst_n ) ,
    20. .key_in ( key ) ,
    21. .key_out ( key_out_w )
    22. );
    23. dht11_ctrl dht11_ctrl_insert(
    24. .sys_clk ( sys_clk ) ,
    25. .sys_rst_n ( sys_rst_n ) ,
    26. .key_flag ( key_out_w ) ,
    27. .dht11 ( dht11 ) ,
    28. .data_out ( data_w ) ,
    29. .sign ( sign_w )
    30. );
    31. seg_595_dynamic seg_595_dynamic_insert(
    32. .sys_clk ( sys_clk ) ,
    33. .sys_rst_n ( sys_rst_n ) ,
    34. .data ( data_w ) ,
    35. .point ( point_w ) ,
    36. .sign ( sign_w ) ,
    37. .seg_en ( en_w ) ,
    38. .ds ( ds ) ,
    39. .oe ( oe ) ,
    40. .shcp ( shcp ) ,
    41. .stcp ( stcp )
    42. );
    43. endmodule
    1. module dht11_ctrl (
    2. input wire sys_clk ,
    3. input wire sys_rst_n ,
    4. input wire key_flag ,
    5. inout wire dht11 ,
    6. output reg [19:0] data_out ,
    7. output reg sign
    8. );
    9. // reg signal define
    10. // 产生us时钟
    11. reg clk_us ;
    12. reg [4:0] cnt_clk_us ;
    13. // 内部信号(用于产生状态转移条件与输出信号)
    14. reg [19:0] cnt_us ;
    15. reg [ 6:0] cnt_low ;
    16. reg dht11_reg1 ;
    17. reg dht11_reg2 ;
    18. wire dht11_fall ;
    19. wire dht11_rise ;
    20. reg [ 5:0] bit_cnt ;
    21. reg [39:0] data_temp ;
    22. reg [31:0] data ;
    23. reg data_flag ;
    24. // 三态输出
    25. reg dht11_en ;
    26. wire dht11_out ;
    27. // [4:0] cnt_clk_us ;
    28. always @(posedge sys_clk or negedge sys_rst_n) begin
    29. if(~sys_rst_n) begin
    30. cnt_clk_us <= 5'd0 ;
    31. end else begin
    32. if(cnt_clk_us == 5'd24) begin
    33. cnt_clk_us <= 5'd0 ;
    34. end else begin
    35. cnt_clk_us <= cnt_clk_us + 1'b1 ;
    36. end
    37. end
    38. end
    39. // clk_us ;
    40. always @(posedge sys_clk or negedge sys_rst_n) begin
    41. if(~sys_rst_n) begin
    42. clk_us <= 1'b0 ;
    43. end else begin
    44. if(cnt_clk_us == 5'd24) begin
    45. clk_us <= ~clk_us ;
    46. end else begin
    47. clk_us <= clk_us ;
    48. end
    49. end
    50. end
    51. // reg signal define
    52. // 在clk_us时钟域下
    53. // 状态机 三段式写法(现态与次态描述)(状态转移条件描述)(输出信号描述)
    54. localparam WAIT_1S = 6'b000_001 ,
    55. START = 6'b000_010 ,
    56. DELAY_1 = 6'b000_100 ,
    57. REPLAY = 6'b001_000 ,
    58. DELAY_2 = 6'b010_000 ,
    59. RD_DATA = 6'b100_000 ;
    60. reg [5:0] state_c ;
    61. reg [5:0] state_n ;
    62. wire WAIT_1StoSTART ;
    63. wire STARTtoDELAY_1 ;
    64. wire DELAY_1toREPLAY ;
    65. wire REPLAYtoDELAY_2 ;
    66. wire REPLAYtoSTART ;
    67. wire DELAY_2toRD_DATA ;
    68. wire DELAY_2toSTART ;
    69. always @(posedge clk_us or negedge sys_rst_n) begin
    70. if(~sys_rst_n) begin
    71. state_c <= 6'd0 ;
    72. end else begin
    73. state_c <= state_n ;
    74. end
    75. end
    76. always @(*) begin
    77. case (state_c)
    78. WAIT_1S:begin
    79. if(WAIT_1StoSTART) begin
    80. state_n <= START ;
    81. end else begin
    82. state_n <= WAIT_1S ;
    83. end
    84. end
    85. START :begin
    86. if(STARTtoDELAY_1) begin
    87. state_n <= DELAY_1 ;
    88. end else begin
    89. state_n <= START ;
    90. end
    91. end
    92. DELAY_1:begin
    93. if(DELAY_1toREPLAY) begin
    94. state_n <= REPLAY ;
    95. end else begin
    96. state_n <= DELAY_1 ;
    97. end
    98. end
    99. REPLAY :begin
    100. if(REPLAYtoDELAY_2) begin
    101. state_n <= DELAY_2 ;
    102. end else begin
    103. if(REPLAYtoSTART) begin
    104. state_n <= START ;
    105. end else begin
    106. state_n <= REPLAY ;
    107. end
    108. end
    109. end
    110. DELAY_2:begin
    111. if(DELAY_2toRD_DATA) begin
    112. state_n <= RD_DATA ;
    113. end else begin
    114. state_n <= DELAY_2 ;
    115. end
    116. end
    117. RD_DATA:begin
    118. if(DELAY_2toSTART) begin
    119. state_n <= START ;
    120. end else begin
    121. state_n <= RD_DATA ;
    122. end
    123. end
    124. default: state_n <= START ;
    125. endcase
    126. end
    127. // 状态机第二段描述
    128. assign WAIT_1StoSTART = (state_c == WAIT_1S && cnt_us == 20'd999_999) ? 1'b1 : 1'b0 ;
    129. assign STARTtoDELAY_1 = (state_c == START && cnt_us == 20'd17_999) ? 1'b1 : 1'b0 ;
    130. assign DELAY_1toREPLAY = (state_c == DELAY_1 && cnt_us == 20'd10) ? 1'b1 : 1'b0 ;
    131. assign REPLAYtoDELAY_2 = (state_c == REPLAY && dht11_rise == 1'b1 && cnt_low <= 7'd85 && cnt_low >= 7'd81) ? 1'b1 : 1'b0;
    132. assign REPLAYtoSTART = (state_c == REPLAY && dht11_rise == 1'b1 && (cnt_us >= 20'd100 || cnt_us <= 20'd70)) ? 1'b1 : 1'b0 ;
    133. assign DELAY_2toRD_DATA= (state_c == DELAY_2 && dht11_fall == 1'b1 && cnt_us >= 20'd85 && cnt_us <= 20'd88) ? 1'b1 : 1'b0 ;
    134. assign DELAY_2toSTART = (state_c == RD_DATA && bit_cnt == 6'd40 && dht11_rise == 1'b1) ? 1'b1 : 1'b0 ;
    135. // // 内部信号(用于产生状态转移条件与输出信号)
    136. // reg [19:0] cnt_us ;
    137. always @(posedge clk_us or negedge sys_rst_n) begin
    138. if(~sys_rst_n) begin
    139. cnt_us <= 20'd0 ;
    140. end else begin
    141. if((state_c == WAIT_1S && cnt_us == 20'd999_999)
    142. || (state_c == START && cnt_us == 20'd17_999)
    143. || (state_c == DELAY_1 && cnt_us == 20'd10)
    144. || (state_c == REPLAY && dht11_rise == 1'b1)
    145. || (state_c == DELAY_2 && dht11_fall == 1'b1)
    146. || (state_c == RD_DATA && (dht11_fall || dht11_rise)))begin // 记得最后加大括号
    147. cnt_us <= 20'd0 ;
    148. end else begin
    149. cnt_us <= cnt_us + 1'b1 ;
    150. end
    151. end
    152. end
    153. // reg [ 6:0] cnt_low ;
    154. always @(posedge clk_us or negedge sys_rst_n) begin
    155. if(~sys_rst_n) begin
    156. cnt_low <= 7'd0 ;
    157. end else begin
    158. if(state_c == REPLAY && dht11_reg1 == 1'b0) begin
    159. cnt_low <= cnt_low + 1'b1 ;
    160. end else begin
    161. cnt_low <= 7'd0 ;
    162. end
    163. end
    164. end
    165. // reg dht11_reg1 ;
    166. // reg dht11_reg2 ;
    167. always @(posedge clk_us or negedge sys_rst_n) begin
    168. if(~sys_rst_n) begin
    169. dht11_reg1 <= 1'b1 ;
    170. dht11_reg2 <= 1'b1 ;
    171. end else begin
    172. dht11_reg1 <= dht11 ;
    173. dht11_reg2 <= dht11_reg1 ;
    174. end
    175. end
    176. // wire dht11_fall ;
    177. // wire dht11_rise ;
    178. assign dht11_fall = ~dht11_reg1 && dht11_reg2 ;
    179. assign dht11_rise = dht11_reg1 && ~dht11_reg2 ;
    180. // reg [ 5:0] bit_cnt ;
    181. always @(posedge clk_us or negedge sys_rst_n) begin
    182. if(~sys_rst_n) begin
    183. bit_cnt <= 6'd0 ;
    184. end else begin
    185. if(dht11_rise && bit_cnt == 6'd40 ) begin
    186. bit_cnt <= 6'd0 ;
    187. end else begin
    188. if(state_c == RD_DATA && dht11_fall) begin
    189. bit_cnt <= bit_cnt + 1'b1 ;
    190. end else begin
    191. bit_cnt <= bit_cnt ;
    192. end
    193. end
    194. end
    195. end
    196. // reg [39:0] data_temp ;
    197. always @(posedge clk_us or negedge sys_rst_n) begin
    198. if(~sys_rst_n) begin
    199. data_temp <= 40'd0 ;
    200. end else begin
    201. if(state_c == RD_DATA && dht11_fall && bit_cnt <= 39) begin
    202. if(cnt_us >= 20'd50) begin // 也可以是68
    203. data_temp[39 - bit_cnt] <= 1'b1 ;
    204. end else begin
    205. data_temp[39 - bit_cnt] <= 1'b0 ;
    206. end
    207. end else begin
    208. data_temp <= data_temp ;
    209. end
    210. end
    211. end
    212. // reg [31:0] data ;
    213. always @(posedge clk_us or negedge sys_rst_n) begin
    214. if(~sys_rst_n) begin
    215. data <= 32'd0 ;
    216. end else begin
    217. if(data_temp[7:0] == (data_temp[15:8] + data_temp[23:16] + data_temp[31:24] + data_temp[39:32])) begin
    218. data <= data_temp[39:8] ;
    219. end else begin
    220. data <= data ;
    221. end
    222. end
    223. end
    224. // reg data_flag ; sys_clk时钟域下
    225. always @(posedge sys_clk or negedge sys_rst_n) begin
    226. if(~sys_rst_n) begin
    227. data_flag <= 1'b0 ;
    228. end else begin
    229. if(key_flag) begin
    230. data_flag <= ~data_flag ;
    231. end else begin
    232. data_flag <= data_flag ;
    233. end
    234. end
    235. end
    236. // // 三态输出
    237. // wire dht11_out ;
    238. assign dht11 = (dht11_en == 1'b1) ? dht11_out : 1'bz ;
    239. assign dht11_out = 1'b0 ;
    240. // reg dht11_en ;
    241. always @(posedge clk_us or negedge sys_rst_n) begin
    242. if(~sys_rst_n) begin
    243. dht11_en <= 1'd0 ;
    244. end else begin
    245. if(state_c == START) begin
    246. dht11_en <= 1'b1 ;
    247. end else begin
    248. dht11_en <= 1'b0 ;
    249. end
    250. end
    251. end
    252. // output signal
    253. // reg [19:0] data_out ,
    254. always @(posedge sys_clk or negedge sys_rst_n) begin
    255. if(~sys_rst_n) begin
    256. data_out <= 20'd0 ;
    257. end else begin
    258. if(data_flag == 1'b0) begin // 显示湿度
    259. data_out <= data[31:24] * 16'd10 ;
    260. end else begin
    261. data_out <= data[15:8] * 16'd10 + data[3:0] ;
    262. end
    263. end
    264. end
    265. // reg sign
    266. always @(posedge sys_clk or negedge sys_rst_n) begin
    267. if(~sys_rst_n) begin
    268. sign <= 1'b0 ;
    269. end else begin
    270. if(key_flag == 1'b1 && data[7] == 1'b1) begin
    271. sign <= 1'b1 ;
    272. end else begin
    273. sign <= 1'b0 ;
    274. end
    275. end
    276. end
    277. endmodule

     其他模块都是之前的,就不发了。

     

     

  • 相关阅读:
    机场调度管理系统(客户端+服务器端+Java+MySQL)
    easypoi自定义模板导出
    【C++高阶(二)】熟悉STL中的map和set --了解KV模型和pair结构
    tsconfig.json在配置文件中找不到任何输入,怎么办?
    小小装饰器大大用处
    笔记随笔:基于selvlet的Web应用程序流程
    ⑬、企业快速开发平台Spring Cloud之HTML 字符实体
    使用阿里云服务器学习Docker
    计算机毕业设计(附源码)python在线学习平台
    ZGC在三色指针中的应用
  • 原文地址:https://blog.csdn.net/Meng_long2022/article/details/132957886