| 
 前面章节中我们打印的测试结果都是通过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调用,需要慢慢积累。  
 
 
 |