关于数码管日历以及流水灯功能实现设计报告.docx_第1页
关于数码管日历以及流水灯功能实现设计报告.docx_第2页
关于数码管日历以及流水灯功能实现设计报告.docx_第3页
关于数码管日历以及流水灯功能实现设计报告.docx_第4页
关于数码管日历以及流水灯功能实现设计报告.docx_第5页
已阅读5页,还剩11页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

关于数码管日历以及流水灯功能实现设计报告 1.设计内容:利用Quartus II 13.0建立CPU软核,同时用NIOS II 生成相应的驱动程序。本人利用8个七段数码管作为日历显示器,同时以4个按键作为控制器,用6个LED灯显示四个按键状态,另外额外添加了8个LED实现流水灯。2.设计要求:能实现日期显示,并且能够实现日期的修改,用key3控制程序是否运行,用key2控制修改的项目,初始状态默认为修改年份,按下key2状态变为修改月份,再按下key2状态变为修改天数,之后重复。Key1和key0分别为增加和减少。同时添加一个流水灯显示。3.软核建立:利用Quartus II 13.0建立软核,在Qsys中分别添加以下相应器件:a. CPU 使用的是f型的cpub. SDRAM 位宽16,64Mbits,基地址保证为0x00000000c. CLOCK 内部时钟,频率为50MHzd. EPCS 串行存储器,代码被从EPCS控制器的片内搬到RAM中执行e. SYSID 系统基地址分配f. JTAG UART 深度64位,用于内部测试和在线编程g. LIGHTS 加入一个位宽为8的PIO控制8个LED灯用于流水灯显示h. SEG 添加了8个七段数码管用于显示年月日i. KEY 添加了四个key输入管脚,分别为key1、key2、key3、key4,使用上升沿触发。输入管脚经非门之后输入。j. KEY_STATE PIO输出管脚控制LED等,显示按键目前数值状态:LEDLED1LED2LED3LED4LED5LED6亮Key1_state=1Key2_state1=1Key2_state2=2Key2_state3=3Key3_state=1Key4_state=1运行停止修改年份修改月份修改天数增加减少灭Key1_state=0Key2_state1=0Key2_state2=0Key2_state3=0Key3_state=0Key4_state=0正常运行Generate之后,添加一个PLL,两个时钟输出,一个相位偏移为0,另外一个是75o。将相位不变的时钟作为cpu时钟,另外一个作为sdram时钟。Re_set接vcc,pll的输入接外接时钟,输入接非门进入,然后自动生成其他pins。将I/O设置为普通的I/O,然后分配管脚。编译,通过之后软核就生成完毕。 图 1 软核框图示意图4.NIOS II驱动程序编写:本实验设想是利用七段数码管显示日期,日期可以更改,并且能够显示流水灯。首先FileNewNIOS II applications and BSP from template,利用Quartus中生成的sof文件,通过NIOS II的“hello world”模板生成相应的应用和BSP。在myNIOSII中新建main头文件夹用于存放hello world.c文件,新建inc头文件夹存放所要调用的头文件,内包含“system.h”等头文件在sopc.h中定义声明相应的结构体用于存储相关的数据。如:#ifndef SOPC_H_#define SOPC_H_ #include system.h#define _LIGHTStypedef struct unsigned long int DATA; unsigned long int DIRECTION; unsigned long int INTERRUPT_MASK; unsigned long int EDGE_CAPTURE;PIO_STR;#ifdef _LIGHTS#define LIGHTS (PIO_STR *)LIGHTS_BASE)#endif#endif /* SOPC_H_ */对于日期的显示,首先应该考虑年是否是闰年,月份等特殊情况,所以用代码:void ISR_key3(void * context,unsigned long id)/按键增加日期显示/ KEY3_STATE-DATA=1; KEY4_STATE-DATA=0; if(key_flag2=1)/年份增加/ if(yearDATA=displayeryear/1000;/显示年份/ SEG_YEAR2-DATA=displayer(year/100)%10; SEG_YEAR3-DATA=displayer(year/10)%10; SEG_YEAR4-DATA=displayeryear%10; else if(key_flag2=2)/月份增加/ if(monthDATA=displayermonth/10;/显示月份变化/ SEG_MONTH2-DATA=displayermonth%10; else if(key_flag2=3)/日期增加/ if(month=1)|(month=3)|(month=5)|(month=7)|(month=8)|(month=10)|(month=12) if(day31)day+; else if(day=31)day=1; else if(month=4)|(month=6)|(month=9)|(month=11) if(day30)day+; else if(day=30)day=1; else if(month=2) if(!(year%4)&!(year%100)|!(year%400)/判断是否是闰年/ if(day29)day+; else if(day=29)day=1; else if(dayDATA=displayerday/10;/显示日期增加变化/ SEG_DAY2-DATA=displayerday%10; for(k=0;k3)key_flag2=1;if(key_flag2=1)KEY2_STATE1-DATA=1;KEY2_STATE2-DATA=0;KEY2_STATE3-DATA=0;else if(key_flag2=2)KEY2_STATE1-DATA=0;KEY2_STATE2-DATA=1;KEY2_STATE3-DATA=0;else if(key_flag2=3)KEY2_STATE1-DATA=0;KEY2_STATE2-DATA=0; KEY2_STATE3-DATA=1;添加另外一个按键,key3按下,产生中断,进行日期的修改。再次按下程序继续运行。中断注册函数:void ISR_key1(void * context,unsigned long id) key_flag1 = key_flag1; KEY1_STATE-DATA=key_flag1;七段数码管显示操作:由于不会使用PIO操作函数,本人采用了直接赋值的办法。定义了一个数组:const alt_u8 displayer16=0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf;然后将要显示的十进制数据每个位分离出来,用直接赋值的办法显示相应的十进制数据:如对年份显示的操作:year1=year/1000;year2=(year/100)%10);year3=(year/10)%10;year4=year%10;SEG_YEAR1-DATA=displayeryear1;/显示年份/SEG_YEAR2-DATA=displayeryear2;SEG_YEAR3-DATA=displayeryear3;SEG_YEAR4-DATA=displayeryear4;流水灯显示:对于流水灯显示,本人用宽度为8的I/O输出控制8个LED等,通过预设了显示效果:const alt_u32 LIGHTS_TBL = /流水灯显示样式/ 0x00,0xFF,/全暗和全亮 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,/从右到左依次点亮/ 0x01,0x03,0x07,0x0F,0x1F,0x3F,0x7F,0xFF,/从右到左逐个点亮/ 0xFF,0x7F,0x3F,0x1F,0x0F,0x07,0x03,0x01,/从左到右依次逐个熄灭/ 0x81,0x42,0x24,0x18,0x18,0x24,0x42,0x81,/从两侧往中间依次点亮/ 0x81,0xC3,0xE7,0xFF,0xFF,0xE7,0xC3,0x81,/从两侧往中间逐个点亮/ 0x01,0x04,0x10,0x40,0x02,0x08,0x20,0x80/先奇数次序点亮,后偶数次序点亮/然后,利用语句: j=j%52;/流水灯/ LIGHTS-DATA=LIGHTS_TBLj; j+;当程序运行的时候,流水灯就可以依次进行,不断重复。主函数结构:主函数简单表述如下:Main() 相关变量定义; 四个按键的注册函数; While(1) If(key3产生中断)执行日期修改; Else 执行日期正常变化,执行流水灯; Return 0;5.结果:成功实现了相应的功能,显示日期,能够完成日期的修改,然后按key3正常恢复运行。流水灯运行正常。代码#include system.h#define _LIGHTS#define _LCD#define _SEG_YEAR1#define _SEG_YEAR2#define _SEG_YEAR3#define _SEG_YEAR4#define _SEG_MONTH1#define _SEG_MONTH2#define _SEG_DAY1#define _SEG_DAY2#define _KEY1#define _KEY2#define _KEY3#define _KEY4#define _KEY1_STATE#define _KEY2_STATE1#define _KEY2_STATE2#define _KEY2_STATE3#define _KEY3_STATE#define _KEY4_STATEtypedef structunsigned long int DATA;unsigned long int DIRECTION;unsigned long int INTERRUPT_MASK;unsigned long int EDGE_CAPTURE;PIO_STR;#ifdef _LIGHTS#define LIGHTS (PIO_STR *)LIGHTS_BASE)#endif#ifdef _LCD#define LCD (PIO_STR *)LCD_BASE)#endif#ifdef _SEG_YEAR1#define SEG_YEAR1 (PIO_STR *)SEG_YEAR1_BASE)#endif#ifdef _SEG_YEAR2#define SEG_YEAR2 (PIO_STR *)SEG_YEAR2_BASE)#endif#ifdef _SEG_YEAR3#define SEG_YEAR3 (PIO_STR *)SEG_YEAR3_BASE)#endif#ifdef _SEG_YEAR4#define SEG_YEAR4 (PIO_STR *)SEG_YEAR4_BASE)#endif#ifdef _SEG_MONTH1#define SEG_MONTH1 (PIO_STR *)SEG_MONTH1_BASE)#endif#ifdef _SEG_MONTH2#define SEG_MONTH2 (PIO_STR *)SEG_MONTH2_BASE)#endif#ifdef _SEG_DAY1#define SEG_DAY1 (PIO_STR *)SEG_DAY1_BASE)#endif#ifdef _SEG_DAY2#define SEG_DAY2 (PIO_STR *)SEG_DAY2_BASE)#endif#ifdef _KEY1#define KEY1 (PIO_STR *)KEY1_BASE)#endif#ifdef _KEY2#define KEY2 (PIO_STR *)KEY2_BASE)#endif#ifdef _KEY3#define KEY3 (PIO_STR *)KEY3_BASE)#endif#ifdef _KEY4#define KEY4 (PIO_STR *)KEY4_BASE)#endif#ifdef _KEY1_STATE#define KEY1_STATE (PIO_STR *)KEY1_STATE_BASE)#endif#ifdef _KEY2_STATE1#define KEY2_STATE1 (PIO_STR *)KEY2_STATE1_BASE)#endif#ifdef _KEY2_STATE2#define KEY2_STATE2 (PIO_STR *)KEY2_STATE2_BASE)#endif#ifdef _KEY2_STATE3#define KEY2_STATE3 (PIO_STR *)KEY2_STATE3_BASE)#endif#ifdef _KEY3_STATE#define KEY3_STATE (PIO_STR *)KEY3_STATE_BASE)#endif#ifdef _KEY4_STATE#define KEY4_STATE (PIO_STR *)KEY4_STATE_BASE)#endif#endif /* SOPC_H_ */*代码说明*/本代码用于实现跑马灯以及日期显示,通过四个按键进行设置操作/按下key3,可以使显示暂停,再按一次可以重新启动代码。key2则是作为选项按钮,初始默认为年份设置,再按转为月份设置,再按转为日期设置,之后重复/按键key1和key0分别为增加和减少按钮/添加了六个led灯指示按键状态/作者:谢新华 学号:SC13023167 日期:2013-12-20/*/#include ./inc/sopc.h#include #include ./inc/system.h#include ./inc/alt_irq.h#include #include #include alt_types.h#include altera_avalon_pio_regs.hunsigned int nirq_isr_context; / 定义全局变量以储存isr_context指针int key_flag1= 0;int key_flag2= 1;int key_flag3= 0;int key_flag4= 0;int year= 2013;/初始化显示的时间/int month= 1;int day= 1;int k;const alt_u8 displayer16=0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf;const alt_u32 LIGHTS_TBL = /流水灯显示样式/ 0x00,0xFF, 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80, 0x01,0x03,0x07,0x0F,0x1F,0x3F,0x7F,0xFF, 0xFF,0x7F,0x3F,0x1F,0x0F,0x07,0x03,0x01, 0x81,0x42,0x24,0x18,0x18,0x24,0x42,0x81, 0x81,0xC3,0xE7,0xFF,0xFF,0xE7,0xC3,0x81, 0x01,0x04,0x10,0x40,0x02,0x08,0x20,0x80;/*按键操作函数*/void ISR_key1(void * context,unsigned long id) key_flag1 = key_flag1; KEY1_STATE-DATA=key_flag1; /IOWR_ALTERA_AVALON_PIO_EDGE_CAP(KEY1_BASE, 1);void ISR_key2(void * context,unsigned long id) key_flag2+;if(key_flag23)key_flag2=1;if(key_flag2=1)KEY2_STATE1-DATA=1;KEY2_STATE2-DATA=0;KEY2_STATE3-DATA=0;else if(key_flag2=2)KEY2_STATE1-DATA=0;KEY2_STATE2-DATA=1;KEY2_STATE3-DATA=0;else if(key_flag2=3)KEY2_STATE1-DATA=0;KEY2_STATE2-DATA=0; KEY2_STATE3-DATA=1;void ISR_key3(void * context,unsigned long id)/按键增加日期显示/ KEY3_STATE-DATA=1; KEY4_STATE-DATA=0; if(key_flag2=1)/年份增加/ if(yearDATA=displayeryear/1000;/显示年份/ SEG_YEAR2-DATA=displayer(year/100)%10; SEG_YEAR3-DATA=displayer(year/10)%10; SEG_YEAR4-DATA=displayeryear%10; else if(key_flag2=2)/月份增加/ if(monthDATA=displayermonth/10;/显示月份变化/ SEG_MONTH2-DATA=displayermonth%10; else if(key_flag2=3)/日期增加/ if(month=1)|(month=3)|(month=5)|(month=7)|(month=8)|(month=10)|(month=12) if(day31)day+; else if(day=31)day=1; else if(month=4)|(month=6)|(month=9)|(month=11) if(day30)day+; else if(day=30)day=1; else if(month=2) if(!(year%4)&!(year%100)|!(year%400)/判断是否是闰年/ if(day29)day+; else if(day=29)day=1; else if(dayDATA=displayerday/10;/显示日期增加变化/ SEG_DAY2-DATA=displayerday%10; for(k=0;kDATA=0;KEY4_STATE-DATA=1;if(key_flag2=1)/年份增加/ if(year0)year-; else if(year=0)year=9999; SEG_YEAR1-DATA=displayeryear/1000;/显示年份/ SEG_YEAR2-DATA=displayer(year/100)%10; SEG_YEAR3-DATA=displayer(year/10)%10; SEG_YEAR4-DATA=displayeryear%10; else if(key_flag2=2)/月份增加/ if(month1)month-; else if(month=1)month=12; SEG_MONTH1-DATA=displayermonth/10;/显示月份变化/ SEG_MONTH2-DATA=displayermonth%10; else if(key_flag2=3)/日期增加/ if(month=1)|(month=3)|(month=5)|(month=7)|(month=8)|(month=10)|(month=12) if(day1)day-; else if(day=1)day=31; else if(month=4)|(month=6)|(month=9)|(month=11) if(day1)day-; else if(day=1)day=30; else if(month=2) if(!(year%4)&!(year%100)|!(year%400) if(day1)day-; else if(day=1)day=29; else if(day1)day-; else if(day=1)day=28; SEG_DAY1-DATA=displayerday/10;/显示日期减小变化/ SEG_DAY2-DATA=displayerday%10; for(k=0;kINTERRUPT_MASK =1;return alt_irq_register (KEY1_IRQ,NULL,ISR_key1);int init_key2(void)KEY2-INTERRUPT_MASK =1;return alt_irq_register (KEY2_IRQ,NULL,ISR_key2);int init_key3(void)KEY3-INTERRUPT_MASK =1;return alt_irq_register (KEY3_IRQ,NULL,ISR_key3);int init_key4(void)KEY4-INTERRUPT_MASK =1;return alt_irq_register (KEY4_IRQ,NULL,ISR_key4);/*主函数*/int main()/主函数/ int i,j; int y

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论