3.25k likes | 3.47k Views
可编程逻辑器件讲义. 第四讲 实例分析与设计. 本讲主要内容. 数码显示电路、矩阵键盘接口电路 正弦信号发生器设计、 ROM 定制、 RAM 定制、 FIFO 定制 嵌入式锁相环、 8051IP 核使用 状态机设计、序列检测器、 ADC0809 采样控制电路、比较器和 DA 器件实现 AD 转换功能. 本讲主要内容. 16×16 点阵显示、 LCD 显示接口设计 音乐演奏电路、 DDS 设计 等精度频率计( 8051IP 核)、直流电机驱动电路设计 步进电机驱动设计 VGA 显示器驱动设计 NiosII 软核嵌入式系统设计.
E N D
可编程逻辑器件讲义 第四讲 实例分析与设计
本讲主要内容 • 数码显示电路、矩阵键盘接口电路 • 正弦信号发生器设计、ROM定制、RAM定制、FIFO定制 • 嵌入式锁相环、8051IP核使用 • 状态机设计、序列检测器、ADC0809采样控制电路、比较器和DA器件实现AD转换功能
本讲主要内容 • 16×16点阵显示、LCD显示接口设计 • 音乐演奏电路、DDS设计 • 等精度频率计(8051IP核)、直流电机驱动电路设计 • 步进电机驱动设计 • VGA显示器驱动设计 • NiosII软核嵌入式系统设计
数码显示电路的VHDL设计 • 数码管显示驱动方法 • 专用译码驱动电路 7448等 • 单片机指令译码驱动 查表法 • PLD器件译码驱动 原理图、VHDL语言
a b c d e f g dp SEL2 SEL0 SEL1 数码显示电路的VHDL设计 • 单数码管静态显示驱动设计 实验箱上数码管采用的是共阴 驱动方式,单管时不防SEL2、 SEL1、SEL0固定接为高电平
数码显示电路的VHDL设计 • 单数码管静态显示驱动设计 单管驱动最终设计的就是一个4至7(8)的译码电路 LED7S最低位为 a,最高位为g • LIBRARY IEEE ; • USE IEEE.STD_LOGIC_1164.ALL ; • ENTITYDECL7S IS • PORT ( A: IN STD_LOGIC_VECTOR(3 DOWNTO 0); • LED7S : OUT STD_LOGIC_VECTOR(6 DOWNTO 0) ) ; • END ;
数码显示电路的VHDL设计 • 单数码管静态显示驱动设计 ARCHITECTURE one OF DECL7S IS BEGIN PROCESS( A ) BEGIN CASE A IS WHEN "0000" => LED7S <= "0111111" ; WHEN "0001" => LED7S <= "0000110" ; … WHEN "1110" => LED7S <= "1111001" ; WHEN "1111" => LED7S <= "1110001" ; WHEN OTHERS => NULL ; END CASE ; END PROCESS ; END ; CASE语句是顺序语句, 只能在进程或子程序中使用 如果换成WHEN_ELSE语句, 如何表达??
数码显示电路的VHDL设计 • 8数码管动态扫描显示设计 • 什么是动态扫描? 该设计显示的数据来 自模块内部,不具备 通用性!!
数码显示电路的VHDL设计 • 8数码管动态扫描显示设计 LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY SCAN_LED IS PORT ( CLK : IN STD_LOGIC; SG : OUT STD_LOGIC_VECTOR(6 DOWNTO 0); --段控制信号输出 BT : OUT STD_LOGIC_VECTOR(2 DOWNTO 0) ); --位控制信号输出 END;
数码显示电路的VHDL设计 • 8数码管动态扫描显示设计 • 在结构体的说明部分定义两个信号 • ARCHITECTURE one OF SCAN_LED IS • SIGNAL CNT8 : INTEGER RANGE 0 TO 7; • SIGNAL A : INTEGER RANGE 0 TO 15; • BEGIN 信号常作为进程之间通信的 手段
数码显示电路的VHDL设计 • 8数码管动态扫描显示设计 • 第1个进程:模8计数模块 • P1:PROCESS(CLK) • BEGIN • IF CLK'EVENT AND CLK = '1' THEN • CNT8 <= CNT8 + 1; • END IF; • END PROCESS P1;
数码显示电路的VHDL设计 • 8数码管动态扫描显示设计 • 第2个进程:产生位选信号及显示数据 P2:PROCESS( CNT8 ) BEGIN CASE CNT8 IS WHEN 0 => BT <= "000" ; A <= 1 ; WHEN 1 => BT <= "001" ; A <= 3 ; WHEN 2 => BT <= "010" ; A <= 5 ; WHEN 3 => BT <= "011" ; A <= 7 ; WHEN 4 => BT <= "100" ; A <= 9 ; WHEN 5 => BT <= "101" ; A <= 11 ; WHEN 6 => BT <= "110" ; A <= 13 ; WHEN 7 => BT <= "111" ; A <= 15 ; WHEN OTHERS => NULL ; END CASE ;END PROCESS P2;
数码显示电路的VHDL设计 观察到的结 果是什么? • 8数码管动态扫描显示设计 • 第3个进程:显示数据的7段译码 扫描的速率与什么 有关?如果显示外部 数据? P3:PROCESS( A ) --译码电路 BEGIN CASE A IS WHEN 0 => SG <= "0111111"; WHEN 1 => SG <= "0000110"; … WHEN 14 => SG <= "1111001"; WHEN 15 => SG <= "1110001"; WHEN OTHERS => NULL ; END CASE ; END PROCESS P3; END;
矩阵键盘控制接口电路设计 • 实验箱(4×8)矩阵键盘简介 实验箱上矩阵键盘用到4×8结构 中共的30个键, 有两键未使用
矩阵键盘控制接口电路设计 • 实验箱(4×8)矩阵键盘简介 0 1 2 3 MEM ESC 4 5 6 7 REG EXEC 8 9 A B LAST STEP C D E F NEXT ENTER CTRL SHIFT 未用
矩阵键盘控制接口电路设计 KIN0 KIN1 KIN2 KIN3 • 实验箱(4×8)矩阵键盘简介 • 8行怎么选中? • SEL2 SEL1 SEL0 • 0 0 0 • 0 0 1 • 0 1 0 • 0 1 1 • 1 0 0 • 1 0 1 • 1 1 0 • 1 1 1 按键输出 低电平有 效
矩阵键盘控制接口电路设计 KIN0 KIN1 KIN2 KIN3 • 实验箱(4×8)矩阵键盘简介 按键对应关系表详细 见实验手册内容
矩阵键盘控制接口电路设计 时钟电路,产生扫描(键盘、数码管)时钟,键盘译盘电路时钟,去抖电路时钟 • 矩阵键盘控制接口电路顶层设计 译码显示 去抖电路 键盘译码 注意原理图 中数据线的 连接方式
矩阵键盘控制接口电路设计 • 时钟电路 • LIBRARY IEEE; • USE IEEE.STD_LOGIC_1164.ALL; • USE IEEE.STD_LOGIC_ARITH.ALL ; • USE IEEE.STD_LOGIC_UNSIGNED.ALL ; • ENTITY clk_block IS • PORT ( • CLK_1M ,clr : IN STD_LOGIC ; • SELOUT : OUT STD_LOGIC_VECTOR (2 downto 0) ; CLK_SCAN : OUT STD_LOGIC ; • CLK_KEY : OUT STD_LOGIC ); • END;
矩阵键盘控制接口电路设计 • 时钟电路 ARCHITECTURE behave of clk_block is Signal Q : STD_LOGIC_VECTOR(10 DOWNTO 0); BEGIN PROCESS (Clk_1M,clr) Begin IF clr=‘0' thenQ <=(others=>'0'); ELSIF CLK_1M'Event AND CLK_1M = '1' then Q <= Q+1; END IF;END PROCESS; CLK_KEY <= Q(0) ; CLK_SCAN <=Q(6); SELOUT <= Q(10 DOWNTO 8); END;
矩阵键盘控制接口电路设计 • 去抖电路 由4个1位去 抖构成4位 位去抖
矩阵键盘控制接口电路设计 keyin为按键输入,clk_sam为采样时钟。 • 去抖电路 三个D触发器,锁了三个不同时刻的按键值,当三时刻输入全为高电平时,key_h输出高电平;当三时刻输入全为低电平时,key_l输出低电平。 电路中D触发器的数量没有严格规定,但至少需要两个。
矩阵键盘控制接口电路设计 • 去抖电路
矩阵键盘控制接口电路设计 • 按键译码电路 LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL ; USE IEEE.STD_LOGIC_UNSIGNED.ALL ; ENTITY keys_decoder IS PORT ( CLK ,clr : IN STD_LOGIC ; SELTMP : IN STD_LOGIC_VECTOR (2 downto 0) ; KEY : IN STD_LOGIC_VECTOR (3 downto 0) ; KEY_CODE : OUT STD_LOGIC_VECTOR (4 DOWNTO 0)); END;
矩阵键盘控制接口电路设计 • 按键译码电路 ARCHITECTURE behave OF keys_decoder IS signal Z : std_logic_VECTOR(6 downto 0) ; SIGNAL ZOUT:STD_LOGIC_VECTOR(4 DOWNTO 0) ; begin Z<=KEY & SELTMP; KEY_CODE <= ZOUT; PROCESS(CLK,clr) begin IF clr=‘0’ then zout<=(others=>'0'); ELSIF CLK 'EVENT AND CLK = '1' THEN
矩阵键盘控制接口电路设计 • 按键译码电路 case Z is WHEN "1110000" => ZOUT <= "00000";--0 WHEN "1110001" => ZOUT <= "00001";--1 WHEN "1110010" => ZOUT <= "00010";--2 WHEN "1110011" => ZOUT <= "00011";--3 … WHEN "0111100" => ZOUT <= "11101";--NOP4 WHEN "0111101" => ZOUT <= "11001";--SHIFT WHEN "0111110" => ZOUT <= "11110";--NC WHEN "0111111" => ZOUT <= "11110";--NC WHEN OTHERS => null; end case ; END IF ; END PROCESS; END;
矩阵键盘控制接口电路设计 • 译码显示电路 LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL ; USE IEEE.STD_LOGIC_UNSIGNED.ALL ; ENTITY keys_display IS PORT ( SELTMP : IN STD_LOGIC_VECTOR (2 downto 0) ; BCDIN : IN STD_LOGIC_VECTOR (31 downto 0) ; SEGOUT : OUT STD_LOGIC_VECTOR(6 DOWNTO 0)); END;
矩阵键盘控制接口电路设计 • 译码显示电路 ARCHITECTURE behave OF keys_display IS Signal DB : STD_LOGIC_VECTOR (3 downto 0) ; Signal SEG : STD_LOGIC_VECTOR (6 downto 0) ; begin SEGOUT <= SEG;
矩阵键盘控制接口电路设计 注意:块的使用 根据扫描变化,将32位 数据分别译码显示 • 译码显示电路 MULTIPLEXER : BLOCK BEGIN DB <= BCDIN(3 DOWNTO 0) WHEN SELTMP = 0 ELSE BCDIN(7 DOWNTO 4) WHEN SELTMP = 1 ELSE BCDIN(11 DOWNTO 8) WHEN SELTMP = 2 ELSE BCDIN(15 DOWNTO 12) WHEN SELTMP = 3 ELSE BCDIN(19 DOWNTO 16) WHEN SELTMP = 4 ELSE BCDIN(23 DOWNTO 20) WHEN SELTMP = 5 ELSE BCDIN(27 DOWNTO 24) WHEN SELTMP = 6 ELSE BCDIN(31 DOWNTO 28); End Block MULTIPLEXER ;
矩阵键盘控制接口电路设计 • 译码显示电路 SEVEN_SEGMENT : Block Begin --ABCDEFG SEG <= "1111110" when DB= "0000" else "0110000" when DB= "0001" else "1101101" when DB= "0010" else … "1001111" when DB= "1110" else "0000000" when DB= "1111" ELSE--1000111 "0000000"; End Block SEVEN_SEGMENT; END;
矩阵键盘控制接口电路设计 • 译码显示电路 • VHDL语言中块的使用 • 块将结构体划分成多个等价并行部分 • 块与块之间是并行的,块的内部也是并行的 • 结构体本身就等价于一个BLOCK • 目的是在于改善并行语句及其结构的可读性 • 块可以嵌套 块标号:BLOCK 块说明部分 BEGIN 并行语句 END BLOCK 块标号;
正弦信号发生器设计 宏功能元件使用 元件例化与连接 • 设计原理 FPGA内完成 数据宽度8位 f=f0/64 6位计数器 地址发生器 数据存储 ROM 正弦波数据 8位D/A 64个存储单元 计数器(地址发生器)的宽度与ROM的地址宽度有关;ROM的数据宽度与D/A转换的宽度有关
正弦信号发生器设计 • 正弦数据ROM的定制 • 初始化文件的建立(*.mif *.hex) • ROM的定制与初始化
正弦信号发生器设计 • 正弦数据ROM的定制 • 初始化文件的建立(*.mif *.hex) • QuartusII菜单操作法 • C语言编译法 • 汇编语言生成法
正弦信号发生器设计 • 正弦数据ROM的定制 • 初始化文件的建立(*.mif *.hex) • QuartusII菜单操作法 • File/new… 选择other files/Memory Initialization File(或Hexadecimal(Intel-Format)File)文件类型 • 设置初始化文件大小和字宽 • 设置地址索引(Address Radix)和存储器索引(Memory Radix)的格式 • 添加初始化数据,保存文件
正弦信号发生器设计 Other files/ Memory Initialization File文件
正弦信号发生器设计 设置初始化文件的大小和字宽
正弦信号发生器设计 正弦信号初始化数据如何获得? 设置地址索引(Address Radix)和存储器索引(Memory Radix)的格式
正弦信号发生器设计 复制数据到初始化文件(*.mif或*.hex)表格中 在Matlab命令窗口键入如下指令: a=(reshape(round(127*cos(0:2*pi/64:2*pi*63/64)+128),8,8))'
正弦信号发生器设计 保存初始化文件(SINGT.mif)。如果新建的是16进制文件则扩展名为(*.hex)
正弦信号发生器设计 关闭初始化文件,留作定制ROM时使用。
正弦信号发生器设计 • 正弦数据ROM的定制 • 初始化文件的建立(*.mif *.hex) • QuartusII菜单操作法 • C语言编译法
正弦信号发生器设计 WIDTH=8; DEPTH=64; ADDRESS_RADIX=UNS; DATA_RADIX=UNS; CONTENT BEGIN 0 : 255; 1 : 254; … 62 : 253; 63 : 254; END; #include <stdio.h> #include "math.h" main() {int i;float s; for(i=0;i<64;i++) { s = cos(atan(1)*8*i/64); printf("%d : %d;\n",i,(int)((s+1)*255/2)); }} 将上述程序编译成可执行文件(romgen.exe),在DOS命令行下执行:romgen>sim_rom.mif。在用文本编辑器打开sim_rom.mif文件,加上必要的头文件说明部分。
正弦信号发生器设计 • 正弦数据ROM的定制 • 初始化文件的建立(*.mif *.hex) • QuartusII菜单操作法 • C语言编译法 • 汇编语言生成法
正弦信号发生器设计 在Keil C中建立工程,新建汇编源程序,输入如右图程序代码,编译生成16进制文件(*.hex)
正弦信号发生器设计 • 正弦数据ROM的定制 • 初始化文件的建立(*.mif *.hex) • ROM的定制与初始化 • 选择Tools/MegaWizard Plug-In Manager…菜单
选择器件类型(Cyclone) 输出文档的语言类型(VHDL) 宏器件类型选择 输出文件的名称