FPGA-CPLD原理及应用课程设计报告
题目: 万年历
学院: 信息与电子工程学院 专业: 电子科学与技术 学号:
姓名: 指导老师:
时间:2013-7-15~2013-7-20
一、摘要
本文介绍了一种基于片上可编程系统(SOPC)设计万年历的方法。本次设计从系统硬件出发,由CPU,总线,RAM,外接设备等构成SOPC Builder的硬件系统,通过Nios II DE2开发的嵌入式软件编写并嵌入SOPC Builder的硬件中实现万年历的整体开发。通过应用SoPC Builder开发工具,设计者可以摆脱传统的、易于出错的软硬件设计细节,从而达到加快项目开发、缩短开发周期、节约开发成本的目的并具有高集成度、设计灵活和可移植性较好。 关键词:万年历 SOPC SOPC Builder Nios II DE2
二、设计要求
用Nios II DE2 开发板的LCD显示电子钟的日期和时间。LCD分两行显示,第1行显示年、月、日;第2行显示时、分、秒。用输入BUTTON[0]来控制LCD行的修改,同时让Nios II DE2开发板上的绿色发光二极管亮灭来表示这个选择。当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、SOPC Builder 硬件建立
SOPC Builder是在Quartus II里的SOPC Builder进行的,先建立工
程,在SOPC Builder里添加硬件,包括CPU ,jtag_uart ,RAM,LCD,PIO,按键,LED,以及LCD_ON。 3、Quartus II硬件处理
硬件会自动建立一个顶层模块,通过建一个原理图来对对应的硬件进行输入输出的添加,再锁定引脚,编译工程,硬件下载。 4、Nios II DE2嵌入软件编写
在Nios II里建立工程,选择相应的模块,编写需要嵌入的软件,添加
缺少的头文件对应的宏定义,编译工程,进行软件下载,在观察结果。
四、设计步骤
1、打开Quartus II新建工程
1
2、打开SOPC Builder生成相应的硬件如图所示
建立好后点击Generate运行,看是否出错,然后点击exit退出。
3、调用刚才生成的硬件系统,在Quartus II中建立图形文件,然后进行引脚
锁定。
引脚锁定引脚文件如下: #Setup.tcl
#Setup pin setting
set_global_assignment -name RESERVE_ALL_UNUSED_PINS \"AS INPUT TRI-STATED\"
set_global_assignment -name ENABLE_INIT_DONE_OUTPUT OFF set_location_assignment PIN_N2 -to clk set_location_assignment PIN_V18 -to led[3] set_location_assignment PIN_W19 -to led[2] set_location_assignment PIN_AF22 -to led[1] set_location_assignment PIN_AE22 -to led[0] set_location_assignment PIN_W26 -to KEY[3] set_location_assignment PIN_P23 -to KEY[2] set_location_assignment PIN_N23 -to KEY[1] set_location_assignment PIN_G26 -to KEY[0] set_location_assignment PIN_K4 -to LCD_RW set_location_assignment PIN_K3 -to LCD_EN set_location_assignment PIN_K1 -to LCD_RS set_location_assignment PIN_L4 -to LCD_ON
set_location_assignment PIN_J1 -to LCD_DATA[0] set_location_assignment PIN_J2 -to LCD_DATA[1] set_location_assignment PIN_H1 -to LCD_DATA[2] set_location_assignment PIN_H2 -to LCD_DATA[3] set_location_assignment PIN_J4 -to LCD_DATA[4] set_location_assignment PIN_J3 -to LCD_DATA[5] set_location_assignment PIN_H4 -to LCD_DATA[6] set_location_assignment PIN_H3 -to LCD_DATA[7] 然后进行编译,在Quartus I下生成文件如下图:
2
4、Nios II运行
打开Nios II IDE2,建立工程,选择count_binary模块,添加一个LCD.h的顶层文件。
LCD.h的顶层文件为: #ifndef _LCD_H_ #define _LCD_H_ //LCD Module 16*2
#define lcd_write_cmd(base,data) IOWR(base, 0, data) #define lcd_read_cmd(base) IORD(base, 1)
#define lcd_write_data(base,data) IOWR(base, 2, data) #define lcd_read_data(base) IORD(base, 3) //========================== void LCD_Init();
void LCD_Show_Text(char*Text); void LCD_Line2(); void LCD_Test();
//========================= #endif //_LCD_H_
然后建立count_binary的C++文件。 C++文件见附件。
5、连接开发板,将文件下载到开发板,运行文件检验是否正确。 6、检查错误并修改,知道结果正确。
五、运行情况与问题分析
1、建立工程时,注意不能出现中文或者空格,且工程名需与文件名一致,选定芯片;
2、在生成CPU硬件系统时,定义端口时,需注意设定端口输入与输出的位宽,需与程序定义的数值一致,否则运行溢出报错,须修改;
3、建立图形文件后,需进行编译,出现错误得返回原理图核对,找到错误修改后重新编译;
4、进行引脚锁定时,注意引脚文件的编写,否则选择引脚文件点击Run后会不成功,从而影响后面程序的调试;
5、当日数为31时,调节月份日期不会随机改变,就会出现4月31日等错误,加入程序段但是还是没有完成跳变;
3
6、程序中闪烁程序段、跳变程序段不执行,程序还需后续修改。
六、结论
采用NIOSⅡ集成开发环境提供的快捷开发手段,在EP4CE115F29C7N芯片上创建了一个用户定制CPU和外设的片上系统,同时完成对液晶显示器和LED的编程控制。整个系统充分体现了SOPC设计方法的灵活性,设计时只定制系统需要的外设器件接口,避免过多的外围电路和器件造成体积、功耗的增多和可靠性的下降。由于采用软核结构,方便系统的升级和扩展,而不必硬件改版,节约了成本,加快开发进度,缩短了产品的开发周期。综上所述,万年历的设计思想新颖独特,
有很多创新之处。
七、心得体会
经过本次SOPC课程设计实验,使我更加熟悉了Quartus Ⅱ与Nios Ⅱ DE2以及开发板的使用,熟练掌握了从理论设计到硬件开发的流程,了解了万年历通过编程实现的整个过程。从整个实验实现的过程中,碰到一些以前未出现过的问题,在自己的努力以及同学、老师的帮助下,使自己的理论及操作水平有所提高,在此我要郑重感谢指导老师。
4
附 件
C++程序代码如下:
/*
* \"Hello World\" example. *
* This example prints 'Hello from Nios II' to the STDOUT stream. It runs on
* the Nios II 'standard', 'full_featured', 'fast', and 'low_cost' example * designs. It runs with or without the MicroC/OS-II RTOS and requires a STDOUT
* device in your system's hardware.
* The memory footprint of this hosted application is ~69 kbytes by default * using the standard reference design. *
* For a reduced footprint version of this template, and an explanation of how
* to reduce the memory footprint for a given application, see the * \"small_hello_world\" template. * */
#include #include \"altera_avalon_pio_regs.h\" #include \"alt_types.h\" #include \"system.h\" #ifndef _LCD_H_ #define _LCD_H_ //LCD Module 16*2 #define lcd_write_cmd(base,data) IOWR(base, 0, data) #define lcd_read_cmd(base) IORD(base, 1) #define lcd_write_data(base,data) IOWR(base, 2, data) #define lcd_read_data(base) IORD(base, 3) //========================== void LCD_Init(); void LCD_Show_Text(char*Text); void LCD_Line2(); void LCD_Test(); //========================= #endif //_LCD_H_ 5 int year=2013; int month=7; int day=15; int hour=20; int minute=25; int second=30; int selectkey=1; int selectkeylr=1; int ms=0; int KEY=0; int shift=0,con=0,step=0; //#include \"basic_io.h\" volatile int edge_capture; void LCD_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); } void LCD_Show_Text(char*Text) { int i; for(i=0;i void LCD_Line1() { lcd_write_cmd(LCD_BASE,0x80); usleep(2000); } 6 void LCD_Line2() { lcd_write_cmd(LCD_BASE,0xC0); usleep(2000); } //==========判断按键================= int push_button(void){ if(IORD(KEY_PIO_BASE, 0)==14) {while(1){if(IORD(KEY_PIO_BASE, 0)==15)break;}return 1;} if(IORD(KEY_PIO_BASE, 0)==13) {while(1){if(IORD(KEY_PIO_BASE, 0)==15)break;}return 2;} if(IORD(KEY_PIO_BASE, 0)==11) {while(1){if(IORD(KEY_PIO_BASE, 0)==15)break;}return 3;} if(IORD(KEY_PIO_BASE, 0)==7) {while(1){if(IORD(KEY_PIO_BASE, 0)==15)break;}return 4;} else return 0; } //==========判断按键================= //==========修改时间================= void modify(void) { if(shift==2){//修改时间 if(con==0){hour+=step;if(hour>=24||hour<0)hour=0;} else if(con==1){minute+=step;if(minute>=60||minute<0) minute=0;} else if(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;} else if(con==1){ month+=step;if(month>12||month<0)month=0;} else if(con==2) {day +=step;if(day>31||day<0)day=0;} } 7 step=0; } //==========修改时间================= int main() { /* printf(\"%d-%2d-%d\\n\ lcd_write_cmd(LCD_BASE,0x0f); usleep(1000000); lcd_write_cmd(LCD_BASE,0x10); usleep(1000000); lcd_write_cmd(LCD_BASE,0x10); usleep(1000000); lcd_write_cmd(LCD_BASE,0x03); usleep(1000000); lcd_write_data(LCD_BASE,'c'); */ 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 { 8 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){ case 1: shift++;if(shift>=3)shift=0; break; case 2: step=1;break; case 3: step=-1;break; case 4: con++;if(con>=3)con=0; break; default :break; } modify(); //=============检测按键 } return 0; } 9 实验结果: 10 因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- igat.cn 版权所有 赣ICP备2024042791号-1
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务