⑴ EPLDPLD器件的设计步骤
设计EPLD器件通常需要经过以下几个步骤:
首先,对电路逻辑功能进行描述。PLD器件的逻辑功能可以通过两种方式来表述,一是直观的原理图描述,它能直接将小规模集成电路的功能映射到PLD上,但表述可能不够简练。另一种是硬件描述语言(HDL)描述,如ABEL和VHDL。ABEL支持布尔方程、真值表和状态机,适用于简单的逻辑功能如计数器、译码器等;而VHDL,作为一种行为描述语言,类似C语言的编程结构,描述复杂逻辑设计时更为简洁,具有强大的逻辑描述和仿真能力,成为硬件设计的主流趋势。
接着,使用计算机软件编程和模拟。无论是HDL描述还是原理图,都必须通过软件编译,将逻辑功能转换成布尔代数表达式,并根据PLD器件特性适配为JED文件,即熔断丝文件。在实际应用前,常常通过软件模拟验证设计的正确性,确保其符合设计要求。
最后,通过编程器将JED文件下载到PLD器件。这个过程涉及JED文件的下载,通常需要专门的编程器,如河洛公司的ALL系列或南京西尔特公司的Super系列。编程器通过计算机的并行打印接口将JED文件传输到PLD器件中,实现逻辑功能在实际器件中的实现。
⑵ 如何实现CPLD计数功能的调试
一、实验目的
1. 熟悉CPLD的开发软件的基本使用。
2. 掌握CPLD逻辑电路设计方法。
3. 会用逻辑分析仪进行数字电路的测试分析。
二、实验任务和内容
1. 在CPLD中设计一个多位计数器电路,设计要求为:
(1)6位十进制加法/减法计数器,运行过程中可改变加法或减法;
(2)输入计数信号频率最高1MHz,信号电平为0~5V的脉冲信号。
(3)6位数码管动态扫描显示,显示亮度均匀,不闪烁。
(4)有手动清零按键。
2.对设计的电路进行软件仿真
3.计数器电路的CPLD下载、实验调试。
4.使用虚拟逻辑分析仪进行调试和测试
三、实验器材
1. 1.SJ-8002B电子测量实验箱 1台
2.计算机(具有运行windows2000和图形化控件的能力 1台
3.函数发生器 1台
4. SJ-7002 CPLD实验板 1块
5 . 短接线若干
四、实验原理
4.1 CPLD介绍
可编程逻辑器(PLD)是70年代发展起来的一种划时代的新型逻辑器件,一般来说,PLD器件是由用户配置以完成某种逻辑功能的电路。80年代末,美国ALTERA和XILINX公司采用E2CMOS工艺,分别推出大规模和超大规模的复杂可编程逻辑器件(CPLD)和现场可编程逻辑门阵列器件(FPGA),这种芯片在达到高度集成度的同时,所具有的应用灵活性和多组态功能是以往的LSI/VLSI电路无法比拟的。到90年代,CPLD/FPGA发展更为迅速,不仅具有电擦除特性,而且出现了边缘扫描及在线编程等高级特性。另外,外围I/O模块扩大了在系统中的应用范围和扩展性。较常用的有XILIN X公司的EPLD和ALTERA及LATTICE公司的CPLD。
CPLD/FPGA的设计开发采用功能强大的EDA工具,通过符合国际标准的硬件描述语言(如VHDL或VERILOG-HDL)来进行电子系统设计和产品开发,开发工具的通用性,设计语言的标准化以及设计过程几乎与所用的CPLD/FPGA器件的硬件结构没有关系,所以设计成功的逻辑功能软件有很好的兼容性和可移植性,开发周期短;易学易用,开发便捷。
尽管CPLD、FPGA以及其它类型的PLD器件的结构各有其特点和长处,但是概括起来它们都是由三大部分组成的:(1)一个二维的逻辑块阵列,构成器件的逻辑组成核心;(2)输入/输出块(3)连接逻辑块的互联资源,连线资源由各种长度的线段组成,也包括用于连接逻辑块之间,逻辑块与输入输出部分的可编程连接开关。
本CPLD实验电路板选用ALTERA公司的EPM7128SLC84器件,EPM7128SLC84的特点为:84引脚Pin,内部有128个宏单元、2500个等效逻辑门、15ns的速度、PLCC84封装形式。除电源引脚、地线引脚、全局控制引脚和JTAG引脚外,共提供了64个可用I/O脚,这些引脚可以任意配置为输入、输出和双向方式。
图1 CPLD芯片EPM7128SLC84外形图
4.2 CPLD(FPGA)器件的设计和验证步骤
一般可分为设计输入、编译、功能仿真和时延仿真、器件下载(编程)、硬件电路三个设计步骤以及相应的功能仿真、时序仿真和器件测试三个设计验证过程。
(1).设计输入:设计输入有多种方式,目前最常用的有电路图和硬件描述语言两种,对于简单的设计,可采用原理图的方式设计,对于复杂的设计可使用原理图或硬件描述语言(Verilog、AHDL、VHDL语言),或者两者混用,采用层次化设计方法,分模块层次地进行描述。原理图设计方法主要是按照数字系统的功能采用具体的逻辑器件组合来实现的,把这些由具体器件实现逻辑功能的电路图输入到软件当中。这种设计方法比较直观。硬件描述语言设计方法主要把数字系统的逻辑功能用硬件语言来描述
(2)编译:编译前先选择器件的系列、型号,分配输入/输出管脚进行管脚,然后开始编译编译是指从设计输入文件到熔丝图文件(CPLD)或位流文件(FPGA)的编译过程。在该过程中,编译软件自动地对设计文件进行综合、优化,并针对所选中的器件进行映射、布局、布线、产生相应的熔丝图或位流数据文件。
(3)仿真:分为功能仿真(Functional)和时延(Timing)仿真:编译成功的设计并不一定完全正确,可通过仿真来验证电路是否达到设计要求,基本思路是首先用波形编辑器编辑仿真文件,给输入加载不同的激励信号,然后运行仿真器,产生对应的输出,根据输入和输出的关系,以此判别设计的正确性。
(4)器件编程:器件编程就是将熔丝图文件或位流数据文件下载到相应的CPLD或FPGA器件中。
(5)系统硬件电路测试
图2 CPLD设计流程
4.3 设计软件的使用
对CPLD的设计可使用ALTERA公司的MAX-PLUSⅡ或Quartus Ⅱ,设计的主要步骤为:
(1)创建或打开一个工程。
(2)原理图输入方式:新建一个图形文件,输入符号(代表子模块或元件、输入输出引脚),连线,存盘。如图4所示为采用两片74190级联的两位十进制计数器电路,文件名为Z74190.gdf。
(3)文本输入方式:新建一个文本文件,输入HDL语言编写的电路,存盘。
(4)选择芯片为CPLD实验电路板选用的EPM7128SLC84器件,分配引脚。
(5)波形仿真,首先新建空白的波形文件,导入本设计电路的输入输出节点,给输入节点按照需要指定时钟信号和高低电平,开始仿真,得到结果,再分析结果。如图5为Z74190.gdf的仿真文件波形。
(6)CPLD程序的下载:我们采用的是并口下载电缆ByteBlaster,它可以对MAX7000S系列进行在线编程。该下载电缆具有以下几个部分:与PC机并行口相连的25针插座头、与PCB板插座相连的10针插头。其示意图如3所示。
图 3 并行电缆下载示意图
设计举例:图 4和图 5分别是用原理图方式设计的2位十进制计数器的原理图和软件仿真波形图。
图4两位十进制计数器电路图 图11-5 两位十进制计数器电路仿真波形图
4.4 CPLD实验电路板原理和虚拟逻辑分析仪使用
实验电路板的组成和虚拟逻辑分析仪的使用在本实验指导书的“实验四 逻辑分析仪的原理和应用”中已作了说明,请读者参考。图6 为CPLD板的详细电路图。CPLD与62芯插座定义表见表1和CPLD可供用户自定义的引脚见表2。
使用CPLD板的1.000MHz的晶振时钟,需放置CPLD板上S1短路块位置在右面。
表1 CPLD和62芯插座连线引脚定义
引脚名称 CPLD
芯片引脚
62芯插座引脚
说明
引脚名称
CPLD对应脚
62芯插座引脚
说明
DO0
P40
16
连接逻辑分析仪的24个输入通道
DO24
P63
28
系统保留
DO1
P36
48
DO25
P76
60
DO2
P41
17
DO26
P64
29
DO3
P44
49
DO27
P75
61
DO4
P45
18
DO28
P68
30
DO5
P46
50
VCC
P3,P13,
P26,P3
P43,P5,
P66,P78
31,62
+5V电源
DO6
P48
19
DO7
P49
51
DO8
P50
20
DO9
P51
52
GND
P1,P7,
P19,P32,
P42,P47,
P59,P72,
P82,P84
13,44
电源地
DO10
P55
21
DO11
P52
53
DO12
P54
22
DO13
P65
54
DO14
P57
23
CPLD时钟源
sourceCLK
P83
45
由S1短路
选择接
CPLD-CLK1
DO15
P67
55
DO16
P56
24
DO17
P69
56
DO18
P58
25
outsideclk
P39
15
选择接(P83)
DO19
P70
57
allCLR
P35
47
系统总清零
DO20
P61
26
outside_tri
P37
14
外部触发
DO21
P73
58
DO22
P60
27
DO23
P74
59
表2 用户可用的CPLD自定义I/O引脚
P4 P5
P6
P8
P9
P10
P11
P15
P16
P17
P18
P20
P21
P22
P24
P25
P27
P28
P29
P30
P31
P77
P79
P80
P81
图6 CPLD实验板电路原理图
五、设计指导:
设计和调试的过程是:①任务分析,层次分解,得到顶层设计框图,大致确定每个子模快(子电路)的功能、输入和输出;②子模快电路设计和软件仿真;③完成顶层电路设计,顶层仿真;④分配引脚,下载,连线和调试。
软件仿真注意尽量给定符合实际电路工作的输入电平、时钟,仿真最小间隔不小于20ns,仿真时间长短适中。
5.1 设计任务分析
根据设计任务,可分为两大部分:多位计数器电路和计数结果动态显示电路。根据CPLD电路的层次化设计功能,设计出如图7所示的顶层设计框图。
6位十进制的计数器对输入的脉冲计数,有加减计数控制和清零计数值控制,输出6位十进制计数值,每位都用4位BCD码表示,共有24根线。
根据动态扫描显示的需要,必须设计一个6位BCD选1的多路数据选择器,输出的一位BCD码(4根线)送给BCD-七段译码器译成段信号,从CPLD输出给数码管的7段。同时多路数据选择器的控制选通信号需要3根,必须与6位数码管的位选信号同步。
位选信号来自电路板的时钟(1MHz)分频,在用译码器译码(每次只能选中一个数码管)。要保证多位显示均匀和不闪烁,请计算和设计分频的频
电路的设计均有原理图设计和HDL语言文本设计两种方法,根据电路的特点和各人的情况,自己选用。
对每个子模快进行软件仿真,先创建波形文件,设定时间间隔和解释时间,编辑输入波形,运行仿真,分析结果是否正确。若不正确,则修改设计,重新编译后,再仿真,直到正确为止。
(1)6位十进制的计数器子模块设计:
没有现成电路可用,所以必须自己设计。
为什么不选用二进制计数器?(从显示要求、二进制转换为BCD电路的难易等考虑)
设计方法一:选用6个1位的可逆带清零十进制计数器级联得到。注意进位/借位信号的时序。
设计方法二:使用HDL语言编程,注意同时满足十进制、加、减的进位和借位。
(2)6位BCD选1的多路数据选择器设计:
没有现成电路可用,所以必须自己设计。
可选用多个数据选择器来组合。要求控制选通信号需要3根,按000-001-010-011-100-101变化,只有6个状态。
(3)BCD-七段译码器设计:
有现成电路选用,注意共阴和共阳数码管的区别。
位选信号产生
①位选译码:每次选中一个,可选用什么译码器?注意位选电平是高电平有效还是低电平有效。
②位选控制:要求为6个状态,设计电路可采用状态机的方法,但仔细分析6个状态之间的关系后,可得出符合_________的计数器。
设计方法:语言和图形均可。
分频电路:位选信号来自电路板的时钟(1MHz)分频,要保证多位显示均匀和不闪烁,先计算分频电路要求的输出频率,在设计分频电路。可使用计数器分频。
5.3分配引脚和编译、下载
引脚分配要满足CPLD电路板上已有的连线情况,把主要的输入信号和重要的中间结果同时分配给逻辑分析仪的输入通道A0~A23,可以利用逻辑分析仪进行测试,观察到电路实际的内部工作时序。每次分配引脚后,需重新编译后,再下载。
六、调试和测试结果
6.1实验硬件连接
根据各人设计的计数器电路和分配的引脚连线,计数器输入控制信号连接开关和按键,计数脉冲信号连接到函数发生器的TTL(CMOS)输出端。计数器的输出位选分别连接6个数码管的为选端L1~L6注意,左边的数码管为低位,7段信号分别连接。
6.2调试和测试
按照以下顺序对计数器电路进行测试,如不正确,请按下面步骤检查:连线——引脚分配——CPLD电路设计。改正错误,再测试,若是CPLD电路错误,需重新编译和重新下载。
①检查动态扫描电路
数码管7段信号全部直接接地,位选分别连接CPLD输出位信号,这时,6个数码管应该稳定显示“888888”。
②检查加法计数器是否正确
连接数码管7段信号到CPLD指定输出引脚,位选分别连接CPLD输出位信号,选计数器输入连接函数发生器的TTL电平信号输出端,设置函数发生器为方波,频率为1~2Hz,加/减控制信号输入“加”有效,观察数码管的显示,应是加1计数,更新频率即为输入信号频率。提高输入信号频率,使计数更新快,检查计数器进位和高位计数是否正确。
③检查减法计数器是否正确
加/减控制信号输入“减”有效,测试方法同上。
④检查“清零”控制是否正确。
⑶ 请问如何将C或汇编源程序或烧到自己制作的PCB板上 谢谢···
一. 安装单片机程序编译软件KEIL。
1.点击图标 运行直至安装完成。
2.点击图标 运行KEIL,然后选择菜单“project”点击“new……”点击“ ”建立新的工程。填写好工程文件名选择保存路径后按“保存”,此时弹出一个窗口如下图所示
点击Atmel左边的+号展开CPU的型号,选择“AT89C51”按“确定”再生成一个对话框如下图,再按“是”即可。
这时在工程左边的文件指示栏中多了一个 这样的图标,点其左边的+号可展开当前所包含的文件。
选择菜单“File”“new”新建一个文本编辑器,按保存按钮,在弹出的窗口填入文件名后缀为.C ,然后按保存即把这个C文本文件保存到这个工程的目录下。
再在工程左边的文件指示栏中指着 点击右键选择 选项把刚才建立的C文件加入来,按“Add”即可加入,这时就可以在C文本编辑器里编号程序了。
写好程序后选择菜单“project”选择“ ”打开的对话框如下图所示
如果弹出来的不是这个对话框时可以重复一次“project”选择“ ”便可以打开,打开后在 这个方框里打上勾然后按“确定”才可以编译生成单片机的烧写文件HEX文件。这些选项都设置好并写好源程序后就可以在菜单选项project选项中选择 选项对源程序进行编译,生成的HEX文件就在工程的目录下。
本文章后面附带的是HJSMSY-V1.0开发板的测试源程序,读者可以将其复制到编译器里编译。此程序为一个简单的计算器功能程序,数写键依次对应电路板上的数字0--9,“A”键功能为清除,“B”键功能为等于,“C”键功能为+,“D”键功能为-,“E”键功能为*,“F”键功能为除。
二. 把单片机开发板用9针串口线与电脑连接好,用配套的USB供电线将单片机开发板供电,并关闭电路板上的电源开关。运行STC芯片烧写软件,
点击图标
打开下载界面如下图
按这个图里面的设置设好参数后,点击“Open File/打开文件”打开HEX文件,在打开的对话框中找到刚才所建立工程的目录,在此目录下可以找到刚才编译得到的HEX文件,如果找不到则是还没有在 这个方框里打上勾,回到工程里打上勾并按 编译一次就行了。打开HEX文件确定后就点击下载软件的 ,再打开单片机开发板上的电源开关,这时电脑便自动与单片机连接并把程序下载到单片机里,下载完成后会有声音提示的,或者可以在软件界面上看得到。注:STC系列单片机是在开机的瞬间下载程序的,如果还未能连接成功可以关掉电源再开一次即可。
//HJSMSY-V1.0单片机开发板测试程序.C
//-----------------------------------------------
// <<计算器>>
//-----------------------------------------------
//编写人:李春起
//编定日期:2010.06.26
//修改日期:
//============================================================
#include <AT89X52.H>
#define uchar unsigned char
#define uint unsigned int
uint comdata,vardata,dispdata;
unsigned char flag=0,incflag=0,maxflag=10,maxvar=1;
//===========共阳数码管段码表==================================
uchar code SEG7[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
uchar code ACT[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};
//================引脚定义=======================================
sbit yy=P3^2;
sbit jk=P3^4;
sbit k1=P2^3;
sbit k2=P2^2;
sbit k3=P2^1;
sbit k4=P2^0;
//=====子函数声明======================================
void init(void);
void delay1(uint z);
void kk(void);
//===========程序初始化===============================
void init(void)
{
TMOD=0x01;
TH0=0xf4;
TL0=0x48;
ET0=1;
TR0=1;
EA=1;
}
//=====空操作延时子程序=======================
void delay1(uint z)
{
uint j,y;
yy=0;
for(j=0;j<z;j++)
{for(y=0;y<100;y++){;}}
yy=1;
for(j=0;j<z;j++)
{
for (y=0;y<3422;y++);
}
}
//========键盘扫描子程序===================
void kk(void)
{ P2=0xf0;
if(P2!=0xf0)
{
P2=0xef;
if(!k1){delay1(15);comdata=vardata;vardata=0;incflag=1;} //k13
if(!k2){delay1(15);comdata=vardata;vardata=0;incflag=2;} //k14
if(!k3){delay1(15);comdata=vardata;vardata=0;incflag=3;} //k15
if(!k4){delay1(15);comdata=vardata;vardata=0;incflag=4;} //k16
P2=0xdf;
if(!k1){delay1(15);if(vardata>6553){goto ab1;};vardata=((vardata*10)/maxflag+8*maxvar);dispdata=vardata;} //k9
ab1:if(!k2){delay1(15);if(vardata>6553){goto ab2;};vardata=((vardata*10)/maxflag+9*maxvar);dispdata=vardata;} //k10
ab2:if(!k3){delay1(15);vardata=0;dispdata=vardata;} // k11
if(!k4){delay1(15);switch (incflag){
case 1:{vardata=(comdata+vardata);dispdata=vardata;}break;
case 2:{vardata=(comdata-vardata);dispdata=vardata;}break;
case 3:{vardata=(comdata*vardata);dispdata=vardata;}break;
case 4:{vardata=(comdata/vardata);dispdata=vardata;}break;
default:break;
}
}//k12
P2=0xbf;
if(!k1){delay1(15);if(vardata>6553){goto ab3;};vardata=((vardata*10)/maxflag+4*maxvar);dispdata=vardata;} //k5
ab3:if(!k2){delay1(15);if(vardata>6553){goto ab4;};vardata=((vardata*10)/maxflag+5*maxvar);dispdata=vardata;} //k6
ab4:if(!k3){delay1(15);if(vardata>6553){goto ab5;};vardata=((vardata*10)/maxflag+6*maxvar);dispdata=vardata;} //k7
ab5:if(!k4){delay1(15);if(vardata>6553){goto ab6;};vardata=((vardata*10)/maxflag+7*maxvar);dispdata=vardata;} //k8
ab6:P2=0x7f;
if(!k1){delay1(15);if(vardata>6553){goto ab7;};vardata=((vardata*10)/maxflag+0*maxvar);dispdata=vardata;} //k1
ab7:if(!k2){delay1(15);if(vardata>6553){goto ab8;};vardata=((vardata*10)/maxflag+1*maxvar);dispdata=vardata;} //k2
ab8:if(!k3){delay1(15);if(vardata>6553){goto ab9;};vardata=((vardata*10)/maxflag+2*maxvar);dispdata=vardata;} //k3
ab9:if(!k4){delay1(15);if(vardata>6553){goto ab10;};vardata=((vardata*10)/maxflag+3*maxvar);dispdata=vardata;} //k4
ab10:;
}
}
//======定时器0中断服务子程序================
void time0(void) interrupt 1
{
TH0=0xf4;
TL0=0x48;
P0=0xff;P1=0xff;
// 时钟显示子程序
switch(flag)
{
case 0:{P0=SEG7[dispdata%10];P1=ACT[0];flag=1;}break;
case 1:{P0=SEG7[(dispdata/10)%10];P1=ACT[1];flag=2;}break;
case 2:{P0=SEG7[(dispdata/100)%10];P1=ACT[2];flag=3;}break;
case 3:{P0=SEG7[(dispdata/1000)%10];P1=ACT[3];flag=4;}break;
case 4:{P0=SEG7[dispdata/10000];P1=ACT[4];flag=5;}break;
case 5:{P0=SEG7[0];P1=ACT[5];flag=0;}
default:break;
}
}
//=========主函数======================================
void main()
{
init();
yy=1;
jk=0;
while(1)
{
if((vardata/1000)>=9){maxflag=10;maxvar=0;}
else {maxflag=1;maxvar=1;}
kk();
}
}