[X]关闭

Mis603开发板MB SOC开发教程:第七章 串口中断实验

文档创建者:Milinker_XU
浏览次数:4098
最后更新:2016-01-14
前面章节中我们打印的测试结果都是通过JTAG返回控制台的,这章我们将在MB系统中添加一个串口,利用此串口可进行相关的调试,并完成一个串口的中断实验。
◎紧接第六章工程,打开XPS系统,在工程中添加AXI UART(Lite)IP,在弹出对话框中选择yes。


◎点击该ip,打开配置程序,选择默认。波特率9600bps,8位,无奇偶校验位。


◎单击axi_uart_lite,将名称命名为RS232。可以看到RS232挂到了MB系统的AXI4Lite0总线上。


◎在Ports中,打开RS232的下拉菜单,将RS232中断连接到中断控制器上。


◎可以看到,加上前两章,此时已有3个中断系统挂在中断控制intc0下了。


ExternalPorts中可以看到,RS232的两个接口已接到外面了。


◎在mis603_soc.mhs文件中,已经可以看到串口的两个PORT了。


◎打开mis603_soc.ucf文件,为RS232的两个引脚配置约束。

◎保存后,在Hardware下运行Generate NetList,产生网表。
◎打开SDK文件,在SDK中新建个工程,工程命名为Uart_Interrupt,以helloworld为模板。


◎将helloworld.c文件命名为uart_intr.c文件。
◎先写个程序来测试下,RS232是否能正常通信。我们从上位机中发送数据,当接收到数据后,立即发送至上位机,做一个环路测试。
  
/*
  
* uart_intr.c
  
*
  
*   Created on: 2016-1-14
  
*       Author: Milinker Xu
  
*/
  
#include <stdio.h>
  
#include "xparameters.h"
  
#include "xuartlite_l.h"
  
#include "xuartlite.h"
  
#include "platform.h"
  
int main()
  
{
  
    unsigned char rx_data;      //8 bit接收数据
  
    unsigned char i;
  
  
    init_platform();
  
  
    while(1)
  
{
  
//check receiver buffer is empty or not
  
        if(!XUartLite_IsReceiveEmpty(XPAR_UARTLITE_1_BASEADDR))                 
  
{
  
       //delay
  
         for (i=100;i>0;i--);                    
  
       //receive one byte
  
         rx_data  = XUartLite_RecvByte(XPAR_UARTLITE_1_BASEADDR);        
  
      //delay
  
       for (i=100;i>0;i--);                        
  
       //send one byte         
  
         XUartLite_SendByte(XPAR_UARTLITE_1_BASEADDR,rx_data);         
  
//delay
  
for (i=100;i>0;i--);                                    
  
       }
  
    }
  
    return 0;
  
}
  

◎将ISE生成的bit文件下载后,在运行UART_INTR工程,在run configuration新建一个UART_INTR Debug,中默认即可。


◎将J5连接到PC机的串口,安装好驱动程序。打开串口调试助手,设置好波特率。


◎在发送串口输入发送数据,选择自动发送模式,再打开串口。这样串口调试助手中就能收到发送端的数据,证明发送与接收通信正常。


◎在发送串口输入发送数据,选择自动发送模式,再打开串口。这样串口调试助手中就能收到发送端的数据,证明发送与接收通信正常。
◎同前几节一样,新建几个文件:1.uart中断设置文件,uart_intr_initial_set.c;2.串口中断处理函数文件uart_intr_handler.c;3.串口中断头文件。
◎在uart_intr_initial_set.c文件主要包括两方面:中断控制器初始化和串口初始化。中断控制器初始化包括:初始化中断、使能中断、外部中断初始化、外部中断处理子函数和启动中断。串口初始化包括:串口控制器初始化、串口中断与中断控制器直接映射、以及使能串口中断程序。代码如下所示。
  
/*
  
* uart_intr_initial.c
  
*
  
*   Created on: 2016-1-14
  
*       Author: Milinker XU
  
*/
  
  
#include "uart_intr.h"
  
  
void Uart_Init(XIntc* IntcInstancePtr,XUartLite* UartInstancePtr,u16 DeviceId,u16 IntrId)
  
{
  
    XUartLite_Initialize(UartInstancePtr,  DeviceId);
  
    XIntc_Connect(IntcInstancePtr, IntrId,(XInterruptHandler)uart_intr_handler,(void*)UartInstancePtr);
  
    XUartLite_EnableInterrupt(UartInstancePtr);
  
}
  
  
void intr_set(void) //设置中断
  
{
  
    intr_init(&Intc,  XPAR_INTC_0_DEVICE_ID);//初始化中断
  
    Uart_Init(&Intc,&Uart,XPAR_UARTLITE_1_DEVICE_ID,XPAR_INTC_0_UARTLITE_1_VEC_ID);//初始化GPIO中断
  
}
  
  
void intr_init(XIntc *IntcInstancePtr, u16 DeviceId)
  
{
  
    XIntc_Initialize(IntcInstancePtr,  DeviceId);//初始化中断
  
     XIntc_Enable(&Intc, XPAR_INTC_0_UARTLITE_1_VEC_ID);//使能中断
  
    Xil_ExceptionInit();
  
     Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, (Xil_ExceptionHandler)XIntc_InterruptHandler,IntcInstancePtr);
  
    Xil_ExceptionEnable();
  
    XIntc_Start(IntcInstancePtr,  XIN_REAL_MODE);//启动中断
  
}
  

◎uart_intr_handler.c文件中,主要是串口中断子程序的调用。当串口接收到数据时,通过读取状态寄存器来判断,进入中断,中断子程序将接收到的数据发送回去。
  
/*
  
* uart_intr_handler.c
  
*  Created on: 2016-1-14
  
*       Author: Administrator
  
*/
  
#include "uart_intr.h"
  
void uart_intr_handler(void *CallbackRef)//中断函数
  
{
  
    u8 ReadByte;
  
    u32 IsrStatus;
  
    XUartLite *InstancePtr= (XUartLite *)CallbackRef;
  
    //读取状态寄存器
  
    IsrStatus = XUartLite_ReadReg(InstancePtr->RegBaseAddress,XUL_STATUS_REG_OFFSET);    while(IsrStatus &  XUL_SR_RX_FIFO_VALID_DATA)
  
    {
  
        //读取数据
  
        ReadByte=XUartLite_ReadReg(InstancePtr->RegBaseAddress,XUL_RX_FIFO_OFFSET);
  
        //发送数据
  
        XUartLite_WriteReg(InstancePtr->RegBaseAddress,XUL_TX_FIFO_OFFSET,ReadByte);
  
        //读取状态寄存器
  
        IsrStatus = XUartLite_ReadReg(InstancePtr->RegBaseAddress,XUL_STATUS_REG_OFFSET);
  
    }
  
}
  
  

◎这样在主函数中只需要调用中断设置函数intr_set()即可。uart_intr.h文件中依然包含各类头文件和函数声明。

  
#include "uart_intr.h"
  
int main(void)
  
{
  
    Xil_ICacheEnable();
  
    intr_set();
  
    while(1)
  
        ;
  
}
  
◎将程序下载到板子上,运行该工程,打开串口调试助手,输入发送数据,可以看到接收到一样的数据。



◎或许有人就不理解了,既然结果是一致的,为什么还要用到中断,直接用第一中方法不是一样么。这里需要做下解释,串口中断是指无论程序工作在什么状态,只要串口端接收到数据,就立即跳转到中断函数执行,完成后继续返回原程序进行后续操作。而第一种方法采用查询的方式,不断读取串口标志位,查询是否有数据接收到。程序需要不停地读取状态寄存器,才能够判断是否接收到数据,两者相比,效率明显低下,且占据了程序空间。
◎UART程序中,有两个重要的头文件。xuartlite.h文件。这两个文件分别包含了串口的初始化,发送,接收,状态寄存器和使能中断控制。Xuartlite_l.h文件包含一些寄存器的偏移地址,在读写数据和状态寄存器时都需用到。至于具体的寄存器操作和API调用,需要慢慢积累。



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则