数字电路课程设计报告
题目:FPGA控制ADC0809的温度采集及控制系统设计
学院: 机电工程学院
专业: 自动化
姓名: XXXX
学号: 04123137
指导老师: XXXX
时间: 20## .9.4~20##.10.15
FPGA控制ADC0809的温度采集及控制系统设计
一、设计目的
温度是日常生活中无时不在的物理量,温度的控制在各个领域有着广泛积极的意义。如温室的温度控制等。另外随着数字电子技术的迅速发展,将模拟电量转换成数字量输出的接口电路A/D转换器是现实世界中模拟信号向数字信号的桥梁。在以往的A/D器件采样控制设计中,多数是以单片机或CPU为控制核心,虽然编程简单,控制灵活,但缺点是控制周期长,速度慢。单片机的速度极大的限制了A/D高速性能的利用,而FPGA的时钟频率可高达100MHz以上。本设计进行时序控制、码制变换,具有开发周期短,灵活性强,通用能力好,易于开发、扩展等优点。
二、设计的基本内容
本次设计主要是基于FPGA+VHDL的温度控制系统,可编程器件FPGA和硬件描述语言VHDL的使用使得数字电路的设计周期缩短、难度减少。设计采用模块化思路,包括四个模块FPGA控制ADC0809模块、分频模块、数据传输模块、元件例化模块,再加以整合实现整个系统,达到温度控制的目的。
基于FPGA的信号采集系统主要有:A/D转换器,FPGA,RS232通信。A/D 转换器对信号进行会采集,A/D 内部集成了采样、保持电路,可有效的降低误差,减少外围电路的设计,降低系统的功耗。A/D在接受到指令后进行采集,FPGA采集控制模块首先将采集到的通过A/D 转换城的数字信号引入FPGA,而后对数字信号送往算法实现单元进行处理,并存于FPGA内部RAM中。
温度测量图
FPGA控制ADC0809模块
VHDL程序
library ieee;
use ieee.std_logic_1164.all;
entity ad_control is
port(
d : in std_logic_vector(7 downto 0); --0809的8位转换数据输出
clk ,eoc : in std_logic; --clk是转换工作时钟
lock1,ale,start,oe,adda :out std_logic;
q : out std_logic_vector(7 downto 0)
);
end ad_control;
architecture rtl of ad_control is
type state is (s0,s1,s2,s3,s4,s5,s6); --定义个状态子函数
signal current_state,next_state : state;
signal regl : std_logic_vector (7 downto 0);
signal lock : std_logic; -- 转换后数据输出锁存时钟信号
begin
adda <= '1';
lock1 <= lock;
process(current_state,eoc) --规定各状态工作方式
begin
case current_state is
when s0 => ale <= '0';
start <= '0';
oe <= '0';
lock <= '0';
next_state <= s1;
when s1 => ale <= '1';
start <= '0';
oe <= '0';
lock <= '0';
next_state <= s2;
when s2 => ale <= '0';
start <= '1';
oe <= '0';
lock <= '0';
next_state <= s3;
when s3 => ale <= '0';
start <= '0';
oe <= '0';
lock <= '0';
if (eoc = '1') then --检测eoc的下降沿
next_state <= s3;
else
next_state <= s4;
end if;
when s4 => ale <= '0';start <= '0';oe <= '0';lock <= '0';if (eoc = '0') then --测试eoc的上升沿
next_state <= s4; else --eoc = '1'、表明数据转化结束
next_state <= s5;
end if;
when s5 => ale <= '0';
start <= '0'; oe <= '1'; lock <= '0'; next_state <= s6;
when s6 => ale <= '0'; start <= '0'; oe <= '1'; lock <= '1';next_state <= s0;
when others =>ale <= '0'; start <= '0'; oe <= '0';lock <= '0';next_state <= s0;
end case;
end process;
process(clk) --状态转换进程
begin
if (clk 'event and clk = '1') then
current_state <= next_state;
end if;
end process;
process(lock) --数据锁存进程
begin
if (lock 'event and lock = '1' ) then
regl <= d;
end if;
end process;
q <= regl;
end rtl;
Flow Summary
仿真波形图
结果说明:在S0状态中的RESET为复位信号,在此状态下输出ALE<='0';START<='0';OE<='0';LOCK<='0';表示对ADC0809的初始化。在S1状态下输出ALE<='1';START<='0';OE<='0';LOCK<='0';其中ALE上升沿有效,此状态下模拟信号输入选通。在S2状态下,输出ALE<='0';START<='1';OE<='0';LOCK<='0';START信号有效,启动A/D转换。在S3状态下,输出ALE<='0';START<='0';OE<='0';LOCK<='0';在此状态中检测EOC的下降沿,如果EOC的下降沿来了则启动采样,否则,等待启动采样。在S4状态下,输出ALE<='0';START<='0';OE<='0';LOCK<='0';在此状态中检测EOC的上升沿,如果EOC的上升沿来了则停止采样,否则,采样周期中等待。在S5状态下,输出ALE<='0';START<='0';OE<='1';LOCK<='0';OE为高电平,则控制打开三态缓冲器,把转换好的8位数据结果输至数据总线。
在S6状态下,输出ALE<='0';START<='0';OE<='1';LOCK<='1';至此一次完整地采样控制结束。
2.分频模块
VHDL程序
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL; --使用库函数
entity adcint is
Port ( clk : in std_logic; --系统时钟
clk1: out std_logic; --分频后的时钟输出
shuout: out std_logic_vector(7 downto 0)); --8位二进制输出端
end adcint;
architecture Behavioral of adcint is --结构体
begin
process(clk) --进程
variable cnt:integer range 0 to 49999999; --系统时钟为50MHZ
begin
if clk'event and clk='1' then
if cnt=500 then --分频系数为800
cnt:=0;
clk1<='1';
else
cnt:=cnt+1;
clk1<='0';
end if;
end if;
end process; --结束进程
shu:process(clk) --
variable cnt:integer range 0 to 49999999; --定义整型变量
variable p:std_logic_vector(7 downto 0):="00000000";
variable full:integer range 0 to 499; --定义整型变量
begin
if clk'event and clk='1' then
if full=640 then
full:=0;
p:=p+1;
else
full:=full+1;
end if;
end if;
if p="11111111" then --当P计数满后,清零重新开始计数
p:="00000000";
end if;
shuout<=p;
end process shu;
end Behavioral;
波形仿真图
仿真结果说明:clk为系统时钟,所加频率为50MHZ;clk1为adc0809的控制时钟,分频系数500,频率为100khz;shuout为八位二进制输出。
数据传输模块
数据传输设计图
VHDL程序
library IEEE; --使用库函数
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL; --使用程序包
entity trans is
PORT(clk:in std_logic;
reset:in std_logic; --复位
enable:in std_logic; --发送使能
datain:in std_logic_vector(7 downto 0); --发送十六进制代码
TxD:out std_logic); --发送端
end trans;
architecture Behavioral of trans is
signal TReg:Std_Logic_Vector(7 downto 0); --发送寄存器
signal SampleCnt:std_logic_vector(0 to 1);
begin
TReg<=datain; --Rx Process
RxProc:process(clk,reset,enable)
variable BitPos:INTEGER range 0 to 9; --发送寄存器的位置
begin
if reset='0' then
BitPos:=0;SampleCnt<="00";
elsif Rising_Edge(clk) then
if reset='1' then --复位
if SampleCnt="11" then SampleCnt<="00";
else SampleCnt<=SampleCnt+1; --从0到3每位计数
end if;
case BitPos is
when 0=> if SampleCnt="01" then --起始位
TxD<='0'; --发送起始位
Bitpos:=BitPos+1; end if;
when 1=> if SampleCnt="01" then
TxD<=Treg(0); --发送第1位
BitPos:=BitPos+1; end if;
when 2=> if SampleCnt="01" then
TxD<=Treg(1); --发送第2位
BitPos:=BitPos+1;end if;
when 3=> if SampleCnt="01" then
TxD<=Treg(2); --发送第3位
BitPos:=BitPos+1;
end if;
when 4=> if SampleCnt="01" then
TxD<=Treg(3); --发送第4位
BitPos:=BitPos+1;
end if;
when 5=> if SampleCnt="01" then
TxD<=Treg(4); --发送第5位
BitPos:=BitPos+1;
end if;
when 6=> if SampleCnt="01" then
TxD<=Treg(5); --发送第6位
BitPos:=BitPos+1;
end if;
when 7=> if SampleCnt="01" then
TxD<=Treg(6); --发送第7位
BitPos:=BitPos+1;
end if;
when 8=>
if SampleCnt="01" then
TxD<=Treg(7); --发送第8位
BitPos:=BitPos+1;
end if;
when 9=> if SampleCnt="01" then
TxD<='1'; --发送第9位
BitPos:=BitPos+1;
end if;
end case;
else TxD<='1';
BitPos:=0;
SampleCnt<="00";
end if;
end if;
end process;
end Behavioral;
Flow Summary
波形仿真图
仿真结果说明:datain是数据输入,在这里我输入了十六进制数55,使能端enable和reset在置高电平1时使能端有效,数据发送出去,发送端TxD输出了55,因为输入端一直加入的是55,所以输出TxD周期性的,由仿真图可以看出明显的周期性。
元件例化模块将单个模块连接为整体(FPGA)
VHDL程序:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity FPGA is
port( CLK,EOC: in std_logic; --CLK为系统时钟;EOC为ADC0809转换结束信号输入FPGA
CLK1,START,ALE,OE: out std_logic; --CLK1为ADC0809工作时钟;START为转换启动信号;ALE为地址锁存信号;OE为数据输出控制信号;均从FPGA输出
D : in std_logic_vector (7 downto 0); --ADC0809输出的采样数据输入FPGA
ile:out std_logic; --数据锁存允许信号
cont:out std_logic; --控制信号(WR1、WR2、CS、Xfer)
Q: out std_logic_vector(7 downto 0); --经数据处理后转化为温度所对应的从FPGA输出的二进制数据
y:out std_logic_vector(7 downto 0);
se1:out std_logic_vector(6 downto 0);
se2:out std_logic_vector(6 downto 0);
ADDA:out std_logic;
ADDB:out std_logic;
ADDC:out std_logic;
LOCK1 : out std_logic; --寄存器锁存测试信号
q1:out integer range 0 to 255 ); --数据处理过程中的整型数据
end FPGA;
architecture b of FPGA is
component led_decoder is --led_decoder元件例化申明部分
port(a:in std_logic_vector(3 downto 0);
b:in std_logic_vector(3 downto 0);
seg1:out std_logic_vector(6 downto 0);
seg2:out std_logic_vector(6 downto 0));
end component;
component ADC0809 is --ADC0809元件例化申明部分
port( CLK,EOC: in std_logic;
CLK1,START,ALE,OE: out std_logic;
D : in std_logic_vector (7 downto 0);
ile:out std_logic;
cont:out std_logic;
Q: out std_logic_vector(7 downto 0);
a:out std_logic_vector(3 downto 0);
b:out std_logic_vector(3 downto 0);
y:out std_logic_vector(7 downto 0);
ADDA:out std_logic;
ADDB:out std_logic;
ADDC:out std_logic;
LOCK1 : out std_logic;
q1:out integer range 0 to 255);
end component;
signal s1: std_logic_vector(6 downto 0); --用于总的seg1与ADC0809的seg1连接
signal s2: std_logic_vector(6 downto 0); --用于总的seg2与ADC0809的seg2连接
signal u:std_logic_vector(3 downto 0); --用于ADC0809与led_decoder的a端口相连
signal v:std_logic_vector(3 downto 0); --用于ADC0809与led_decoder的b端口相连
begin
U0:ADC0809 port map(clk=>clk,EOC=>EOC,clk1=>clk1,START=>START,ALE=>ALE,oe=>oe,d=>d,ile=>ile,cont=>cont,
q=>q,a=>u,b=>v,y=>y,ADDA=>adda,addb=>addb,addc=>addc,lock1=>lock1,q1=>q1); --ADC0809元件例化部分
U1:led_decoder port map(a=>u,b=>v,seg1=>s1,seg2=>s2); ----led_decoder元件例化部分
se1<=s1;
se2<=s2;
end b;
Flow Summary
仿真波形图
仿真结果说明:CLK是系统所给频率为50MHZ,经128分频后CLK1为390.6KHZ.
2)ADDA,ADDB,ADDC分别是1,0,0表示选通通道一。
3)控制器发送有效的ALE信号,锁存该地址,以备转换该地址对应的模拟量通道上的模拟量。控制器随即发送START信号启动A/D转换,一旦转换启动,ADC0809会在EOC引脚上输出表示转换进行的低电平信号。待E0C变为高电平,表示转换已完成,此时控制器就可以发送OE信号,控制ADC0809将转换完的数据送到输出引脚上。如图所示,图中数据转换时间为183.99us。符合ADC0809工作时序图。
4)cont为低电平,ile为高电平,表示成为直通型连续反馈工作方式,两个寄存器均处于常通状态,两个寄存器的输出跟随数字输入而变化。即DAC0832处于直通型工作状态。
5)D为经ADC0809转换送来的二进制数据,图中给出“01111111”,q1为输出中间信号,和D值相同,Q为经数据转换后的输出温度,图中为24°C,表明当一个模拟量V0输入至ADC0809转换后得到的D经一系列的处理转化后得到的与该模拟量所对应的温度T=24°C。
6)y是经控制模块从FPGA输出到DAC0832的二进制值,由程序看出,当T为24°C 时,y输出为“00110011”,由时序图看出y的确为“00110011”,满足要求。
7)a,b为输出端口,将与数码管端口相连,图中看出a=“0010”b=“0100”即a代表十位2,b代表个位4.表示24°C。
与预期结果一致,元件例化成功。
执 行 电 路 图
设计心得
通过本次设计过程,是我对ADC0809有了一定的了解,大致懂得如何编写VHDL程序,并在看完QuartusII教程后,学会了在QuartusII上进行程序运行并且进行波形的仿真。
在设计中,利用硬件描述语言—VHDL编程时,曾经遇到过一些比较棘手的问题,编程总是出错,通过不断的查阅、思考,问题最终还是成功解决。通过看相关的书籍以及上网查资料学到了很多,了解了一项新的编程语言,总之本次设计实验过程收获很大,也很感谢中间过程同学的帮助
参考文献:
⑴ 杨颂华 冯毛官 孙万蓉 数字电子技术基础(第二版)[M]西安电子科技大学出版社2008
⑵侯伯亨顾新.VHDL硬件描述语言与数字逻辑电路[M].西安:西安电子科技大学出版社.1999
⑶朱明程编著.FPGA原理及应该设计[M]. 北京:电子工业出版社.1994