ZYNQ UART中断
·
一、另存一个zynq的hello word工程,命名为uart_inter_loop

二、删掉SDK包,重新生成SDK 硬件设计编写代码。

三、导出硬件设计

四、打开SDK,新建一个项目,建立一个main.c的源文件后编写SDK代码。
#include "stdio.h"
#include "xparameters.h"
#include "xuartps.h"
#include "XScuGic.h"
#define UART_DEVICE_ID XPAR_XUARTPS_0_DEVICE_ID
#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID
#define UART_INT_IRQ_ID XPS_UART1_INT_ID
#define XIL_EXCEPTION_ID_INT XIL_EXCEPTION_ID_IRQ_INT
XUartPs_Config *Config;
XUartPs UartPs;
XScuGic_Config *IntcConfig;
XScuGic Interr_contrl;
//串口初始化函数
int uart_init(XUartPs *UartPs)
{
int Status;
//GPIO 初始化
Config = XUartPs_LookupConfig(UART_DEVICE_ID);
if (NULL == Config) {
return XST_FAILURE;
}
Status = XUartPs_CfgInitialize(UartPs, Config, Config->BaseAddress);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/* Check hardware build */
Status = XUartPs_SelfTest(UartPs);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
//设置串口的工作模式
XUartPs_SetOperMode(UartPs, XUARTPS_OPER_MODE_NORMAL);//设置为正常模式
//设置接收fifo触发的阈值,达到设置的阈值后的数据会产生中断,以下是每接收到一个就产生一次中断。
XUartPs_SetFifoThreshold(UartPs,1);
//设置波特率,这里软件已经设置了默认的1152200,如果要自己修改可以设置。
XUartPs_SetBaudRate(UartPs,115200);
//设置停止位
XUartPs_SetRecvTimeout(UartPs, 8);
return XST_SUCCESS;
}
//中断处理函数
void uart_interr_handle(void *CallBackRef)
{
u32 recive_data;
u32 IsrStatus;
XUartPs *Uart_gpio=(XUartPs *)CallBackRef;
//读中断寄存器里面的值。XUartPs_SetInterruptMask(UartPs, XUARTPS_IXR_RXOVR);其实就是这个函数XUARTPS_IXR_RXOV的值,这个值
//只将最低为设置为1,也就是我们在中断系统初始化时使能了最低位。因此22读出来的也就是1:XUARTPS_IXR_RXOV
IsrStatus = XUartPs_ReadReg(Uart_gpio->Config.BaseAddress,XUARTPS_IMR_OFFSET);
IsrStatus &= XUartPs_ReadReg(Uart_gpio->Config.BaseAddress, XUARTPS_ISR_OFFSET);
//接收数据
if(IsrStatus & XUARTPS_IXR_RXOVR)
{
recive_data=XUartPs_RecvByte(Uart_gpio->Config.BaseAddress);
//清除状态位
XUartPs_WriteReg(Uart_gpio->Config.BaseAddress, XUARTPS_IMR_OFFSET,XUARTPS_IXR_RXOVR);
//发送数据
XUartPs_SendByte(Uart_gpio->Config.BaseAddress,recive_data);
}
}
//串口初始化函数中断函数
int uart_interr_init(XScuGic *Interr_contrl,XUartPs *UartPs)
{
int Status;
//中断初始化
IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
if (NULL == IntcConfig) {
return XST_FAILURE;
}
Status = XScuGic_CfgInitialize(Interr_contrl, IntcConfig,IntcConfig->CpuBaseAddress);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
Status = XScuGic_Connect(Interr_contrl, UART_INT_IRQ_ID,(Xil_ExceptionHandler)uart_interr_handle,(void *) UartPs);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
//设置触发方式,阈值触发
XUartPs_SetInterruptMask(UartPs, XUARTPS_IXR_RXOVR);
//处理ARM异常,中断程序必须有的三个函数
Xil_ExceptionInit();
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,(Xil_ExceptionHandler)XScuGic_InterruptHandler,Interr_contrl);
Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ);
//使能中断号。
XScuGic_Enable(Interr_contrl, UART_INT_IRQ_ID);
return XST_SUCCESS;
}
int main()
{
int Status;
printf("uart_interr_loop test!\n");
Status=uart_init(&UartPs);
if (Status != XST_SUCCESS) {
printf("uart_init error!\n");
return XST_FAILURE;
}
Status=uart_interr_init(&Interr_contrl,&UartPs);
if (Status != XST_SUCCESS) {
printf("uart_interr_init error!\n");
return XST_FAILURE;
}
while(1);
return Status;
}
五、这里就一个注意的点:#define UART_INT_IRQ_ID XPS_UART1_INT_ID。这里我用的小梅哥的板子,他的UART外设在vivade进行硬件设计的时候只能选择UART1,根据原理图所得。而正点原子的启明星zynq开发板的外设为UART0。也是根据原理图看出来的。这里我前面也有提到过。

六、烧录、实验结果。记得连接串口。下图,右上角的绿色加号。

更多推荐



所有评论(0)