基于FPGA的VHDL语言温度控制.docx

上传人:b****6 文档编号:8356537 上传时间:2023-01-30 格式:DOCX 页数:22 大小:1.75MB
下载 相关 举报
基于FPGA的VHDL语言温度控制.docx_第1页
第1页 / 共22页
基于FPGA的VHDL语言温度控制.docx_第2页
第2页 / 共22页
基于FPGA的VHDL语言温度控制.docx_第3页
第3页 / 共22页
基于FPGA的VHDL语言温度控制.docx_第4页
第4页 / 共22页
基于FPGA的VHDL语言温度控制.docx_第5页
第5页 / 共22页
点击查看更多>>
下载资源
资源描述

基于FPGA的VHDL语言温度控制.docx

《基于FPGA的VHDL语言温度控制.docx》由会员分享,可在线阅读,更多相关《基于FPGA的VHDL语言温度控制.docx(22页珍藏版)》请在冰豆网上搜索。

基于FPGA的VHDL语言温度控制.docx

基于FPGA的VHDL语言温度控制

基于FPGA的恒温控制系统

孵化器是一种最新的孵化禽蛋的机器,通过人工制造适合禽蛋孵化的恒温环境,来以较小的经济投入孵化禽蛋,通过调查,市面上的孵化器多数是以模拟电路的方式制造恒温环境,如以下列图

这种模拟电路控制在实际应用中很难做到恒温控制,温度会在最终归的预设值附近上下浮动,影响禽蛋的孵化。

而且,孵化器的温度设置也是模拟电路,这样是完全达不到精准的温度设置。

通过学习FPGA,我设想运用数字电路来对禽蛋孵化器部温度进展控制,来实现可控,可调,温度恒定的禽蛋孵化器。

具体的设计框架如下

通过前向温度采集电路,采集当前孵化器部的温度信号,将采集到的模拟信号通过ADC0809模数转换芯片,转变为FPGA可控的数字信号,FPGA芯片根据输入的当前实际温度,控制输出合理的数字信号,再由DAC0832转换为模拟信号,输入到后向加热执行电路,以此来完成对整个孵化器的温度控制。

整个系统中,带有温度传感器的前向温度采集电路作为系统的反响环节,实时反映当前环境的具体温度,具体的电路图如下。

前向温度采集电路图

此电路设计以AD590作为温度触感器,通过添加相应的调节电阻,让温度与输出电压保持一个相对线性的关系

其中:

为调零电阻

为调满度电阻

最终得到的温度与输出电压的关系式为:

模数转换芯片采用的是ADC0809,具体的连接电路图如下

IN0—IN7管角中任选一路作为前向温度采集电路的输入,VCC与

同时接+5V电压,

与GND接地,OUT1—OUT8数据输出端连接FPGA,START,OE,EOC,ADDA-C均连接FPGA,根据ADC0809的工作时序图,由FPGA给出相应的信号控制ADC0809。

数模转换局部采用的是DAC0832,具体连接图如下

DI0-DI7分别于FPGA的8位数据输出端相连,因为DAC0832工作在连续的负反响电路中,故采用直通的工作方式,将WR1与WR2直接与地相连,ILE与CS,Xfer引脚均接至FPGA,有FPGA发送控制信号来控制DAC0832的工作。

输出引脚Iout1与Iout2连接一个流压转换器,将输出的电流信号转换为需要的电压信号,并进展适当的放大。

最后输出到孵化器的加热电路。

FPGA模块控制ADC0809的工作状态,并接收来自ADC0809的数字信号,与键盘输入的预设信号进展比拟后,将控制信息传送给DAC0832,经由数模转换器转换后加在发热装置两端,对整个孵化器部温度进展控制。

整个的FPGA模块分为以下几个局部;

分频模块:

由于外界的时钟源一般都较高,而ADC0809以及键盘扫描模块需要的时钟频率较低,故需要对外界时钟源进展分频,这里外界输入时钟源为20MHz,对其进展64分频。

波形仿真图如下:

从波形图可以看出,clk每经过64个脉冲,clk1跳转一次。

分频模块工作正常;

统计报告图如下:

分频模块的VHDL文件见附录1.

键盘模块:

键盘模块的脉冲输入来自分频模块。

其中,输入端口为两位二进制数,分别接两个按键,来对预设温度进展加减调控。

输出有两个端口,xianshi端口作为保存端口,存储着当前预设温度的数值,可外接显示设备。

zhi端口为信息传送端口,其存储值为当前预设温度值经由采集电路温度—电压公式换算后的十进制数值。

换算公式如下:

例:

38摄氏度对应的ADC0809输出数据为5*38*256/100/5,得到十进制值为97;

波形仿真图如下:

图〔1〕

图〔2〕

图中,shuru〔1〕为温度减按键,shuru〔0〕为温度加按键,相应的预设温度对应相应的ADC0809输出值,由图2得,当预设温度为38摄氏度时,对应换算后的ADC0809输出数据为97,与计算相符。

键盘输入模块工作正常。

统计报告图如下:

键盘模块的VHDL文件见附录2.

ADC0809控制模块:

经查阅资料,DAC0832需采用直通式,故,将DAC0832的控制语句直接写在了ADC0809的控制语句块。

ile为输出到ADC0832的输入锁存允许信号,cont为ADC0832WR1,WR2,CS等引脚。

Wendu为预设温度的输入引脚。

din为ADC0809转换后的输出信号,dout为受FPGA控制的输出到DAC0832的控制信号。

clk8为来自为频器的时钟信号。

根据ADC0809的时序图,总结出相应的状态转移图,一次来编写控制ADC0809的VHDL语言文件,状态转移图如下:

 

具体波形仿真图如下:

波形仿真建立在预设温度为38摄氏度的条件下。

前面提到,38摄氏度对应的ADC0809输出值为97,VHDL程序中设定,当ADC0809输入值大于或等于97时〔当前温度大于或等于预设温度〕,FPGA输出到DAC0832的控制信号为0,即停顿加热。

当ADC0809输入值小于92〔即36摄氏度,与设定温度相差大于两度〕时,FPGA输出到DAC0832的控制信号为255,即以最大功率加热。

当ADC0809输入值小于92时,将会细分为5个阶段,即以逐次递减的功率加热。

由图可知,ADC0809工作正常。

统计报告图如下:

ADC0809模块的VHDL仿真文件见附录3.

最后,将三个模块运用元件例化语句连接在一块,并进展电路观察,生成相应的逻辑电路,如以下列图:

总体波形仿真如以下列图

波形分析:

刚开场,FPGAjia置1,预设温度逐渐增加,如以下列图

当温度到达38摄氏度后停顿增加,即将38摄氏度作为预设温度,随后,观察FPGAin与FPGAout。

当预设温度为38摄氏度时,输入为97时,对应输出为0,当为92时,对应输出为5,当为96时,对应输出为1,当输入不在92-97之间,输入大于97时,输出为0,输入小与92时,输出为255.观察上图波形仿真,完全符合程序设计。

后面给FPGAjian置1,预设温度会随之降低。

统计报告图如下:

总体的VHDL程序见附录4.

 

附录1:

LIBRARYIEEE;

USEIEEE.STD_LOGIC_1164.ALL;

USEIEEE.STD_LOGIC_ARITH.ALL;

USEIEEE.STD_LOGIC_UNSIGNED.ALL;

entityfenpinis

port(clk:

instd_logic;--外部输入时钟源

clk1:

outstd_logic);endfenpin;--分频后的时钟源

architectureboffenpinis

signalcount:

std_logic_vector(7downto0);--信号定义

signalclk2:

std_logic;

begin

process(clk)

begin

if(clk'eventandclk='1')then--计数脉冲上升沿

if(count="01000000")then

count<=(others=>'0');clk2<=notclk2;--当到达64个脉冲时count置0,clk2取反

else

count<=count+1;--未到达64脉冲时继续计数;

endif;

endif;

clk1<=clk2;——将产生的分频信号给输出端口

endprocess;

endb;

 

附录2:

libraryieee;

useieee.std_logic_1164.all;

useieee.std_logic_arith.all;

useieee.std_logic_unsigned.all;

entityjianpanis

port(clk:

instd_logic;--分频后的时钟输入

shuru:

instd_logic_vector(1downto0);--输入端,按键加0位,按键减1位

zhi:

outinteger;--预设温度转化为ADC0809输出值

xianshi:

outinteger);--当前预设温度

endentity;

architecturebehaofjianpanis

signalx:

integerrange0to200;--定义信号

begin

process(clk)

begin

if(clk'eventandclk='1')then

caseshuruis--检测是否有输入

when"01"=>x<=x+1;--按键加按下,温度+1

when"10"=>if(x=0)thenx<=0;--按键减按下,判断温度是否为0

elsex<=x-1;--假设为0,那么依旧为0,否那么,温度-1

endif;

whenothers=>x<=x;--其他按键情况,温度不变

endcase;

endif;

xianshi<=x;--将温度赋给显示输出端

zhi<=x*5*256/100/5;--将温度转化后赋给输出端

endprocess;

endbeha;

 

附录3:

libraryieee;

useieee.std_logic_1164.all;

useieee.std_logic_arith.all;

useieee.std_logic_unsigned.all;

entityADC0809is

port(din:

instd_logic_vector(7downto0);--ADC0809输出的采样数据

clk8:

instd_logic;--时钟信号

eoc:

instd_logic;--ADC0809转换完毕指示,高电平有效

ale:

outstd_logic;--ADC0809地址锁存次信号

ile:

outstd_logic;--DAC0832数据锁存允许

cont:

outstd_logic;--DAC0832控制信号〔WR1,WR2,CS,Xfer〕

start:

outstd_logic;--ADC0809转换启动信号

oe:

outstd_logic;--ADC0809数据输出允许信号

wendu:

ininteger;--温度显示

adda:

outstd_logic;--ADC0809信号通道控制位

addb:

outstd_logic;--ADC0809信号通道控制位

addc:

outstd_logic;--ADC0809信号通道控制位

lock0:

outstd_logic;--ADC0809观察数据锁存时钟

dout:

outstd_logic_vector(7downto0));--输出到DAC0832的8位数据

endADC0809;

architecturebehaofADC0809is

typestatesis(st0,st1,st2,st3,st4);--定义ADC0809工作状态

signalcurrent_state,next_state:

states:

=st0;--定义信号

signalregl:

std_logic_vector(7downto0);

signalshuchu:

std_logic_vector(7downto0);

signallock:

std_logic;

signalcount:

std_logic_vector(7downto0);

begin

adda<='1';--地址输入001,选择IN1

addb<='0';

addc<='0';

dout<=shuchu;-将处理后的数据传输到输出端口

lock0<=lock;--数据传输

ile<='1';--DAC0832的控制信号

cont<='0';

:

process(current_state,eoc)--状态转移

begin

casecurrent_stateis

whenst0=>ale<='0';start<='0';lock<='0';oe<='0';next_state<=st1;

whenst1=>ale<='1';start<='1';lock<='0';oe<='0';next_state<=st2;

whenst2=>ale<='0';start<='0';lock<='0';oe<='0';next_state<=st1;

if(eoc='1')thennext_state<=st3;

elsenext_state<=st2;

endif;

whenst3=>ale<='0';start<='0';lock<='0';oe<='1';next_state<=st4;

whenst4=>ale<='0';start<='0';lock<='1';oe<='1';next_state<=st0;

whenothers=>next_state<=st0;

endcase;

endprocess;

reg:

process(clk8)

begin

if(clk8'eventandclk8='1')

thencurrent_state<=next_state;--在时钟上升沿改变状态

endif;

endprocessreg;

latch1:

process(lock)

begin

iflock='1'andlock'eventthenregl<=din;--将输入数据赋给中间变量

endif;

endprocesslatch1;

kongzhi:

process(regl)

begin

if(regl

casewendu-reglis--判断输入数据与预设温度的

when"00000101"=>shuchu<="00000101";--差值为5时输出控制信号5

when"00000100"=>shuchu<="00000100";--差值为4时输出控制信号4

when"00000011"=>shuchu<="00000011";--差值为3时输出控制信号3

when"00000010"=>shuchu<="00000010";--差值为2时输出控制信号2

when"00000001"=>shuchu<="00000001";--差值为1时输出控制信号1

whenothers=>shuchu<="11111111";--差值大于5时输出255

endcase;

elseshuchu<="00000000";--当前温度大于预设温度,输出0

endif;

endprocesskongzhi;

endbeha;

 

附录4:

libraryieee;

useieee.std_logic_1164.all;

useieee.std_logic_unsigned.all;

useieee.std_logic_arith.all;

entityFPGAis

port(clkin:

instd_logic;--定义外部时钟端口

FPGAeoc:

instd_logic;

FPGAin:

instd_logic_vector(7downto0);

FPGAout:

outstd_logic_vector(7downto0);

FPGAale:

outstd_logic;

FPGAjia:

instd_logic;

FPGAjian:

instd_logic;

FPGAwendu:

outinteger;

FPGAile:

outstd_logic;

FPGAcont:

outstd_logic;

FPGAstart:

outstd_logic;

FPGAoe:

outstd_logic;

FPGAadda:

outstd_logic;

FPGAaddb:

outstd_logic;

FPGAaddc:

outstd_logic);

endentity;

architecturebehaofFPGAis

ponentADC0809is--元件例化声明

port(din:

instd_logic_vector(7downto0);

clk8:

instd_logic;

eoc:

instd_logic;

ale:

outstd_logic;

ile:

outstd_logic;

cont:

outstd_logic;

start:

outstd_logic;

wendu:

ininteger;

oe:

outstd_logic;

adda:

outstd_logic;

addb:

outstd_logic;

addc:

outstd_logic;

lock0:

outstd_logic;

dout:

outstd_logic_vector(7downto0));

endponent;

ponentfenpinis--元件例化声明

port(clk:

instd_logic;

clk1:

outstd_logic);

endponent;

ponentjianpanis

port(clk:

instd_logic;

shuru:

instd_logic_vector(1downto0);

zhi:

outinteger;

xianshi:

outinteger);

endponent;

signalc:

std_logic;--定义中间变量

signaln:

integer;

begin

U0:

fenpinportmap(clk=>clkin,clk1=>c);--元件例化

U1:

ADC0809portmap(clk8=>c,wendu=>n,din=>FPGAin,eoc=>FPGAeoc,dout=>FPGAout,ale=>FPGAale,ile=>FPGAile,

cont=>FPGAcont,start=>FPGAstart,oe=>FPGAoe,adda=>FPGAadda,addb=>FPGAaddb,addc=>FPGAaddc);

U2:

jianpanportmap(clk=>c,shuru

(1)=>FPGAjian,shuru(0)=>FPGAjia,zhi=>n,xianshi=>FPGAwendu);

endbeha;

LIBRARYIEEE;

USEIEEE.STD_LOGIC_1164.ALL;

USEIEEE.STD_LOGIC_ARITH.ALL;

USEIEEE.STD_LOGIC_UNSIGNED.ALL;

entityfenpinis

port(clk:

instd_logic;--外部输入时钟源

clk1:

outstd_logic);endfenpin;--分频后的时钟源

architectureboffenpinis

signalcount:

std_logic_vector(7downto0);--信号定义

signalclk2:

std_logic;

begin

process(clk)

begin

if(clk'eventandclk='1')then--计数脉冲上升沿

if(count="01000000")then

count<=(others=>'0');clk2<=notclk2;-当到达64个脉冲时count置0,clk2取反

else

count<=count+1;--未到达64脉冲时继续计数;

endif;

endif;

clk1<=clk2;——将产生的分频信号给输出端口

endprocess;

endb;

libraryieee;

useieee.std_logic_1164.all;

useieee.std_logic_arith.all;

useieee.std_logic_unsigned.all;

entityjianpanis

port(clk:

instd_logic;--分频后的时钟输入

shuru:

instd_logic_vector(1downto0);--输入端,按键加0位,按键减1位

zhi:

outinteger;--预设温度转化为ADC0809输出值

xianshi:

outinteger);--当前预设温度

endentity;

architecturebehaofjianpanis

signalx:

integerrange0to200;--定义信号

begin

process(clk)

begin

if(clk'eventandclk='1')then

caseshuruis--检测是否有输入

when"01"=>x<=x+1;--按键加按下,温度+1

when"10"=>if(x=0)thenx<=0;--按键减按下,判断温度是否为0

elsex<=x-1;--假设为0,那么依旧为0,否那么,温度-1

endif;

whenothers=>x<=x;--其他按键情况,温度不变

endcase;

endif;

xianshi<=x;--将温度赋给显示输出端

zhi<=x*5*256/100/5;--将温度转化后赋给输出端

endprocess;

endbeha;

 

libraryieee;

useieee.std_logic_1164.all;

useieee.std_logic_arith.all;

useieee.std_logic_unsigned.all;

entityADC0809is

port(din:

instd_logic_vector(7downto0);--ADC0809输出的采样数据

clk8:

instd_logic;--时钟信号

eoc:

instd_logic;--ADC0809转换完毕指示,高电平有效

ale:

outstd_logic;--ADC0809地址锁存次信号

ile:

outstd_logic;--DAC0832数据锁存允许

cont:

outstd_logic;--DAC0832控制信号〔WR1,WR2,CS,Xfer〕

start:

outstd_logic;--ADC0809转换启动信号

oe:

outstd_logic;--ADC0809数据输出允许信号

wendu:

ininteger;--温度显示

adda:

outstd_logic;--ADC0809信号通道控制位

addb:

outstd_logic;--

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 表格模板 > 合同协议

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1