文章使用的工具及板子类型
工具:Quartus II 13.1
开发板:Cyclone IV E EP4CE115F29C7
一、UART IP核的介绍
-
定义
实现FPGA上的嵌入式系统与外部器件的RS-232串口通信
嵌入式系统的组成结构
-
寄存器的说明
divisor寄存器的说明
divisor寄存器的值是用于产生波特率时钟的,它是一种可选的硬件功能。如果没有使能Baud Rate Can Be Changed By Software(波特率能被软件改变),将不存在divisor寄存器。
计算公式:
b a u d r a t e = c l o c k f r e q u e n c y d i v i s o r + 1 {baud rate=\frac {clock frequency}{divisor+1}} baudrate=divisor+1clockfrequency
d i v i s o r = i n t ( c l o c k f r e q u e n c y b a u d r a t e + 0.5 ) {divisor=int(\frac {clock frequency}{baud rate}+0.5)} divisor=int(baudrateclockfrequency+0.5)
status寄存器的说明
状态寄存器的各个位可以反应UART核的各个状态,重点说明TRDY,RRDY名称 操作 描述 TRDY 读 Transmit Ready,TRDY位提示txdata寄存器的当前状态。当txdata寄存器位空时,可以接收新的字符且TRDY位为1,反之。Avalon-MM主控制器必须等TRDY位为1后,才能将新的数据写入txdata寄存器中 RRDY 读 Receive Character Ready,RRDY位提示rxdata寄存器的当前状态。当rxdata寄存器为空时,RRDY为0,且还不是读取rxdata寄存器的时刻。当新接收的值传输到rxdata寄存器时,RRDY位置为1,读rxdata寄存器会将RRDY位置置为0。Avalon-MM主控制器必须等待RRDY为变为1后,才能够读取rxdata寄存器
二、Nios II软核实现UART通信
(一)硬件部分设计
- 完成基本的硬件部分设计
请先参考下面链接中的硬件部分设计,完成相应的硬件部分设计
https://blog.youkuaiyun.com/qq_43279579/article/details/115933154 - 添加其他IP核
添加UART
在搜索框上输入uart,选择UART(RS-232 Serial Port),点击Add
进行数据设置,也可保持默认设置
连接时钟和复位,以及数据位,中断的设置,Export设置
- 系统分配地址
选择System->Assign Base Address - 使用FPGA资源
选择Generate->Generate,保持默认设置,点击Generate,选择Save - 创建顶层文件
回到Quarters,选择New->Verilog HDL File
顶层文件内容
保存文件,并编译module uart( input clk, input reset_n, //uart的接收和发送端 input rxd,//接收 output txd//发送 ); system_qsys u0 ( .clk_clk (clk), // clk.clk .reset_reset_n (reset_n), // reset.reset_n .uart_rxd (rxd), // uart.rxd .uart_txd (txd) // .txd ); endmodule
- 芯片引脚设置
菜单里选择 Assignments-device,点击 Device pin options
进行 unused pin 设置,可能会收到外部信号的干扰,将未用引脚设置为 As input tri-stated,特殊引脚设置,设置为常规引脚 - 编译完成后,分配管脚
再次编译
(二)软件设计
- 基本软件设计过程
请参考下面链接中,软件设计的过程,完成文件的创建
https://blog.youkuaiyun.com/qq_43279579/article/details/115933154 - 修改代码文件
打开hello_world中的.c文件
内容如下#include <stdio.h> #include "unistd.h" #include "system.h" #include "alt_types.h" #include "altera_avalon_uart_regs.h" #include "sys\alt_irq.h" alt_u8 txdata=0; alt_u8 rxdata=0; //UART中断服务函数 void IRQ_UART_Interrupts(){ rxdata = IORD_ALTERA_AVALON_UART_RXDATA(UART_BASE);//将rxdata寄存器中存储的值读入变量rxdata中 txdata = rxdata;//串口自收发,将变量rxdata的值赋给txdata while(!(IORD_ALTERA_AVALON_UART_STATUS(UART_BASE)& ALTERA_AVALON_UART_STATUS_TRDY_MSK)); //查询发送准备接收信号,如果没有准备好,则等待 IOWR_ALTERA_AVALON_UART_TXDATA(UART_BASE,txdata);//发送准备好,发送txdata } //中断初始化函数 void IRQ_init() { //清除状态寄存器 IOWR_ALTERA_AVALON_UART_STATUS(UART_BASE, 0); //使能接收准备中断,给控制寄存器相应位写1 IORD_ALTERA_AVALON_UART_CONTROL(UART_BASE); alt_ic_isr_register( UART_IRQ_INTERRUPT_CONTROLLER_ID,//注册ISR UART_IRQ,//中断控制器标号,从system.h复制 IRQ_UART_Interrupts,//UART中断服务函数 0x0,//指向与设备驱动实例相关的数据结构体 0x0);//flags,保留未用 } int main() { /*while(1){ IOWR_ALTERA_AVALON_UART_TXDATA(UART_BASE, "hello world!\n"); int i=0; while(i<5000) { i++; } }*/ IRQ_init(); while(1); return 0; }
- 保存编译
点击保存,选择hello_wold_bsp,右键后,选择Nios II中的Generate BSP,编译应用文件,选择hello_world右键后,点击Build Project
(三)下载硬件和软件
- 硬件的下载
检查是否检测到USB-Blaster,如果检测到后,点击Start,开始下载,否则,就检查看问题出现在那个地方。 - 软件的下载
选择应用工程,右键后,选择Run As中的Nios II Hardware,如果没有出现问题,就点击Apply->Run.
三、实际结果
由于暂时无法连接板子上面的RS-232接口,结果无法展示。后续能够连接接口后,再添加相应的结果。