SOPC综合实验报告资料.docx
- 文档编号:4717950
- 上传时间:2022-12-07
- 格式:DOCX
- 页数:23
- 大小:433.15KB
SOPC综合实验报告资料.docx
《SOPC综合实验报告资料.docx》由会员分享,可在线阅读,更多相关《SOPC综合实验报告资料.docx(23页珍藏版)》请在冰豆网上搜索。
SOPC综合实验报告资料
基于SOPC的数字钟设计
学院:
计控学院
班级:
计本121
学号:
2012021001
姓名:
钟济强
指导老师:
张浩鹏
一、
设计概述
用NiosIIDE2开发板的LCD显示电子钟的日期和时间,LCD分两行显示,第一行显示年月日,第二行显示时分秒。
用输入按钮BUTTON来控制LCD行修改,通过NiosIIIDE进行软件设计。
二、设计要求
1.掌握NiosII系统的设计和使用方法;
2.学习通过NiosIIIDE进行软件设计的方法;
3.实现在液晶屏上显示时间和日期,并可以对其进行设置。
三、实验环境
DE2开发板
QuartusII7.2
SOPCBuilder7.2
NiosIIIDE7.2
四、设计方案(总体设计、软件设计、硬件设计)
1.总体设计要实现以下两个功能:
(1).在液晶屏上显示时间,日期
(2).对时间、日期能够进行设置
建立新工程clock
2.硬件系统组成设计
根据系统要实现的功能和开发板配置,需要用到的DE2开发板上的外围器件有:
LCD:
电子钟显示屏幕
按钮:
电子钟设置功能键
CFIFlash存储器:
存储软、硬件程序
SDRAM存储器:
程序运行时将其导入SDRAM
根据所用到的外设和器件特性,在SOPCBuilder中建立系统要添加的模块包括:
NiosIICPU定时器,按键PIO,LCD,外部存储器总线(Avalon三态桥),外部SDRAM控制器,外部Flash接口。
打开SOPCBuider,系统名称为sopc_clock
加入SDRAM组件
加入FlashMemory组件
加入外部存储器总线(Avalon三态桥)
加入按键PIO
加入LCD
加入NiosIICPU定时器,选择标准型的
元件添加完后,要为每个外设分配及地址和中断请求优先级(IRQ),在System中选择Auto-AssignBaseAddress和Auto-AssignIRQs命令,这两个命令可分别简单分配外设基地址和中断优先级。
然后生成NiosII系统。
然后生成顶层文件,将NiosII系统模块加入到顶层文件中,如图所示原理图
进行引脚锁定,并编译,然后进行硬件下载
3.软件系统设计
要实现系统所需的功能,大量的工作应该集中在软件设计和优化上。
电子钟的软件功能主要分为显示、设置和时间算法三大部分。
显示部分的功能包括:
显示时间(小时:
分钟:
秒)和显示日期(年-月-日)
设置部分的功能包括:
设置小时,设置分钟,设置年份,设置月份,设置日期和退出设置。
设置部分的程序主要用在对按键的响应。
在编写程序前要对DE2开发板上的四个按键BUTTON功能进行如下分配:
(1).主菜单
BUTTON0:
设置选择键,可依次选择设置时、分、秒和年、月、日
BUTTON1:
显示日期键
BUTTON2:
显示时间键
(2).子菜单(即进入对某个选项设置后的按键功能):
BUTTON1:
选项数字增加
BUTTON2:
选项数字减少
BUTTON3:
退出对选项的设置,返回主菜单
时间算法部分的功能包括:
时间累加和确定每个月的最大天数,使年、月、日能正确累加
五、软件代码
1.count_binary.c的代码:
#include"count_binary.h"
//程序每秒钟检测一次按钮的状态,对日期和时间进行设置
#include"alt_types.h"
#include
#include
#include
#include"system.h"
#include"sys/alt_irq.h"
#include"altera_avalon_pio_regs.h"
#include"lcd.h"
volatileintedge_capture;
voidLCD_Init()
{
//LCD初始化
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)
{
//LCD输出格式
inti;
for(i=0;i { lcd_write_data(LCD_BASE,Text[i]); usleep(2000); } } voidLCD_Line1() { //向LCD写命令 lcd_write_cmd(LCD_BASE,0x80); usleep(2000); } voidLCD_Line2() { //向LCD写命令 lcd_write_cmd(LCD_BASE,0xC0); usleep(2000); } staticvoidhandle_button_interrupts(void*context,alt_u32id) { volatileint*edge_capture_ptr=(volatileint*)context; /*存储按钮的值到边沿捕获寄存器*/ *edge_capture_ptr=IORD_ALTERA_AVALON_PIO_EDGE_CAP(BUTTON_PIO_BASE); /*复位边沿捕获寄存器*/ IOWR_ALTERA_AVALON_PIO_EDGE_CAP(BUTTON_PIO_BASE,0); } /*初始化button_pio*/ staticvoidinit_button_pio() { void*edge_capture_ptr=(void*)&edge_capture; /*开放全部4个按钮的中断*/ IOWR_ALTERA_AVALON_PIO_IRQ_MASK(BUTTON_PIO_BASE,0xf); /*复位边沿捕获寄存器*/ IOWR_ALTERA_AVALON_PIO_EDGE_CAP(BUTTON_PIO_BASE,0x0); /*登记中断源*/ alt_irq_register(BUTTON_PIO_IRQ,edge_capture_ptr,handle_button_interrupts); } voiddelay(unsignedintx) { while(x--); } intcheck_month(intmonth) { //如果是1、3、5、7、8、10、12月,则每月31天,程序返回1 if((month==1)||(month==3)||(month==5)||(month==7)||(month==8)||(month==10)||(month==12)) return1; //如果是4、6、9、11月,则每月是30天,程序返回0 if((month==4)||(month==6)||(month==9)||(month==11)) return0; //如果是2月,程序返回2,具体多少天还要根据年的判断来决定 if(month==2) return2; } /* 闰年的计算方法: 公元纪年的年数可以被四整数,即为闰年 被100整除而不能被400整除为平年;被100整除也可被400整除的为闰年 如2000年时闰年,而1900年不是 */ intcheck_year(intyear) { if(((year%400)==0)||(((year%4)==0)&&((year%100)! =0))) return1; //是闰年,返回1 elsereturn0; //不是闰年,返回0 } intmain(void) { intscreen=0;//共有两行,一行显示年月日,一行显示时间 intpos=0;//每行都有三个位置,第一行是年月日,第二行是时分秒 intyear,month,day,hour,minute,second; unsignedlongsum;//sum要设置为长整型变量,不然会溢出 chardate[16]; chartime[16]; intyear1=6; intyear2=0; intyear3=0; intyear4=2; intmonth1=1; intmonth2=0; intday1=1; intday2=0; inthour4,hour3,hour2,hour1,minute2,minute1,second2,second1; unsignedintscreenflag; hour=0;minute=0;second=0;year=2006;month=1;day=1; //年月日时分秒初始化 init_button_pio(); LCD_Init(); while (1) { if(pos>=3) pos=0;//共有三个位置0、1、2,超过了2要马上清0 if(screen>=2) screen=0;//共有两行0、1,超过了1要马上清0 //na_LED8->np_piodata=1< if(screen==0) screenflag=8; elsescreenflag=0; //IOWR_ALTERA_AVALON_PIO_DATA(LED_GREEN_BASE,(1< usleep(1000000);//等待1秒的定时时间 if(second<59)second++; else { second=0; if(minute<59)minute++; else { minute=0; if(hour<23)hour++; else { hour=0; if(day<30)day++; else { day=1; if(month<12)month++; else { month=1; if(year<9999)year++; elseyear=2005; } } } } } switch(edge_capture)//检测按钮 { case0x08: pos=pos+1;break;//改变调整位置 /* 对数据进行加减操作的CASE: case0x02和case0x04 根据当前调整位置,判断当前屏显示的是年、月、日还是时分、秒 然后决定是对年月日进行加减还是对分时秒进行加减 */ case0x02: //对当前位置上的数据执行减操作 if(pos==0) { if(screen==0) { if(day>1)day--; else { if(check_month(month)==0)day=30; if(check_month(month)==1)day=31; if(check_month(month)==2) { if(check_year(year))day=29; elseday=28; } } } if(screen==1) { if(second>0)second--; elsesecond=59; } } if(pos==1) { if(screen==0) { if(month>1)month--; elsemonth=12; } if(screen==1) { if(minute>0)minute--; elseminute=59; } } if(pos==2) { if(screen==0) { if(year>0)year--; elseyear=2005; } if(screen==1) { if(hour>0)hour--; elsehour=23; } } break; case0x04: //对当前位置上的数据执行加操作 if(pos==0) { if(screen==0) { if(check_month(month)==0){if(day<30)day++;elseday=1;} if(check_month(month)==1){if(day<31)day++;elseday=1;} if(check_month(month)==2) { if(check_year(year)){if(day<29)day++;elseday=1;} else{if(day<28)day++;elseday=1;} } } if(screen==1) { if(second<59)second++; elsesecond=0; } } if(pos==1) { if(screen==0) { if(month<12)month++; elsemonth=1; } if(screen==1) { if(minute<59)minute++; elseminute=0; } } if(pos==2) { if(screen==0) { if(year<9999)year++; elseyear=2005; } if(screen==1) { if(hour<23)hour++; elsehour=0; } } break; case0x01: screen++;break;//换屏 } edge_capture=0; { year4=year/1000;year3=(year-year4*1000)/100; year2=(year-year4*1000-year3*100)/10;year1=year%10; month2=month/10;month1=month%10; day2=day/10;day1=day%10; LCD_Line1(); date[0]=year4+0x30;date[1]=year3+0x30; date[2]=year2+0x30;date[3]=year1+0x30; date[4]='';date[5]=''; date[6]=month2+0x30;date[7]=month1+0x30; date[8]='';date[9]=''; date[10]=day2+0x30;date[11]=day1+0x30; date[12]='';date[13]=''; date[14]='';date[15]=''; LCD_Show_Text(date); } { hour4=0;hour3=0; hour2=hour/10;hour1=hour%10; minute2=minute/10;minute1=minute%10; second2=second/10;second1=second%10; time[0]='';time[1]=''; time[2]=hour2+0x30;time[3]=hour1+0x30; time[4]='';time[5]=''; time[6]=minute2+0x30;time[7]=minute1+0x30; time[8]='';time[9]=''; time[10]=second2+0x30;time[11]=second1+0x30; time[12]='';time[13]=''; time[14]='';time[15]=''; LCD_Line2(); LCD_Show_Text(time); } } } 2.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 六、实验分析和实验结果 用输入按钮BUTTON[0]可以控制LCD行修改,同时让NiosIIDE2开发板上的绿色发光二极管LEDG3的亮灭来表示。 用输入按钮BUTTON[3]可以控制日期和时间的修改,BUTTON[1]和BUTTON[2]输入按钮可以减少和增加显示的数字。 实验中开始时SDRAM的BIDIR端口的命名错误导致引脚锁定未成功,此端口的名称应为DRAM_DQ[15..0]。 此外,三态桥的设置被改变了,需要重新设置,回到QuartusII中,在assignments中选择settings,Device->DeviceandPinOptions->UnusedPins,改为Asinputtri-stated。 七、总结 通过这12周的SOPC技术综合设计实践的学习,我学会了QuartusII, SOPCBuider和NiosIIDE2的使用,并通过这些软件可以进行简单的实验操作,强化了我的动手能力,并通过这几次实验更加了解SOPC的设计与应用。 在实验中,遇到了各种各样的问题,首先是自己进行检查,查不出来再由老师同学进行检查和讲解,提高了自己解决问题的能力,并且熟悉了整个实验的流程及具体的操作。 我觉得这门课程很有意思,实验中是把各个部分的操作整合在一起,形成一个系统,做实验时要有整体感,一旦出现问题整体的重新进行设置和编译,比如如果添加组建时出现错误,要重新添加,重新生成模块,重新倒入模块,重新编译顶层文件,是一个整体的过程。 八、附录 参考《SOPC技术与应用》,编著: 江国强,机械工业出版社。 参考《SOPC技术综合设计实践实验指南》,编著: 邱德惠。 思考题: 1.何谓SOC? SOC(SystemOnaChip)称为片上系统,它是指将一个完整产品的功能集成在一个芯片上或芯片组上。 SOC中可以包括微处理器CPU、数字信号处理器DSP、存储器(ROM、RAM、Flash等)、总线和总线控制器、外围设备接口等,还可以包括数模混合电路(放大器、比较器、A/D和D/A转换器、锁相环等),甚至传感器、微机电和微光电单元。 2.何谓SOPC? SOPC(SystemOnaProgrammableChip)称为可编程片上系统,它是基于可编程逻辑器件(FPGA或CPLD)可重构的SOC。 SOPC集成了硬核或软核CPU、DSP、锁相环(PLL)、存储器、I/O接口及可编程逻辑,可以灵活高效地解决SOC方案,而且设计周期短,设计成本低,一般只需要一台配有SOPC开发软件的PC和一台SOPC实验开发系统(或开发板),就可以进行SOPC的设计与开发。 3.何谓IP核? IP(IntellectualProperty)是知识产权的简称。 集成电路IP是指经过预先设计、预先验证、符合产业界普遍认同的设计规范和设计标准,并具有相对独立并可以重复利用的电路模块或子系统,如CPU、运算器、存储器、放大器等。 集成电路IP模块具有知识含量高、占用芯片面积小、运行速度快、功耗低、工艺容差性大等特点,可重复用于SOC、SOPC或复杂ASIC设计中。 4.何谓嵌入式系统,嵌入式系统的CPU核可以分为哪两种类型? 嵌入式系统是指嵌入到对象体系中的专用计算机系统,包括硬件和软件两大部分。 硬件包括处理器、存储器、输入输出接口和外部设备等,软件包括系统软件和应用软件。 基于SOPC的嵌入式系统结构主要包括嵌入式微处理器(CPU核)、定时器(Timer)、嵌入式锁相环(PLL)、嵌入式数字信号处理器(DSP)及其他IP模块等部分。 嵌入式系统的CPU核可以分为硬核和软核。 5.简述CPU软核的特点。 软核通常以可综合的HDL提供,因此具有较高的灵活性,并与具体的实现工艺无关,其主要缺点是缺乏对时序、面积和功耗的预见性。 由于软核是以源代码的形式提供,尽管源代码可以采用加密方法,但其知识产权保护问题不容忽视。 6.简述HAL的用途及基于HAL的外围设备的编程方法。 HAL作为支持NiosII处理器系统的软件包,为用户的嵌入式系统上的外围设备提供了与之相匹配的接口程序。 用户不用自己建立或复制HAL文件,也不需要编辑HAL中的任何源代码,使用时只需要在C/C++源程序中指明代表这些接口程序的库函数包含的头文件即可。 在一个基于NiosII的SOPC系统上,外围设备包括通用异步串口UART、发光二极管LED、七段数码管、按钮、LCD、存储器、定时器、鼠标、VGA等。 在应用软件的开发中,对于按钮、发光二极管LED、七段数码管等通用输入输出设备的编程比较简单,而对于通用异步串口UART、LCD、VGA等字符模式外围设备的编程就比较复杂。 为了方便用户对字符模式外围设备的编程,HAL支持标准输入、标准输出和标准错误函数,允许在程序中调用stdio.h中的I/O函数来完成对这些设备的访问,也支持字符模式外围设备的通用访问。 7.简述SOPC的设计流程。 SOPC硬件开发流程 a)创建QuartusII工程 b)创建NiosII系统模块 c)配置NiosII系统 d)将NiosII系统模块、LPM和用户自定义模块连接起来 e)编译、引脚分配、编程下载 SOPC软件开发流程 NiosII程序包括一个应用工程、可选的库工程和一个板支持包工程(自动生成)。 将NiosII程序编译成一个能在NiosII处理器上运行的.elf文件。 1.新建NiosIIC/
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- SOPC 综合 实验 报告 资料