FPGACPLD原理及应用课程万年历设计报告.docx
《FPGACPLD原理及应用课程万年历设计报告.docx》由会员分享,可在线阅读,更多相关《FPGACPLD原理及应用课程万年历设计报告.docx(13页珍藏版)》请在冰豆网上搜索。
FPGACPLD原理及应用课程万年历设计报告
FPGA-CPLD原理及应用课程设计报告
题目:
万年历设计
学院:
信息与电子工程学院
专业:
电子信息工程
学号:
XXXXXXXX
姓名:
XXXXXX
指导老师:
XXXXXX
时间:
2015.12.20-2015.12.23
一、摘要
设计从系统硬件出发,由CPU、总线、RAM、外接设备等构成SOPCBuilder的硬件系统,通过NiosIIDE2开发的嵌入式软件编写并嵌入SOPCBuilder的硬件中实现万年历的整体开发。
通过应用SoPCBuilder开发工具,设计者可以摆脱传统的、易于出错的软硬件设计细节,从而达到加快项目开发、缩短开发周期、节约开发成本的目的并具有高集成度、设计灵活和可移植性较好。
关键词:
万年历SOPCSOPCBuilderNiosIIDE2
二、设计要求
用NiosIIDE2开发板的LCD显示电子钟的日期和时间。
LCD分两行显示,第1行显示年、月、日;第2行显示时、分、秒。
用输入BUTTON[0]来控制LCD行的修改,同时让NiosIIDE2开发板上的绿色发光二极管亮灭来表示这个选择。
当BUTTON[0]按一下后,LEDG3亮,可以修改年、月和日的数字;再按一下BUTTON[0]后,LEDG3灭,可以修改时、分和秒的数字。
另外用输入按钮BUTTON[3]来控制日期和时间的修改,当处于日期修改方式时,每次按动一次BUTTON[3],依次更换“年”、“月”和“日”的修改。
当处于时间修改方式时,每次按动一次BUTTON[3],依次更换“时”、“分”和“秒”的修改。
修改对象被选中后,按动BUTTON[2]输入按钮可以增加显示的数字;按动BUTTON[1]输入按钮可以减少显示的数字。
三、设计内容
1、按键信息
BUTTON[3]:
“年”、“月”、“日”或“时”、“分”、“秒”切换键
BUTTON[2]:
+键
BUTTON[1]:
-键
BUTTON[0]:
“年”、“月”、“日”与“时”、“分”、“秒”切换键
显示信息
LCD_Line1:
显示“年”、“月”、“日”
LCD_Line1:
显示“时”、“分”、“秒”
2、SOPCBuilder硬件建立
SOPCBuilder是在QuartusII里的SOPCBuilder进行的,先建立工程,在SOPCBuilder里添加硬件,包括CPU,jtag_uart,RAM,LCD,PIO,按键,LED,以及LCD_ON。
3、QuartusII硬件处理
硬件会自动建立一个顶层模块,通过建一个原理图来对对应的硬件进行输入输出的添加,再锁定引脚,编译工程,硬件下载。
4、NiosIIDE2嵌入软件编写
在NiosII里建立工程,选择相应的模块,编写需要嵌入的软件,添加缺少的头文件对应的宏定义,编译工程,进行软件下载,在观察结果。
四、设计步骤
1、打开QuartusII新建工程
2、打开SOPCBuilder生成相应的硬件如图所示
图1.SoPC配置
建立好后点击Generate运行,看是否出错,然后点击exit退出。
3、在QuartusII中建立图形文件,调用刚才生成的硬件系统,然后进行引脚配置。
引脚配置图如下:
图2.引脚配置
然后进行编译,生成文件如下图:
图3.顶层电路
4、NiosII运行
打开NiosIIIDE2,建立工程,选择count_binary模块,添加一个LCD.h的顶层文件。
LCD.h的顶层文件为:
#ifndef_LCD_H_
#define_LCD_H_
//LCDModule16*2
#definelcd_write_cmd(base,data)IOWR(base,0,data)
#definelcd_read_cmd(base)IORD(base,1)
#definelcd_write_data(base,data)IOWR(base,2,data)
#definelcd_read_data(base)IORD(base,3)
//==========================
voidLCD_Init();
voidLCD_Show_Text(char*Text);
voidLCD_Line2();
voidLCD_Test();
//=========================
#endif//_LCD_H_
C语言程序代码为:
#include
#include"altera_avalon_pio_regs.h"
#include"alt_types.h"
#include"system.h"
#ifndef_LCD_H_
#define_LCD_H_
//LCDModule16*2
#definelcd_write_cmd(base,data)IOWR(base,0,data)
#definelcd_read_cmd(base)IORD(base,1)
#definelcd_write_data(base,data)IOWR(base,2,data)
#definelcd_read_data(base)IORD(base,3)
//==========================
voidLCD_Init();
voidLCD_Show_Text(char*Text);
voidLCD_Line2();
voidLCD_Test();
//=========================
#endif//_LCD_H_
intyear=2015;
intmonth=12;
intday=23;
inthour=11;
intminute=10;
intsecond=21;
intselectkey=1;
intselectkeylr=1;
intms=0;
intKEY=0;
intshift=0,con=0,step=0;
//#include"basic_io.h"
volatileintedge_capture;
voidLCD_Init()
{
lcd_write_cmd(LCD_BASE,0x38);
usleep(2000);
lcd_write_cmd(LCD_BASE,0x0C);
usleep(2000);
lcd_write_cmd(LCD_BASE,0x01);
usleep(2000);
lcd_write_cmd(LCD_BASE,0x06);
usleep(2000);
lcd_write_cmd(LCD_BASE,0x80);
usleep(2000);
}
voidLCD_Show_Text(char*Text)
{
inti;
for(i=0;i{
lcd_write_data(LCD_BASE,Text[i]);
usleep(2000);
}
}
voidLCD_Line1()
{
lcd_write_cmd(LCD_BASE,0x80);
usleep(2000);
}
voidLCD_Line2()
{
lcd_write_cmd(LCD_BASE,0xC0);
usleep(2000);
}
//==========判断按键=================
intpush_button(void){
if(IORD(KEY_PIO_BASE,0)==14){while
(1){if(IORD(KEY_PIO_BASE,0)==15)break;}return1;}
if(IORD(KEY_PIO_BASE,0)==13){while
(1){if(IORD(KEY_PIO_BASE,0)==15)break;}return2;}
if(IORD(KEY_PIO_BASE,0)==11){while
(1){if(IORD(KEY_PIO_BASE,0)==15)break;}return3;}
if(IORD(KEY_PIO_BASE,0)==7){while
(1){if(IORD(KEY_PIO_BASE,0)==15)break;}return4;}
elsereturn0;
}
//==========判断按键=================
//==========修改时间=================
voidmodify(void)
{
if(shift==2){//修改时间
if(con==0){hour+=step;if(hour>=24||hour<0)hour=0;}
elseif(con==1){minute+=step;if(minute>=60||minute<0)minute=0;}
elseif(con==2){second+=step;if(second>=60||second<0)second=0;}
}
if(shift==1){//修改date
if(con==0){year+=step;if(year<0)year=0;}
elseif(con==1){month+=step;if(month>12||month<0)month=0;}
elseif(con==2){day+=step;if(day>31||day<0)day=0;}
}
step=0;
}
//==========修改时间=================
intmain()
{
while
(1){
if(ms%10==0){
if(ms/10==1){//显示
if(shift==1){//date
if(con==0)//year
printf("-%2d-%d\n",month,day);
if(con==1)//month
printf("%d--%d\n",year,day);
if(con==2)//day
printf("%d-%2d-\n",year,month);
printf("%d:
%d:
%2d\n",hour,minute,second);//time
}
if(shift==2){
printf("%d-%2d-%d\n",year,month,day);
if(con==0)//hour
printf(":
%d:
%2d\n",minute,second);
if(con==1)//minute
printf("%d:
:
%2d\n",hour,second);
if(con==2)//second
printf("%d:
%d:
\n",hour,minute);
}
}
else{
printf("%d-%2d-%d\n",year,month,day);
printf("%d:
%d:
%2d\n",hour,minute,second);
}
}
usleep(50000);
ms++;
if(ms==20){
ms=0;
second++;
}
if(second==60){
minute++;
second=0;
if(minute==60){
minute=0;
hour++;
if(hour==24){
hour=0;
day++;
if(day==31){
day=1;
month++;
if(month==12){
month=1;
year++;
}
}
}
}
}
//=============检测按键
KEY=push_button();
switch(KEY){
case1:
shift++;if(shift>=3)shift=0;break;
case2:
step=1;break;
case3:
step=-1;break;
case4:
con++;if(con>=3)con=0;break;
default:
break;
}
modify();
//=============检测按键
}
return0;
}
5、连接开发板,将文件下载到开发板,运行文件检验是否正确。
6、检查错误并修改,知道结果正确。
五、运行情况与问题分析
1、建立工程时,注意不能出现中文或者空格,且工程名需与文件名一致,选定芯片;
2、在生成CPU硬件系统时,定义端口时,需注意设定端口输入与输出的位宽,需与程序定义的数值一致,否则运行溢出报错,须修改;
3、建立图形文件后,需进行编译,出现错误得返回原理图核对,找到错误修改后重新编译;
4、进行引脚锁定时,注意引脚文件的编写,否则选择引脚文件点击Run后会不成功,从而影响后面程序的调试;
5、当日数为31时,调节月份日期不会随机改变,就会出现4月31日等错误,加入程序段但是还是没有完成跳变;
6、程序中闪烁程序段、跳变程序段不执行,程序还需后续修改;
7、实物图
图4.实物图
六、结论
采用NIOSⅡ集成开发环境提供的快捷开发手段,在Cyclone1C6Q240C8芯片上创建了一个用户定制CPU和外设的片上系统,同时完成对液晶显示器和LED的编程控制。
整个系统充分体现了SOPC设计方法的灵活性,设计时只定制系统需要的外设器件接口,避免过多的外围电路和器件造成体积、功耗的增多和可靠性的下降。
由于采用软核结构,方便系统的升级和扩展,而不必硬件改版,节约了成本,加快开发进度,缩短了产品的开发周期。
七、心得体会
经过本次SoPC课程设计实验,使我对QuartusⅡ与NiosⅡDE2以及开发板的使用更加熟练,并且初步掌握了FPGA从理论设计到硬件开发的流程,详细了解了万年历的软件设计跟硬件设计的整个过程。
在课程设计的过程中,遇到了一些以前没有出现过的问题,例如:
课程设计指导书上的电路图中多了一个引脚LCD_ON,这个引脚是不需要的,但是没有检查出来错误,导致开发板无法显示时间,后来在老师的指导下,才知道了问题所在。
万年历的程序的编写也花费了很多时间,诸如此类的问题还有很多,后来在自己的努力和同学的帮助下完成了本次课程设计,从而使得自己的理论知识与实践能力得到了提升,这次经历是大学中的一次宝贵的财富,自己明白了很多道理,不管做什么事情都要认真,细心,一定要有耐心,不要轻易否定自己,并且要找对方法,不能盲目的去做,要有目的性、针对性的去做,我相信这次经历对以后的学习与帮助都有很大的帮助,另外,如果没有指导老师的细心指导,课设也不会如此成功,在此我要郑重感谢指导老师,老师,您辛苦了。
指导教师评语
课程设计成绩:
指导教师签字: