基于CPLD的温度计设计

   2020-07-16 聪慧网sxxjymy30
核心提示:发表于: 2020年07月16日 07时18分25秒

    1.概述

    本设计基于CPLD设计一款数字温度计,温度传感器使用DS18B20,CPLD采用EPM240T100C5。DS18B20具有体积小,硬件开销低(只需要一根信号线),抗干扰能力强等优点。EPM240T00C5具有延时低、功耗小、稳定性高等优点。

    2.硬件简介

    硬件平台采用BigTree的CPLD开发板,有如下硬件资源:

    CPLDEPM240T100C5;

    USB转串口(省去USB转串口线);

    LED;

    有源蜂鸣器;

    DS18B20温度传感器;

    四位共阳极数码管;

    按键;

    GPIO拓展接口(18个通用IO)。

    有需要的朋友可以在shop397545458.taobao.com购买。

    3.系统框图

基于CPLD的温度计设计(原理和代码)

    温度采集模块:负责初始化、读写DS18B20温度传感器;

    十六进制转十进制模块:将DS18B20的温度输出数据转换成十进制数据;

    数码管显示模块:将转换好的十进制数据动态显示在数码管上。

    4.DS18B20工作原理

    DS18B20引脚功能

    GND:地信号

    DQ:数据信号线

    VDD:电源

    存储资源

    ROM:只读存储器,用于存放DS18B20编码,一共64位,第一个8位是1-wire家族号(28h),第二个48位是唯一的序列号。最后一个8位是前56位的CRC校验码。

    RAM:数据暂存器,共9个字节,第1、2字节是温度转后的数据值。

    EEPROM:用于存放长期需要保持的数据,如上下限温度报警值等。

    设备操作

    1.初始化

    ->数据线拉高1;

    ->短延时;

    ->数据线拉底0;

    ->延时750ms;

    ->数据线拉高1;

    ->延时等待(如果初始化成功则在15~60毫秒内产生一个由DS18B20返回的低电平);

    ->若读到数据线上的低电平,再做延时(第五步算起,最少480ms);

    ->数据线拉高,结束。

    2.发送ROM指令

    ROM指令共5条,每一个工作周期只能发一条,分别为:读ROM、匹配ROM、跳跃ROM、查找ROM和报警查找。一般只有单个18B20芯片,可使用跳过ROM指令[CCH]。

    3.发送存储器操作指令

    在ROM指令后,紧接着发送存储器操作指令,分别为:

    ?温度转换44H:

    启动DS18B20进行温度转换,将温度值放入RAM的第1、2个地址。

    ?读暂存器BEH

    从RAM中读数据,读地址从0开始到9,可只读前两个字节。

    ?写暂存器4EH

    将数据写入暂存器的TH、TL字节。

    ?复制暂存器48H

    把暂存器的TH、TL字节写到E2RAM中。

    ?重新调E2RAMB8H

    把E2RAM中的TH、TL字节写到暂存器TH、TL字节。

    ?读电源供电方式B4H

    启动DS18B20发送电源供电方式的信号给主控。

    4.读当前温度数据

    需要执行两次工作周期,第一个周期为复位,跳过ROM指令,执行温度转换存储器指令等待500us温度转换时间。紧接着执行第二个周期为复位,跳过ROM指令,执行读RAM的存储器,读数据。

    5.写操作

基于CPLD的温度计设计(原理和代码)

    写时隙分为写“0”和写“1”,时序如图,在写数据时间间隙的前15us总线需要是被主控拉低,然后则将是芯片对总线数据的采样时间,采样时间在15-60us,采样时间内,如果主控将总线拉高则表示写1,如果主控将总线拉低则表示写0。每一位的发送都应该有一个至少15us的低电平起始位随后的数据0或1应该在45us内完成。整个位的发送时间应该保持在60-120us,否则不能保证通信的正常。

    6.读操作

基于CPLD的温度计设计(原理和代码)

    读时隙时也是必须先由主控产生至少1us的低电平,表示读时间的起始。随后在总线被释放后的15us中DS18B20会发送内部数据位。注意必须要在读间隙开始的15us内读数据为才可以保持通信的正确。通信时,字节的读或写是从高位开始的,即A7到A0。控制器释放总线,也相当于将总线置1。

    5.进制转换(Hex2Dec)

    由于DS18B20输出的是十六进制数据,所以需要做进制转换为10进制输出。这里由于CPLD资源问题,故只设计温度显示范围为:0~47度,最小分辨率为1度。

    ```

    wire[7:0]data_in;

    assigndata_in={1‘b0,temperature_buf[10:4]};

    reg[7:0]buf0;

    reg[7:0]buf1;

    reg[7:0]buf2;

    reg[7:0]data_out;

    always@(*)

    case(data_in[7:4])

    0:

    begin

    buf0[3:0]=(data_in[3:0]>=10)?(data_in[3:0]-10):data_in[3:0];

    buf0[7:4]=(data_in[3:0]>=10)?(data_in[7:4]+1):data_in[7:4];

    data_out=buf0;

    end

    1:

    begin

    buf0[3:0]=(data_in[3:0]>=10)?(data_in[3:0]-10+6):(data_in[3:0]+6);

    buf0[7:4]=(data_in[3:0]>=10)?(data_in[7:4]+1):data_in[7:4];

    buf1[3:0]=(buf0[3:0]>=10)?(buf0[3:0]-10):buf0[3:0];

    buf1[7:4]=(buf0[3:0]>=10)?(buf0[7:4]+1):buf0[7:4];

    data_out=buf1;

    end

    2:

    begin

    buf0[3:0]=(data_in[3:0]>=10)?(data_in[3:0]-10+6):(data_in[3:0]+6);

    buf0[7:4]=(data_in[3:0]>=10)?(data_in[7:4]+1):data_in[7:4];

    buf1[3:0]=(buf0[3:0]>=10)?(buf0[3:0]-10+6):(buf0[3:0]+6);

    buf1[7:4]=(buf0[3:0]>=10)?(buf0[7:4]+1):buf0[7:4];

    buf2[3:0]=(buf1[3:0]>=10)?(buf1[3:0]-10):(buf1[3:0]);

    buf2[7:4]=(buf1[3:0]>=10)?(buf1[7:4]+1):buf1[7:4];

    data_out=buf2;

    end

    default:

    begin

    data_out=data_in;

    end

    endcase

    assigntemperature=data_out[7:0]

    #6.数码管显示

    本设计采用4位共阳极数码管作为温度显示模块,驱动代码如下:

    //-----------------数码管显示-------------------

    assignsm_sel={2’b11,sm_sel_r};

    assignsm_dat=sm_dat_r;

    //XXXX=8‘b{a,b,c,d,e,f,g,dp}

    parameterZERO=8’b0000_0011,//8‘b1100_0000,

    ONE=8’b1001_1111,//8‘b1111_1001,

    TWO=8’b0010_0101,//8‘b1010_0100,

    THREE=8’b0000_1101,//8‘b1011_0000,

    FOUR=8’b1001_1001,//8‘b1001_1001,

    FIVE=8’b0100_1001,//8‘b1001_0010,

    SIX=8’b0100_0001,//8‘b1000_0010,

    SEVEN=8’b0001_1111,//8‘b1111_1000,

    EIGHT=8’b0000_0001,//8‘b1000_0000,

    NINE=8’b0000_1001;//8‘b1001_0000;

    reg[7:0]sm_dat_r;

    reg[7:0]sm_dat_r1;

    reg[7:0]sm_dat_r2;

    always@(*)

    case(temperature[3:0])

    4’d0:sm_dat_r1<=ZERO;

    4‘d1:sm_dat_r1<=ONE;

    4’d2:sm_dat_r1<=TWO;

    4‘d3:sm_dat_r1<=THREE;

    4’d4:sm_dat_r1<=FOUR;

    4‘d5:sm_dat_r1<=FIVE;

    4’d6:sm_dat_r1<=SIX;

    4‘d7:sm_dat_r1<=SEVEN;

    4’d8:sm_dat_r1<=EIGHT;

    4‘d9:sm_dat_r1<=NINE;

    default:sm_dat_r1<=8’hFF;

    endcase

    always@(*)

    case(temperature[6:4])

    4‘d0:sm_dat_r2<=ZERO;

    4’d1:sm_dat_r2<=ONE;

    4‘d2:sm_dat_r2<=TWO;

    4’d3:sm_dat_r2<=THREE;

    4‘d4:sm_dat_r2<=FOUR;

    4’d5:sm_dat_r2<=FIVE;

    4‘d6:sm_dat_r2<=SIX;

    4’d7:sm_dat_r2<=SEVEN;

    4‘d8:sm_dat_r2<=EIGHT;

    4’d9:sm_dat_r2<=NINE;

    endcase

    reg[1:0]sm_sel_r;

    reg[0:0]sm_cnt;

    always@(posedgeclk_ref)

    sm_cnt<=sm_cnt+1‘b1;

    always@(sm_cnt)

    case(sm_cnt)

    ’d0:

    begin

    sm_sel_r<=2‘b01;

    sm_dat_r<=sm_dat_r1;

    end

    ’d1:

    begin

    sm_sel_r<=2‘b10;

    sm_dat_r<=sm_dat_r2;

    end

    default:

    begin

    sm_sel_r<=2’b11;

    sm_dat_r<=ZERO;

    end

    endcase

    ```

    7.最终结果

    下图为实测的温度结果,比实际温度高出2-3度。由于芯片出厂的误差(没有对0校准),加上板卡本身的散热,使得温度偏高2~3度。但不影响我们学习使用。

 
举报收藏 0打赏 0评论 0
 
更多>同类资讯
  • sxxjymy
    加关注0
  • 没有留下签名~~
推荐图文
推荐资讯
点击排行
网站首页  |  用户协议  |  关于我们  |  联系方式  |  隐私政策  |  版权隐私  |  网站地图  |  排名推广  |  积分换礼  |  网站留言  |  RSS订阅  |  违规举报  |  浙ICP备16039256号-5  |  浙公网安备 33060302000814号