SOPC课程设计实验报告

更新时间:2024-02-02 07:22:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

SOPC课程设计实验报告

基于SOPC的警示灯设计

2013电子信息工程3班

李婕20134557

罗丹妮20134563

一、 设计目的

1、 熟悉掌握SOPC的基本流程 2、 设计一个警示灯并满足基本要求 3、 通过设计发现问题并解决

二、 设计设备

1、硬件:PC机、SOPC-NIOS II EDA/SOPC系统开发平台 2、软件:QUARTUS II、SOPC Builder、NIOS II IDE

三、 设计内容

? 初始状态为红灯(LED2)熄灭,绿灯(LED1)点亮,数码管显示为0。

? 当按键按下,红灯(LED2)闪烁,绿灯(LED1)熄灭,同时蜂鸣器响起,数码管开始倒计时9S,此状态持续时间为9s。

? 9s后,恢复初始状态。

四、 设计步骤

1、 使用Quartus II建立一个工程文件和顶层文件; 2、 使用SOPC Builder建立一个简单Nios II硬件系统

1) 启动SOPC Builder 2) 指定目标FPGA

3) 添加NiosII内核及其他外设

A、添加NiosII、SRAM、JTAG-UART、Avalon总线的IP

B、添加一个2位的输入型PIO作为按键key C、添加两个1位的输出型PIO作为 led1及led2的输出端口

D、添加一个1位的输出型PIO作为蜂鸣器的输入端口A

E、添加一个3位的输出型PIO作为数码管的位选sel

F、添加一个8位的输出型PIO作为数码管的段选dat

4) 指定基地址和中断优先级

5) 设置NiosII复位和异常地址

6) 编译生成NiosII系统

SOPC Builder行程图如下:

3、在 1 24、在 1件

2 3 4 5

Quartus II中建立一个蜂鸣器 ) 用VHDL语言编写蜂鸣器程序

) 编译成功后Creat symbol,生成Project sing

Quartus II中编译Nios II硬件系统并生成配置文件 ) 在Quartus II加入Nios II系统符号到顶层文) 给各端口加入输入输出引脚,并重命名 ) 设置参数 ) 编译顶层文件 ) 分配管脚

6) 再次编译

5、在Nios II IDE中建立C/C++工程,编写用户程序 6、编译用户程序

7、下载.SOF至FPGA,运行程序,观察结果

五、设计程序

蜂鸣器程序(VHDL):

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY sing1 IS PORT(

CLK:IN STD_LOGIC; p:IN STD_LOGIC;

-- DIGIT:BUFFER STD_LOGIC_VECTOR(6 DOWNTO 0); SPEAKER:OUT STD_LOGIC);

END ENTITY;

ARCHITECTURE SONG OF sing1 IS

SIGNAL DRIVER,ORIGIN:STD_LOGIC_VECTOR(12 DOWNTO 0); SIGNAL COUNTER:INTEGER RANGE 0 TO 140; SIGNAL COUNTER1:INTEGER RANGE 0 TO 3;

SIGNAL COUNTER2:INTEGER RANGE 1 TO 10000000; SIGNAL DIGIT :STD_LOGIC_VECTOR(6 DOWNTO 0); SIGNAL COUNT :STD_LOGIC_VECTOR(1 DOWNTO 0); SIGNAL CARRIER,CLK_4MHZ,CLK_4HZ:STD_LOGIC; BEGIN PROCESS(CLK) BEGIN

IF CLK'EVENT AND CLK='1' THEN

IF COUNTER1=1 THEN CLK_4MHZ<='1'; COUNTER1<=2;

ELSIF COUNTER1=3 THEN CLK_4MHZ<='0'; COUNTER1<=0;

ELSE COUNTER1<=COUNTER1+1; END IF;

IF COUNTER2=5000000 THEN CLK_4HZ<='1';

COUNTER2<=5000001;

ELSIF COUNTER2=10000000 THEN CLK_4HZ<='0'; COUNTER2<=1;

ELSE COUNTER2<=COUNTER2+1; END IF; END IF; END PROCESS;

PROCESS(CLK_4MHZ) BEGIN

IF CLK_4MHZ'EVENT AND CLK_4MHZ='1' THEN IF DRIVER=\ CARRIER<='1'; DRIVER<=ORIGIN; ELSE

DRIVER<=DRIVER+1; CARRIER<='0'; END IF; END IF; END PROCESS;

PROCESS(CARRIER)

BEGIN if(p='1')then

IF CARRIER'EVENT AND CARRIER='1' THEN COUNT<=COUNT+1; IF COUNT=\SPEAKER<='1'; ELSE

SPEAKER<='0'; END IF; END IF; end if;

END PROCESS;

PROCESS(CLK_4HZ) BEGIN

IF CLK_4HZ'EVENT AND CLK_4HZ='1' THEN IF COUNTER=140 THEN COUNTER<=0;

ELSE COUNTER<=COUNTER+1; END IF; END IF;

CASE COUNTER IS

WHEN 0 =>DIGIT<=\ WHEN 1 =>DIGIT<=\WHEN 2 =>DIGIT<=\ WHEN 3 =>DIGIT<=\WHEN 4 =>DIGIT<=\ WHEN 5 =>DIGIT<=\WHEN 6 =>DIGIT<=\ WHEN 7 =>DIGIT<=\WHEN 8 =>DIGIT<=\ WHEN 9 =>DIGIT<=\WHEN 10 =>DIGIT<=\ WHEN 12 =>DIGIT<=\ WHEN 14 =>DIGIT<=\ WHEN 16 =>DIGIT<=\ WHEN 18 =>DIGIT<=\ WHEN 20 =>DIGIT<=\ WHEN 22 =>DIGIT<=\ WHEN 24 =>DIGIT<=\ WHEN 26 =>DIGIT<=\ WHEN 28 =>DIGIT<=\ WHEN 30 =>DIGIT<=\ WHEN 32 =>DIGIT<=\ WHEN 34 =>DIGIT<=\ WHEN 36 =>DIGIT<=\ WHEN 38 =>DIGIT<=\ WHEN 40 =>DIGIT<=\ WHEN 42 =>DIGIT<=\ WHEN 11 =>DIGIT<=\WHEN 13 =>DIGIT<=\WHEN 15 =>DIGIT<=\WHEN 17 =>DIGIT<=\WHEN 19 =>DIGIT<=\WHEN 21 =>DIGIT<=\WHEN 23 =>DIGIT<=\WHEN 25 =>DIGIT<=\WHEN 27 =>DIGIT<=\WHEN 29 =>DIGIT<=\WHEN 31 =>DIGIT<=\WHEN 33 =>DIGIT<=\WHEN 35 =>DIGIT<=\WHEN 37 =>DIGIT<=\WHEN 39 =>DIGIT<=\WHEN 41 =>DIGIT<=\WHEN 43 =>DIGIT<=\

WHEN 44 =>DIGIT<=\ WHEN 45 =>DIGIT<=\WHEN 46 =>DIGIT<=\ WHEN 47 =>DIGIT<=\WHEN 48 =>DIGIT<=\ WHEN 49 =>DIGIT<=\WHEN 50 =>DIGIT<=\ WHEN 51 =>DIGIT<=\WHEN 52 =>DIGIT<=\ WHEN 53 =>DIGIT<=\WHEN 54 =>DIGIT<=\ WHEN 56 =>DIGIT<=\ WHEN 58 =>DIGIT<=\ WHEN 60 =>DIGIT<=\ WHEN 62 =>DIGIT<=\ WHEN 64 =>DIGIT<=\ WHEN 66 =>DIGIT<=\ WHEN 68 =>DIGIT<=\ WHEN 70 =>DIGIT<=\ WHEN 72 =>DIGIT<=\ WHEN 74 =>DIGIT<=\ WHEN 76 =>DIGIT<=\ WHEN 78 =>DIGIT<=\ WHEN 80 =>DIGIT<=\ WHEN 82 =>DIGIT<=\ WHEN 84 =>DIGIT<=\ WHEN 86 =>DIGIT<=\ WHEN 55 =>DIGIT<=\WHEN 57 =>DIGIT<=\WHEN 59 =>DIGIT<=\WHEN 61 =>DIGIT<=\WHEN 63 =>DIGIT<=\WHEN 65 =>DIGIT<=\WHEN 67 =>DIGIT<=\WHEN 69 =>DIGIT<=\WHEN 71 =>DIGIT<=\WHEN 73 =>DIGIT<=\WHEN 75 =>DIGIT<=\WHEN 77 =>DIGIT<=\WHEN 79 =>DIGIT<=\WHEN 81 =>DIGIT<=\WHEN 83 =>DIGIT<=\WHEN 85 =>DIGIT<=\WHEN 87 =>DIGIT<=\

WHEN 88 =>DIGIT<=\ WHEN 89 =>DIGIT<=\WHEN 90 =>DIGIT<=\ WHEN 91 =>DIGIT<=\WHEN 92 =>DIGIT<=\ WHEN 93 =>DIGIT<=\WHEN 94 =>DIGIT<=\ WHEN 95 =>DIGIT<=\WHEN 96 =>DIGIT<=\ WHEN 97 =>DIGIT<=\WHEN 98 =>DIGIT<=\ WHEN 100=>DIGIT<=\ WHEN 102=>DIGIT<=\ WHEN 104=>DIGIT<=\ WHEN 106=>DIGIT<=\ WHEN 108=>DIGIT<=\ WHEN 110=>DIGIT<=\ WHEN 112=>DIGIT<=\ WHEN 114=>DIGIT<=\ WHEN 116=>DIGIT<=\ WHEN 118=>DIGIT<=\ WHEN 120=>DIGIT<=\ WHEN 122=>DIGIT<=\ WHEN 124=>DIGIT<=\ WHEN 126=>DIGIT<=\ WHEN 128=>DIGIT<=\ WHEN 130=>DIGIT<=\ WHEN 99 =>DIGIT<=\WHEN 101=>DIGIT<=\WHEN 103=>DIGIT<=\WHEN 105=>DIGIT<=\WHEN 107=>DIGIT<=\WHEN 109=>DIGIT<=\WHEN 111=>DIGIT<=\WHEN 113=>DIGIT<=\WHEN 115=>DIGIT<=\WHEN 117=>DIGIT<=\WHEN 119=>DIGIT<=\WHEN 121=>DIGIT<=\WHEN 123=>DIGIT<=\WHEN 125=>DIGIT<=\WHEN 127=>DIGIT<=\WHEN 129=>DIGIT<=\WHEN 131=>DIGIT<=\

WHEN 132=>DIGIT<=\ WHEN 133=>DIGIT<=\WHEN 134=>DIGIT<=\ WHEN 135=>DIGIT<=\WHEN 136=>DIGIT<=\ WHEN 137=>DIGIT<=\WHEN 138=>DIGIT<=\ WHEN 139=>DIGIT<=\WHEN OTHERS=>DIGIT<=\END CASE; CASE DIGIT IS

WHEN \ WHEN \ WHEN \ WHEN \ WHEN \ WHEN \ WHEN \ WHEN \ WHEN \ WHEN \WHEN OTHERS=>ORIGIN<=\END CASE; END PROCESS; END SONG;

警示灯总程序:

#include #include #include #include #include \

#include \ #include \ #include \ int num;

static void Button_ISR_Init(void);

static void Button_Irq_Handler(void* context,alt_u32 id);

alt_u8 segtab[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //0~9段码 static void display(int num);

//按键初始化

static void Button_ISR_Init(void) {

IOWR_ALTERA_AVALON_PIO_IRQ_MASK(KEY_BASE,0xff); //允许8个按键中断 IOWR_ALTERA_AVALON_PIO_EDGE_CAP(KEY_BASE,0); //清除中断标志寄存器 alt_irq_register(KEY_IRQ,NULL,Button_Irq_Handler); //注册中断 }

static void display(int num) {

IOWR_ALTERA_AVALON_PIO_DATA(SEL_BASE,0); //数码管位选

IOWR_ALTERA_AVALON_PIO_DATA(DAT_BASE,segtab[num]); //显示倒计时 usleep(1000); }

/*------------------------------------------------------------------ ***********************按键中断处理函数**************************** *-----------------------------------------------------------------*/

static void Button_Irq_Handler(void* context,alt_u32 id) { int i;

for(i=0;i<9;i++) {

num=9-i; display(num);

IOWR_ALTERA_AVALON_PIO_DATA(A_BASE, 1);//蜂鸣器响起 IOWR_ALTERA_AVALON_PIO_DATA(LED1_BASE, 0); IOWR_ALTERA_AVALON_PIO_DATA(LED2_BASE, 1); usleep(500000);

IOWR_ALTERA_AVALON_PIO_DATA(LED2_BASE, 0); usleep(500000); }

IOWR_ALTERA_AVALON_PIO_DATA(A_BASE, 0);//蜂鸣器关闭 IOWR_ALTERA_AVALON_PIO_EDGE_CAP(KEY_BASE,0); num=0;

display(num); }

int main(void) {

printf(\

Button_ISR_Init(); //按键中断初始化

while(1) {

usleep(100000);

IOWR_ALTERA_AVALON_PIO_DATA(LED1_BASE, 1); IOWR_ALTERA_AVALON_PIO_DATA(LED2_BASE, 0); num=0; display(num); } return 0; }

六、设计结果

按键未按下时,处于初始状态:LED1亮,LED2灭,数码管显示为0,蜂鸣器未启动;按键按下之后,LED1灭,LED2闪烁,数码管进入9秒倒计时并且蜂鸣器响;9秒后恢复初始状态。

七、设计问题

设计中遇到了不少问题:

一开始因为延迟原因使得蜂鸣器音乐间断,后来将延迟时间缩短后问题解决;

然后在数码管动态显示时,也存在延时问题,按下按键后数码管在一秒后才进入倒计时,修改程序后问题解决;

八、心得感受

通过本次设计,我们更加熟悉C语言和SOPC,也在自己动手设计中发现了平时所没遇到的很多问题,包括硬件和软件方面的,有一部分是粗心,有一部分确实是不够了解这门技术;因此在设计过程中,我们不断和其他小伙伴探讨后解决了问题,并从他们那里学到了不少东西。

本文来源:https://www.bwwdw.com/article/z42w.html

Top