慧聪芯城 | 慧聪智能硬件网 | 慧聪新能源网 | 慧聪LED网 | 慧聪电气网 | 慧聪电源网 | 慧聪IT网 | 慧聪变频器网
特惠新品微信
投稿
热门推荐:指纹识别 | 八代酷睿 | P30芯片 | Nokia 8 | Pixel 2 | 商营通 | 买芯片 | 晶振 | 采购 | 活动规划

慧聪电子网首页 > 技术文章 > 2014技术文章 > 可编程逻辑器件(PLD) > 正文

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

http://www.ec.hc360.com2017年08月22日09:51 来源:电子发烧友T|T

    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度。但不影响我们学习使用。

责任编辑:马兰

声明:本网站中,来源标明为“慧聪智能硬件网”的文章,转载请标明出处。

欢迎投稿,邮箱:lijia03@hc360.com

友情链接

申请友情链接

赛迪网 RFID世界网电子信息产业网畅享网与非网电子产品世界慧聪智能硬件网慧聪电气网慧聪电源网慧聪IT网慧聪变频器网慧聪LED网慧聪芯城

慧聪电子网总部

北京市海淀区大钟寺东路9号京仪科技大厦B座2层

慧聪电子网分部

上海市普陀区中山北路3000号长城大厦5层

深圳市福田区深南中路2018号兴华大厦A座七楼

关于我们 | 加入我们 | 我要投稿
| 寻求报道 | 申请合作

Copyright?2000-2014 hc360.com. All Rights Reserved
京ICP证010051号 海淀公安局网络备案编号:11010802015485