加载中…
正文 字体大小:

[FPGA]基于Qsys的Nios II通用异步收发器(UART)系统设计

(2013-12-22 21:43:40)
标签:

quartusii

niosii

qsys

uart

sdram

it

分类: 嵌入式
一、基本说明

1、软件平台:Quartus II 13.0(64-bit)

Nios II 13.0 Software Build Tools for Eclipse

2、硬件平台:Altera Cyclone II EP2C8Q208C8N

             SAMSUNG K4S641632K-UC60

二、设计目标

完成FPGA平台上的UART的实现,实现方式:基于QsysNios II系统设计,将程序加载到SDRAM中,实现UART的功能。

三、具体步骤

1、打开Quartus II 64-Bit软件,新建工程。单击File -> New Project Wizard,打开New Project Wizard对话框,单击Next>,在what is the working directory for this project?中设置工作目录的位置,如F:/FPGAandCPLD/Demo/NIOS/uart,这里强烈建议大家习惯使用全英文目录,且目录中不要包含空格等。然后设置工程的名称(What is the name of this project?),如uart。最终完成效果如图1所示。

[FPGA]基于Qsys的Nios <wbr>II通用异步收发器(UART)系统设计

1 Directory,Nmae,Top-Level Entity

2、单击Next->,我们没有文件需要添加到当前工程中,所以继续单击Next>进入下一步。这里我们设置器件,使用的Cyclone II系列的EP2C8Q208C8N,先在Family中选择Cyclone II,然后在Available devices中选择EP2C8Q208C8,然后单击Next>进行下一步即可。这里进行EDA Tool设置,由于我们没有进行仿真,所以Simulation行中全部选择为。然后单击Finish完成工程建立。

3、我们单击菜单栏的Tools -> Qsys,使用Qsys工具进行NIOS II软核的设置。首先在左侧的Component Library中搜索Nios II Processor,双击,进入设置,在Core Nios II标签下的Select a Nios II Core栏中选择Nios II/s,至于这三种内核的区别前面的文章中有简单介绍,同时网上也有这方面的介绍,这里就不在赘述。然后针对内核的设置暂时到这,等后面的模块添加完成后在进行进一步设置,先单击Finish完成。

4、下面我们添加JTAG UART,方法同步骤3,双击打开后不用进行任何设置,直接Finish完成即可。

5、下面我们添加System ID Peripheral,同上,双击打开后在Parameters中设置我们希望的系统ID即可,如设置为123,单击Finish完成设置。

6、下面我们添加SDRAM Controller,这里我们使用的SAMSUNGSDRAM芯片,大小为64M      B = 1M x 16Bit x 4Banks,具体的其他内容大家可以查看其datesheet。这里的具体配置如图2所示。然后单击Finish完成即可。

[FPGA]基于Qsys的Nios <wbr>II通用异步收发器(UART)系统设计

2 SDRAM设置

7、最后我们添加UART(RS-232 Serial Port)。双击打开后,按照图3完成设置。单击Finish完成设置。

[FPGA]基于Qsys的Nios <wbr>II通用异步收发器(UART)系统设计

3 UART核设置

8、至此,所有系统需要的模块已经添加完成,这里我们更改一下各个模块的名称,依次选择各个模块,右击,选择Rename进行名称更改。然后进行连线。然后设置输出名称,同时将右侧的IRQ依次连上。具体完成效果图如图4所示。

[FPGA]基于Qsys的Nios <wbr>II通用异步收发器(UART)系统设计

4 重命名、连线等完成效果图

9、继续对Nios II内核进行设置。双击打开nios2_qsys,在Core Nios II标签下,Reset vector memory设置为sdram.s1Exception vector memory设置为sdram.s1,然后单击Finish完成设置。

10、下面我们单击菜单栏的System -> Assign Base Addresses,这时我们会发现下面Message中的错误全部消失,然后单击File -> Save进行保存,保存名称为uart_qsys,然后选择Generation选项卡,单击左下角的Generate进行生成即可。生成时间较长,大家耐心等待。

11、生成完成后,发现会有2 Warnings,这里的警告不影响我们随后的操作,随意我们忽略这2个警告,单击Close后关闭Qsys对话框回到Quartus II主界面。

12、单击菜单栏中的Project -> Add/Remove Files in Project…,选择Files标签,然后在File name中找到我们工程所在文件夹下的uart_qsys.qsys文件,然后单击Add,将其添加到我们的工程文件中。最后单击OK返回。

13、单击菜单栏的File -> New…,新建一个Block Diagram/Schematic File。然后双击新建的文件的空白处,选择左侧Libraries中的Project中的uart_qsys,单击OK将其添加到我们工程中。

14、下面添加PLL模块,系统需要两路时钟,一路供给内核,另一路供给SDRAM,同时这两路时钟需要有一定的相位差。双击空白处,打开Symbol对话框,单击MegaWizard Plug-In Manager…,选择Create a new cunstom megafunction variation,单击Next>进行下一步配置。左侧我们搜索ALTPLL,然后选中,右侧在What name do you want for the output file?中后面添加PLL模块的名称,如PLL,完成效果为F:/FPGAandCPLD/Demo/NIOS/uart/PLL。然后单击Next>进行进一步设置。

15、在What is the frequency of the inclk0 input?中设置为50MHz,单击Next>,去掉Create an 'areset' input to asynchronously reset the PLL前面的勾。单击Next>,不进行任何设置,单击Next>,不进行任何设置,单击Next>。勾选use this clockClock phase shift设置为-60,然后单击Finish完成设置即可。这是弹出一个Quartus II IP Files对话框,不需要进行任何设置,直接单击Yes即可。回到Symbol对话框,单击OK将其添加。

16、双击空白处,打开Symbol对话框,在Name中搜索input,单击OK添加。同样操作,共添加1个两输入与门(and2)、1个双向接口(bidir)、3个输入接口(input)、10个输出接口(output)。具体连接方式和命名方式如图5所示。

[FPGA]基于Qsys的Nios <wbr>II通用异步收发器(UART)系统设计

5 引脚连接方式及命名

17、然后单击File -> Save对文件进行保存,命名为uart.bdf。然后单击File -> New,新建一个TCL Scrtipt File,进行引脚分配,具体分配内容见附录一。然后进行保存,命名为pinset.tcl。然后单击Tools -> Tcl Scripts…,选择pinset.tcl,单击Run,然后弹出对话框,单击OK结束。然后回到uart.bdf文件,可以看到现在引脚已经与标号对应起来。然后我们单击Processing -> Start Compilation,进行编译。编译时间较长,耐心等待。编译无误后进入下一步。

18、单击菜单栏Assignments -> Device…,单击Device and Pin Options…,选择Unused PinsReserve all unused pins选择As input tri-stated。然后单击OK完成设置。然后重新编译工程。

至此,硬件部分设计完成,下面进行软件方面的设计。

19、单击菜单栏Tools -> Nios II Software Build Tools for Eclipse,启动Nios II软件开发环境。首先选择Workspace位置,我们定位到和Nios软核共同的文件夹中,即定位到F:\FPGAandCPLD\Demo\NIOS\uart。单击OK继续进行。

20、单击File -> New -> Nios II Application and BSP from Template,在SOPC Information File name中选择我们已经生成的软核信息,即uart_qsys.sopcinfo注意,一定要选择对应文件夹下的软核信息,否则由于软硬件不对应导致错误。稍等片刻之后,系统完成对信息的读取,然后自动填写CPU name。下面我们填写Project name,如uart,然后Project template选择Hello word。单击Finish即可完成。

21、右击uart目录下的hello_world.c文件,选择Rename…,这里将名称改为main.c,单击OK完成。然后双击打开该文件。

22、编写代码,具体内容见附录二。编写完成后保存一下。

23、右击uart目录,单击Nios II -> BSP Editor,弹出Nios II BSP Editor对话框,然后选择Settings,右侧的设置如图6所示。

[FPGA]基于Qsys的Nios <wbr>II通用异步收发器(UART)系统设计

6 Nios II BSP Editor设置

24、单击右下角的Generate,进行生成。生成完成后退出即可。

25、右击uart目录,选择Build Project,进行工程编译,首次编译时间较长,大家耐心等待。编译无误后,即可进行下一步。

至此,软件设计完成,下面进行硬件配置和软件程序的下载。

26、返回Quartus II,单击Tools -> Programmer,如果Hardware Setup…后面没有显示出下载线,单击Hardware Setup…进行设置,这里就不在多说。然后Mode选择JTAG。单击右侧的Add File…,进入output_files中,选择uart.sof文件,勾上Program/Configure,单击Start进行下载。注意,这时下载线要接在JTAG接口上,而不是AS接口上。下载完成后关闭即可。注意,下载完成后不要对FPGA断电,否则下载内容全部丢失。

27、返回Nios II。右击Run As -> Nios II Hardware,打开Run Configurations对话框,然后选择Target Connection,单击Refresh Connections,然后找到下载器后单击Apply,最后单击Run,将程序下载到FPGA注意:这一步是将程序下载到SDRAM中,如果掉电后程序仍然不存在。

至此,本次试验所有操作全部结束,可以想怎么发就怎么发了。

 

 

 

附录一  引脚分配

#系统时钟引脚

set_location_assignment pin_28  -to sys_clk

#系统复位引脚

set_location_assignment pin_112 -to reset_n

#SDRAM引脚

set_location_assignment pin_192 -to sdram_dq[0]

set_location_assignment pin_193 -to sdram_dq[1]

set_location_assignment pin_195 -to sdram_dq[2]

set_location_assignment pin_197 -to sdram_dq[3]

set_location_assignment pin_198 -to sdram_dq[4]

set_location_assignment pin_15  -to sdram_dq[5]

set_location_assignment pin_30  -to sdram_dq[6]

set_location_assignment pin_31  -to sdram_dq[7]

set_location_assignment pin_208 -to sdram_dq[8]

set_location_assignment pin_207 -to sdram_dq[9]

set_location_assignment pin_206 -to sdram_dq[10]

set_location_assignment pin_205 -to sdram_dq[11]

set_location_assignment pin_203 -to sdram_dq[12]

set_location_assignment pin_201 -to sdram_dq[13]

set_location_assignment pin_200 -to sdram_dq[14]

set_location_assignment pin_199 -to sdram_dq[15]

set_location_assignment pin_44  -to sdram_addr[0]

set_location_assignment pin_45  -to sdram_addr[1]

set_location_assignment pin_46  -to sdram_addr[2]

set_location_assignment pin_47  -to sdram_addr[3]

set_location_assignment pin_14  -to sdram_addr[4]

set_location_assignment pin_13  -to sdram_addr[5]

set_location_assignment pin_12  -to sdram_addr[6]

set_location_assignment pin_11  -to sdram_addr[7]

set_location_assignment pin_10  -to sdram_addr[8]

set_location_assignment pin_8   -to sdram_addr[9]

set_location_assignment pin_43  -to sdram_addr[10]

set_location_assignment pin_6   -to sdram_addr[11]

set_location_assignment pin_40  -to sdram_ba[0]

set_location_assignment pin_41  -to sdram_ba[1]

set_location_assignment pin_4   -to sdram_cke

set_location_assignment pin_48  -to sdram_clk

set_location_assignment pin_3   -to sdram_dqm[1]

set_location_assignment pin_33  -to sdram_dqm[0]

set_location_assignment pin_35  -to sdram_cas_n

set_location_assignment pin_39  -to sdram_cs_n

set_location_assignment pin_37  -to sdram_ras_n

set_location_assignment pin_34  -to sdram_we_n

#UART

set_location_assignment pin_89  -to uart_txd

set_location_assignment pin_90  -to uart_rxd

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

附录二 程序

1、非中断方式

//非中断方式

#include

#include

#include "unistd.h"

#include "system.h"

#include "alt_types.h"

#include "altera_avalon_uart_regs.h"

int main()

{

    printf("Hello from Nios II\n");

    alt_u8txdata = 0;

    alt_u8rxdata = 0;

    while(1)

    {

       //查询接收准备好信号,如果没有准备好,则等待

while(!((IORD_ALTERA_AVALON_UART_STATUS(UART_BASE)&ALTERA_AVALON_UART_STATUS_RRDY_MSK)));

       //接收准备好,读取UART接收数据

       rxdata = IORD_ALTERA_AVALON_UART_RXDATA(UART_BASE);

       txdata = rxdata;

       //查询发送准备好信号,如果没有准备好,则等待

while(!((IORD_ALTERA_AVALON_UART_STATUS(UART_BASE)&ALTERA_AVALON_UART_STATUS_TRDY_MSK)));

       //发送准备好,发送txdata

       IOWR_ALTERA_AVALON_UART_TXDATA(UART_BASE,txdata);

    }

    return 0;

}

2、中断方式

//中断方式

#include

#include

#include "unistd.h"

#include "system.h"

#include "alt_types.h"

#include "altera_avalon_uart_regs.h"

#include "sys\alt_irq.h"

static alt_u8txdata = 0;

static alt_u8rxdata = 0;

//UART中断服务函数

static void uart_isr(void * context,alt_u32 id)

{

    rxdata = IORD_ALTERA_AVALON_UART_RXDATA(UART_BASE);

    txdata = rxdata;

    //查询发送准备好信号,如果没有准备好,则等待

while(!((IORD_ALTERA_AVALON_UART_STATUS(UART_BASE)&ALTERA_AVALON_UART_STATUS_TRDY_MSK)));

    //发送准备好,发送txdata

    IOWR_ALTERA_AVALON_UART_TXDATA(UART_BASE,txdata);

}

void uart_init()

{

    //清除状态寄存器

    IOWR_ALTERA_AVALON_UART_STATUS(UART_BASE,0);

    //使能接受准备好中断

    IOWR_ALTERA_AVALON_UART_CONTROL(UART_BASE,0X80);

}

int main()

{

    printf("Please Start!\n");

    //注册UART中断服务函数

    alt_irq_register(UART_IRQ,NULL,uart_isr);

    uart_init();

    while(1){}

    return 0;

}

0

阅读 评论 收藏 转载 喜欢 打印举报
已投稿到:
  • 评论加载中,请稍候...
发评论

    发评论

    以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

      

    新浪BLOG意见反馈留言板 不良信息反馈 电话:4006900000 提示音后按1键(按当地市话标准计费) 欢迎批评指正

    新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 会员注册 | 产品答疑

    新浪公司 版权所有