我是靠谱客的博主 诚心小馒头,最近开发中收集的这篇文章主要介绍温度检测工程——DS18B20,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

温度检测工程研究点

  • 功能需求及选择DS18B20的理由
    • 没有选择模拟量温度传感器是因为还需要AD转换,直接选用数字温度传感器DS18B20,淘宝资源多,网上资源多
  • 框架图,架构划分原理
    • 划分原理:
      • 硬件有DS18B20温度传感器、数码管、蜂鸣器、串口
      • 串口模块 + 温度传感器接口模块 + 数码管模块 + 蜂鸣器模块
      • opcode_dect没有放到control的原因是因为凡是数据都有包文头,那么就需要先将数据解析,将游戏的命令+数据配合dout_vld传递给后面的control模块
      • ds_intf_byte和ds_intf_bit存在的原因:后者很明显是bit模块,因为跟DS18B20是单线交互,因此需要bit模块,那么bit模块数据的发送和接收那么接着就要对应一个byte模块,control模块只是给你一个写使能和写数据,剩下的你来做这叫控制
      • 数码管显示控制模块seg_disp的输入是32位数据,32位数据的组成方式是是4bit组成一个ASCII码,比如有符号位,正整数小数点等,那么通过数码管扫描到第一个就显示32位数据最低4bit,扫到第八个就显示32位数据最高4bit
  • 各模块代码输入输出以及测试脚本的使用技巧
    • uart_rx:
      • 串口协议低位在前,时钟50mhz
        • ​​​​​​​输入:din串口输入数据,50mhz时钟和系统复位
        • 输出:dout[7:0]和dout_vld
        • 测试文件用到技巧:使用语句 $display("Err at %t ns",$time); 的方式定位错误
    • asscii2hex
      • ​​​​​​​ascii码一位对应8bit的二进制数,通过码表可以查询对应数值关系
        • ​​​​​​​输入:dint[7:0] 8bit的二进制数和din_vld
        • 输出:dout[3:0] 4bit的ascii码和dout_vld,根据输入的din_vld,下一个时钟同步输出dout和dout_vld
        • 测试文件用到技巧:din_vld只维持一个时钟周期,因此和din分开在两个initial begin end中产生
    • opcode_dect
      • 低位在前,收到0x55d5的帧头,那么就启动计数器,输出指令和数据
        • 输入:din[3:0]输入ascii码数据和din_vld
        • 输出:8bit的指令和数据dout[7:0] && dout_vld
    • control
      • 最核心的模块:
      • 指令有读、写、复位,分别产生一个周期使能信号
      • 数据处理分为以下几种:①写的话要对应把写数据给过去    ②读有三种:读温度值低、高、其他分别存储到不同寄存器  ③还有打开蜂鸣器开关、开启数码管显示  ④上下限定值寄存
      • 对于温度值的读取之后要进行处理,处理方式如下:判断温度值高位寄存器最高位是否为“1”,如果为1代表负数,那么取反+1否则保持不变
      • 温度值高位和低位组帧之后的16bit数据中,[10:4]是代表温度值整数,[3:0]代表温度值小数,对于温度值进一步处理如下,因为采集到的数字量转化为温度值需要*0.0625,而整数部分右移4位就相当于*0.0625,所以不需要处理,小数部分则需要*10000*0.0625,所以就是*625,得到整数和小数部分的正整数值,需要将每一位全部求出来,通过%10的方式可以得到个位数余数
      • 将温度值的整数和小数组帧  temp_uns = {{4{temp_uns_sign}},temp_uns_int3,temp_uns_int2,temp_uns_int1,temp_uns_dot1,temp_uns_dot2,temp_uns_dot3,temp_uns_dot4};符号位+3个整数+4个小数
      • 如果指令0x0d那么就开始读取温度值指令,启动计数器,计数值7,输出数据uart_out <= ds_uns_temp[(7-cnt1)*8-1 -:8]; 同步输出uart_out_vld只维持一个时钟周期,其中寄存温度值格式 ds_uns_temp = {(8'h2b+temp_uns[31]*2),{4'b0,temp_uns[27:16]},8'h2e,temp_uns[15:0],8'h0a},其中1-4-7是传递正负号、小数点、回车的ascii码十六进制,不需要转换;
        • 输入:uart_in[7:0]指令和数据&&uart_in_vld,读取数据intf_rdata[7:0]&&intf_rdata_vld
        • 输出:h2a_en进制转换使能、beep蜂鸣器、intf_rst_en复位使能、intf_wr_en写使能、intf_rd_en读使能、intf_wdata[7:0]写数据、temp_valid_en数码管显示使能、temp_uns[31:0]数码管显示数据、uart_out[7:0]串口上传数据&&uart_out_vld
    • ds_byte
      • control和bit模块之间的桥接,完成字节到比特模块的转换
        • 输入:读写复位使能信号,和比特模块传递过来的读传感器数据
        • 输出:读写复位使能给比特模块,同时送写数据过去
  • ds_bit
    • 与底层交互,完成时序协议,获取温度值数据
      • 输入:读写复位使能
      • 输出:本模块准备好信号,读到的数据和有效指示信号
  • seg_disp
    • 20ms扫描每一个数码管,根据计数值得到每一个数码管,并给每个数码管一个显示值
  • hex2asscii
    • 用到了FIFO,将转化使能,低4位,转换时能,高四位数据写入FIFO,输出是转换使能,四位数据——先进先出
    • 需要转换,对din处理,不需要直接输出dout
    • 4bitascii码对应8bit的十六进制数,因此如果是转换,那么转换完成直接输出dout_vld,否则需要一个计数器计数两次后输出dout_vld
      • 输入:8bit数据 ascii,转换使能
      • 输出:8bit数据Hex
  • 开发过程中遇到了哪些难题及解决办法​​​​​​​
    • ​​​​​​​底层时序配置读取数据,解决办法:用示波器调试
    • control模块的温度值转换:右移4位就相当于*0.0625
    • 与上位机的交互:采用ascii因为要使用正负号显示
    • 如何下发指令:采用55d5包文头+指令+数据

 

 

 

 

 

 

 

 

 

 

最后

以上就是诚心小馒头为你收集整理的温度检测工程——DS18B20的全部内容,希望文章能够帮你解决温度检测工程——DS18B20所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(41)

评论列表共有 0 条评论

立即
投稿
返回
顶部