SOPC综合实验报告资料.docx

上传人:b****6 文档编号:4717950 上传时间:2022-12-07 格式:DOCX 页数:23 大小:433.15KB
下载 相关 举报
SOPC综合实验报告资料.docx_第1页
第1页 / 共23页
SOPC综合实验报告资料.docx_第2页
第2页 / 共23页
SOPC综合实验报告资料.docx_第3页
第3页 / 共23页
SOPC综合实验报告资料.docx_第4页
第4页 / 共23页
SOPC综合实验报告资料.docx_第5页
第5页 / 共23页
点击查看更多>>
下载资源
资源描述

SOPC综合实验报告资料.docx

《SOPC综合实验报告资料.docx》由会员分享,可在线阅读,更多相关《SOPC综合实验报告资料.docx(23页珍藏版)》请在冰豆网上搜索。

SOPC综合实验报告资料.docx

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/

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 其它课程

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1