基于zynq7000系列芯片的ARM核,与上位机通信,串口是在数据量不大,速率不快的情况下的最好选择,ZYNQ的串口提供了诸多中断模式,最常用的FIFO满中断(XUARTPS_IXR_RXFULL),FIFO空中断(XUARTPS_IXR_RXEMPTY),以及设定一定长度字符的等级中断(XUARTPS_IXR_RXOVR),对于不定长度的通信,若希望以不定长帧的形式发送数据给下位机,以上几种方式都不是最好的方法,这里使用接收时间溢出的方法,在接收到一帧数据结束后,几个bit的时间内没有接收到信息,则发生中断,这属于以时间成本换取功能的方法。
对于串口中断,需要三个主要部分:串口中断设置,串口初始化和中断服务函数,对于vivado的ps部分配置省略
中断配置函数
int setup_interrupt_uart(XScuGic *intc)
{
?? ?int status;
?? ?XScuGic_Config *interConfig;
?? ?Xil_ExceptionInit();
?? ?//查找中断控制器配置信息及初始化中断控制器驱动
?? ?interConfig=XScuGic_LookupConfig(UART_Interrupt_ID);
?? ?if(NULL==interConfig)
?? ?{
?? ??? ?return XST_FAILURE;//初始化失败返回
?? ?}
?? ?//配置中断控制寄存器
?? ?status=XScuGic_CfgInitialize(intc,interConfig,interConfig->CpuBaseAddress);
?? ?if(status!=XST_SUCCESS)
?? ?{
?? ??? ?return XST_FAILURE;
?? ?}
?? ?//InterruptSystemSetup(interConfig);
?? ?//中断异常使能
?? ?Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
?? ??? ??? ?(Xil_ExceptionHandler) XScuGic_InterruptHandler,(void *)intc);
?? ?Xil_ExceptionEnable();
?? ?//链接中断服务函数UartInterrupt_surver
?? ?status = XScuGic_Connect(intc, UART_INT_IRQ_ID,
?? ??? ??? ?( Xil_ExceptionHandler ) XUartPs_InterruptHandler, (void *) &uart_ps);
?? ?XUartPs_SetHandler(&uart_ps,(XUartPs_Handler)uartIntrHandler,&uart_ps);
?? ?//设置中断类型
?? ?XUartPs_SetInterruptMask(&uart_ps,XUARTPS_IXR_TOUT);
?? ?//使能uart中断
?? ?XScuGic_Enable(intc,UART_INT_IRQ_ID);
?? ?return XST_SUCCESS;
//?? ?while(1);
}
串口初始化函数?
int UART_INIT(void)
{
?? ?int status;
?? ?XUartPs_Config *uart_cfg;
?? ?uart_cfg=XUartPs_LookupConfig(UART_DEVICE_ID);
?? ?if(NULL==uart_cfg)
?? ??? ?return XST_FAILURE;
?? ?status=XUartPs_CfgInitialize(&uart_ps,uart_cfg,uart_cfg->BaseAddress);
?? ?if(status!=XST_SUCCESS)
?? ??? ?return XST_FAILURE;
?? ?status=XUartPs_SelfTest(&uart_ps);
?? ?if(status!=XST_SUCCESS)
?? ??? ?return XST_FAILURE;
?? ?//设置工作模式,正常模式
?? ?XUartPs_SetOperMode(&uart_ps,XUARTPS_OPER_MODE_NORMAL);
?? ?//设置波特率率
?? ?XUartPs_SetBaudRate(&uart_ps,115200);
?? ?//设置RxFIFO的中断溢出时间 5个周期
?? ?XUartPs_SetRecvTimeout(&uart_ps,5);
?? ?XUartPs_Recv(&uart_ps,rxbuf,32);
?? ?XUartPs_EnableUart(&uart_ps);
?? ?return XST_SUCCESS;
}
void uartIntrHandler(void *callback_ref,u32 Event,u32 EventData)
{
?? ?XUartPs *uart_instance=(XUartPs *) callback_ref;
?? ?if(Event==XUARTPS_EVENT_RECV_TOUT)
?? ?{
?? ??? ?XUartPs_Recv(&uart_ps,rxbuf,32);
?? ??? ?XUartPs_Send(&uart_ps,rxbuf,EventData);
????????}
?? ??? ?XUartPs_WriteReg(uart_instance->Config.BaseAddress,XUARTPS_ISR_OFFSET,XUARTPS_IXR_RXOVR);
?? ?}
变量声明
XUartPs uart_ps;
u8 rxbuf[32];
#define UART_DEVICE_ID XPAR_XUARTPS_0_DEVICE_ID
#define ?UART_Interrupt_ID XPAR_SCUGIC_SINGLE_DEVICE_ID
#define UART_INT_IRQ_ID XPAR_XUARTPS_1_INTR
|