广告

原创 FPGA设计——基于CPLD的温度计设计

2017-8-11 14:11 445 0 1 分类: FPGA/CPLD

1. 概述

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

2. 硬件简介

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

  • CPLD EPM240T100C5;
  • USB 转串口(省去 USB 转串口线);
  • LED;
  • 有源蜂鸣器;
  • DS18B20 温度传感器;
  • 四位共阳极数码管;
  • 按键;
  • GPIO 拓展接口(18 个通用 IO)。
    有需要的朋友可以在 shop397545458.taobao.com购买。   

3. 系统框图

  • 温度采集模块:负责初始化、读写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 中。
     重新调 E2RAM B8H
    把 E2RAM 中的 TH、 TL 字节写到暂存器 TH、 TL 字节 。
     读电源供电方式 B4H
    启动 DS18B20 发送电源供电方式的信号给主控。
  4. 读当前温度数据
    需要执行两次工作周期,第一个周期为复位,跳过 ROM 指令,执行温度转换存储器指令等待 500us 温度转换时间。紧接着执行第二个周期为复位,跳过 ROM 指令,执行读 RAM 的存
    储器,读数据。
  5. 写操作

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

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

5. 进制转换(Hex2Dec)

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

wire [7:0] data_in;
assign data_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

assign temperature = data_out[7:0];


6. 数码管显示

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

//-----------------数码管显示-------------------
assign sm_sel ={2'b11,sm_sel_r};
assign sm_dat = sm_dat_r;

//XXXX = 8'b{a,b,c,d,e,f,g,dp}
parameter ZERO = 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 @(posedge clk_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度。但不影响我们学习使用。

广告

文章评论 1条评论)

登录后参与讨论

curton 2019-4-5 16:09

好资源,学习了。
相关推荐阅读
ETree 2017-08-15 10:22
硬件基础——开关稳压电路
1. 开关稳压电路分类在电子线路设计中,经常使用开关稳压电路,其转换效率可达95%以上,大大提高了电路的效率。按稳压控制方式分:脉冲宽度调制(PWM)、脉冲频率调制(PFM)和混合调制。按调整管与负载...
ETree 2017-08-14 15:37
硬件基础——直流电源
1. 直流电源的框图电子电路设备中,需要稳定的几十安以下的直流电源。下图为直流电源的框图。2. 半波整流利用二极管的单向导通性,实现半波整流。3. 全波整流在实际电路中多采用单相全波整流电路。在整个周...
ETree 2017-08-14 11:51
硬件基础——运放的运算电路
1. 虚短与虚断在分析运算电路时,设想为理想运放,因而两输入端的净输入电压和净输入电流均为零,即“虚短”和“虚断”。2. 比例放大电路输入电压uI通过R作用于运放的反相输入端,同相输入端通过电阻R'接...
ETree 2017-08-14 11:08
硬件基础——负反馈
1. 负反馈负反馈指将系统的输出返回到输入端并以某种方式改变输入,进而影响系统功能的过程。负反馈可以稳定工作电路,减少非线性失真。比如温度变化引起集电极电流Ic变大,然后电阻Re上电压变大,使放大管b...
ETree 2017-08-12 19:10
硬件基础——晶体三级管电流放大
1. 晶体三极管结构晶体三极管又称双极型晶体管(Bipolar Junction Transistor),根据工艺结构可分为NPN和PNP,这里以NPN型硅材料晶体管为例说明其结构。如下图所示,位于中...
ETree 2017-08-12 10:52
硬件基础——MOS管的开关特性
1. MOSFET结构MOSFET(Metal Oxide Semiconductor Field Effect Transistor)分为N沟道NMOS和P沟道PMOS。下图为NMOS的结构图:2....
我要评论
1
0
广告