发 帖  
原厂入驻New
[经验]

【正点原子FPGA连载】第五章串口中断实验--摘自【正点原子】达芬奇之Microblaze 开发指南

2020-10-17 11:41:48  308 正点原子FPGA FPGA
分享
1
第五章串口中断实验

我们在使用microBlaze进行嵌入式系统设计的时候,通常会用到AXI Uartlite IP核与外部设备通信。AXI UART IP核实现了RS-232通讯协议,并使得大家可以设置串口通信相关的波特率、奇偶校验位、停止位和数据位等参数。本章我们进一步向大家介绍利用AXI UART IP核的中断进行通信的方法。
本章包括以下几个部分:
55.1简介
5.2实验任务
5.3硬件设计
5.4软件设计
5.5下载验证


5.1简介
AXI UART IP核提供UART信号和AMBA(高级微控制器总线体系结构高级可扩展接口)之间的AXI接口,并提供异步串行数据传输的控制器接口。
AXI UART Lite IP核具有以下特点:
对通过axi4-lite接口接收的字符执行并行到串行转换,并对从串行外围设备接收的字符执行串行到并行转换。
发送和接收8、7、6或5位字符,有一个停止位,并支持奇数、偶数或无奇偶位的配置。AXI UART Lite可以独立传输和接收数据。
下图为AXI UART IP核的顶层框图:

图 5.1.1 AXI UART IP核的顶层框图

AXI InteRFace(AXI接口):该模块实现了用于寄存器访问和数据传输的AXI4-LITE从接口。
UART Lite Registers(UART Lite寄存器模块):此模块包括内存映射寄存器。它由一个控制寄存器、一个状态寄存器和一对发射/接收FIFO组成,两个FIFO都有16个字符的深度。当接收FIFO变为非空或当发送FIFO变为空时,生成上升沿敏感的中断。此中断可以通过使用中断启用/禁用信号来屏蔽。
UART Control(UART控制模块):该模块包括Rx Control(接收控制)、Tx Control(发送控制)、BRG (Baud Rate Generator)和Interrupt Control(中断控制)四个模块。
AXI UART IP核提供了AXI4-Lite接口,我们可以通过AXI4-Lite接口读取状态寄存器或配置UART Control模块(复位收发FIFO、启用中断)。当AXI UART接收到上位机发送的数据后,Rx Control模块根据BRG模块产生的波特率将串行的数据转化成并行数据,写入接收FIFO,然后处理器通过AXI4-Lite接口读出接收FIFO中的数据;处理器中的数据也可以通过AXI4-Lite接口写入发送FIFO,然后经Tx Control根据BRG模块产生的波特率将并行数据转化为串行数据发送出去。
5.2实验任务
本章的实验任务是根据AXI UART IP核产生的中断信号,完成串口数据的收发。
5.3硬件设计
根据实验任务可以画出系统框图,如图 5.3.1所示:

图 5.3.1 系统框图

由上图系统框图可知,AXI UART模块产生中断信号,中断控制器检测到中断信号后,产生输出中断信号,最终传入MicroBlaze软核处理器。可以看出本实验的系统框图跟《Hello World》实验基本相同,只是多添加了AXI Inlerrupt Controller(中断控制器)模块。本实验我们将在《Hello World》实验的基础上进行硬件设计。
我们先打开《Hello World》实验的Vivado工程,打开后依次点击栏的“File-> Project->Save As...”,如图 5.3.2所示:

图 5.3.2 选择另存为

在弹出的另存为界面中可以输入新的工程名或更改保存位置,此处我们输入新的工程名“uart_interrupt”,工程位置保持默认即可然。
在Flow Navigator中,点击IP INTEGRATOR下的“Open Block Design”,打开Block Design。添加AXI Inlerrupt Controller IP核。如图 5.3.3所示:

图 5.3.3 添加AXI Inlerrupt Controller IP核

添加好IP核后将我们然后点击“Run Connection Automation”,在弹出的界面选中所有信号,点击“OK”,如图 5.3.4所示:

图 5.3.4 自动连线

我们在Diagram页面空白处右击,在弹出的菜单栏选择“Regenerate Layout”重新生成布局。如图 5.3.5所示:

图 5.3.5 重新生成布局

然后将AXI Interrupt Controller的输出信号“interrupt”接口与MicroBlaze的“INTERRUPT”接口相连,将新添加的AXI Uartlite的“interrupt”接口与AXI Interrupt Controller的intr[0:0]接口相连。如图 5.3.6所示:

图 5.3.6 手动连线

再次重新生成布局,最终的硬件设计连线图如图 5.3.7所示:

图 5.3.7 整体系统架构连接图

到这里我们的Block Design就设计完成了,在Diagram窗口空白处右击,然后选择“Validate Design”验证设计。验证完成后弹出对话框提示“Validation Successful”表明设计无误,点击“OK”确认。最后按快捷键“Ctrl + S”保存设计。
接下来在Source窗口中右键点击Block Design设计文件“system.bd”,然后依次执行“Generate Output Products”和“Create HDL Wrapper”。
由于本章实验用到的外部设备与《Hello World》实验相同,所以我们不需要修改管脚约束。
在左侧Flow Navigator导航栏中找到PROGRAM AND debug,点击该选项中的“Generate Bitstream”,对设计进行综合、实现、并生成Bitstream文件。
在生成Bitstream之后,在菜单栏中依次点击“File->Export->Export hardware”导出硬件,并在弹出的对话框中,勾选“Include bitstream”,在导出路径最后添加“/vitis”。然后在菜单栏依次点击“Tools->Launch Vitis”,启动Vitis软件。
5.4软件设计
在将硬件导出至Vitis,并打开Vitis开发环境后,创建应用工程的步骤都是一样的,这里不再赘述,新创建的空白应用工程命名为“uart_interrupt”。
首先我们在uart_interrupt/src目录上右键,依次点击“New->Source File”,将源文件命名为“main.c”。
我们在新建的main.c文件中输入以下代码:
  • 1  #include "xil_exception.h"
  • 2  #include "xdebug.h"
  • 3  #include "xparameters.h"
  • 4  #include "xintc.h"
  • 5  #include "xuartlite.h"
  • 6  #include "xuartlite_l.h"
  • 7
  • 8  #define UART_DEVICE_ID XPAR_UARTLITE_0_DEVICE_ID     //串口器件ID
  • 9  #define UART_INTR_ID   XPAR_INTC_0_UARTLITE_0_VEC_ID //串口中断ID
  • 10 #define INTC_ID        XPAR_INTC_0_DEVICE_ID         //中断控制器ID
  • 11
  • 12 #define RX_NOEMPTY     XUL_SR_RX_FIFO_VALID_DATA     // 接收FIFO非空
  • 13
  • 14 static XIntc Intc;          //中断控制器实例
  • 15 static XUartLite Uart;      //串口实例
  • 16
  • 17 void uart_handler(void *CallbackRef);
  • 18
  • 19 int main(void){
  • 20     //初始化串口设备
  • 21     XUartLite_Initialize(&Uart , UART_DEVICE_ID);
  • 22     //初始化中断控制器
  • 23     XIntc_Initialize(&Intc, INTC_ID);
  • 24     //关联处理函数
  • 25     XIntc_Connect(&Intc, UART_INTR_ID,(XInterruptHandler)uart_handler,&Uart);
  • 26     //使能串口
  • 27     XUartLite_EnableInterrupt(&Uart);
  • 28     //打开中断控制器
  • 29     XIntc_Start(&Intc, XIN_REAL_MODE);
  • 30     //使能中断控制器
  • 31     XIntc_Enable(&Intc,UART_INTR_ID);
  • 32     //设置并打开中断异常处理功能
  • 33     Xil_ExceptionInit();
  • 34         Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
  • 35                 (Xil_ExceptionHandler)XIntc_InterruptHandler , &Intc);
  • 36         Xil_ExceptionEnable();
  • 37     while(1);
  • 38 }
  • 39
  • 40 void uart_handler(void *CallbackRef)//中断处理函数
  • 41 {
  • 42     u8 Read_data;
  • 43     u32 isr_status;
  • 44     XUartLite *InstancePtr= (XUartLite *)CallbackRef;
  • 45
  • 46     //读取状态寄存器
  • 47     isr_status = XUartLite_ReadReg(InstancePtr->RegBaseAddress ,
  • 48                                    XUL_STATUS_REG_OFFSET);
  • 49     if(isr_status & RX_NOEMPTY){  //接收FIFO中有数据
  • 50         //读取数据
  • 51         Read_data=XUartLite_ReadReg(InstancePtr->RegBaseAddress ,
  • 52                                     XUL_RX_FIFO_OFFSET);
  • 53         //发送数据
  • 54         XUartLite_WriteReg(InstancePtr->RegBaseAddress ,
  • 55                            XUL_TX_FIFO_OFFSET, Read_data);
  • 56     }
  • 57 }




这里我们介绍一下这段代码,我们可以看到主函数部分与《按键控制中断实验》框架基本相同,不同的是本次实验使用的IP是AXI UART Lite,连接的外设是USB UART。首先代码第21行,对AXI UART初始化;代码第23行,初始化中断控制器;代码第25行XIntc_Connect函数,将中断源UART_INTR_ID(代码第9行)和中断服务函数uart_handler关联起来;接着就是使能串口中断,打开中断控制器,使能中断控制器,中断异常处理一系列操作,如代码第27到36行所示。
代码第40到53行是中断处理函数部分,当AXI UART接收到数据后,产生中断并进入中断处理函数。在代码第47和48行,我们调用了XUartLite_ReadReg函数,来读取状态寄存器(Status Register)。状态寄存器包含了启用中断后或出现错误时数据接收FIFO和数据发送FIFO的状态,共有八种状态,分别是:奇偶校验错误、帧错误、数据溢出、使能中断、发送FIFO满、发送FIFO空、接收FIFO满、接收FIFO空和接收FIFO有数据。
读取到状态寄存器后,就根据状态寄存器判断接收FIFO是否有数据,当检测到接收FIFO中有数据后(RX_NOEMPTY,接收FIFO非空),读出接收FIFO的数据,如代码第51和52行所示。代码第54、55行,将读出的数据写入发送FIFO,最后通过串口发送出去。这样我们就完成了用串口接收数据并发送的环回。
右键uart_interrupt_system,点击“Build Project”,编译工程。
5.5下载验证
首先我们将下载器与达芬奇开发板上的JTAG接口连接,下载器另外一端与电脑连接。然后使用USB连接线将USB_UART接口与电脑连接,用于串口通信。最后连接开发板的电源,并打开电源开关
下载程序(过程不再赘述),软件程序下载完成后,打开资料提供的串口助手而非Vitis自带的Terminal,串口助手设置信息与Terminal相同。正确连接之后就可以发送数据。如图 5.5.1所示:

图 5.5.1 接收数据界面

串口成功打印出了“uart test”字符串,说明本次实验在达芬奇开发板上面下载验证成功。







评论

高级模式
您需要登录后才可以回帖 登录 | 注册

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容图片侵权或者其他问题,请联系本站作侵删。 侵权投诉
发经验
关闭

站长推荐 上一条 /7 下一条

快速回复 返回顶部 返回列表