刚接触 zynq 网上资料也很少,整起来也比较难受。ps、pl 还有SDK。这些东西第一次用都得了解。如果你是个arm工程师,PL部分可以不用怎么了解,只要学习简单的新建硬件流就可以了。主要学习使用的是SDK。在使用方面还得对SDK进行一些配置。
所以记录自己学习zynq的过程。开发板用的是黑金的。下面开始吧!!!!
XScuGic Intc // 中断
XUartPs Uart_PS; //uart
int usart_init(void)
{
int Status;
XUartPs_Config *Config;
Config = XUartPs_LookupConfig( XPAR_XUARTPS_0_DEVICE_ID);
if (NULL == Config)
{
return XST_FAILURE;
}
Status = XUartPs_CfgInitialize(&Uart_PS, Config, Config->BaseAddress);
if (Status != XST_SUCCESS)
{
return XST_FAILURE;
}
Status = XUartPs_SelfTest(&Uart_PS); //UART设备自检
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/* Use Normal mode. */
XUartPs_SetOperMode(&Uart_PS, XUARTPS_OPER_MODE_NORMAL);
/* Set uart mode Baud Rate 115200, 8bits, no parity, 1 stop bit */
XUartPs_SetDataFormat(&Uart_PS, &UartFormat) ; //设置帧格式,波特率,停止位······
#if 1 // 不使用中断
XUartPs_SetRecvTimeout(&Uart_PS, 8);
XUartPs_SetFifoThreshold(&Uart_PS,1) ;//FIFO中断触发字节 为1
XUartPs_SetInterruptMask(&Uart_PS,XUARTPS_IXR_RXOVR|XUARTPS_IXR_TOUT|XUARTPS_IXR_TXEMPTY); // 设置UART的中断触发方式
#endif
return XST_SUCCESS;
}
/*
XScuGic *Intc 把开头声明的 XScuGic Intc变量传进去配置,
u16 DeviveID 传入配置的驱动参数所在的序号
*/
int Inter_System(XScuGic *Intc,u16 DeviveID)
{
int Status=0;
XScuGic_Config *IntcConfig;
IntcConfig = XScuGic_LookupConfig(DeviveID);
Status = XScuGic_CfgInitialize(Intc, IntcConfig, IntcConfig->CpuBaseAddress) ;
if (Status != XST_SUCCESS)
return XST_FAILURE ;
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, //中断异常配置
(Xil_ExceptionHandler)XScuGic_InterruptHandler,(void*)Intc);
Xil_ExceptionEnable(); //Enable GIC
Status=XScuGic_Connect(Intc, XPS_UART1_INT_ID,(Xil_InterruptHandler) Handler,(void *)&Uart_PS);//绑定中断函数与串口
if (Status != XST_SUCCESS)
{
return XST_FAILURE ;
}
XScuGic_Enable(Intc, XPS_UART1_INT_ID);
/*Set receiver FIFO interrupt trigger level, here set to 1*/
return XST_SUCCESS;
}
1、在中断触发方式中,我们虽然没有配置 发送空中断这个模式。但是如果使用发送函数XUartPs_Send函数,会触发发送空中断。所在在中断函数中要清除发送空中断标志位!
2、在串口初始化时,我们配置了接收超时。在中断函数中也可以看到接收超时中断。是为了接收不定长数据用的。
void Handler(void *CallBackRef)
{
XUartPs *UartInstancePtr = (XUartPs *) CallBackRef ;
u32 ReceivedCount = 0 ;
u32 IsrStatus ;
//读取中断ID寄存器,判断触发的是哪种中断
IsrStatus = XUartPs_ReadReg(UartInstancePtr->Config.BaseAddress,
XUARTPS_IMR_OFFSET);
IsrStatus &= XUartPs_ReadReg(UartInstancePtr->Config.BaseAddress,
XUARTPS_ISR_OFFSET);
if (IsrStatus & (u32)XUARTPS_IXR_RXOVR) /* 检查RxFIFO是否触发 */
{
XUartPs_WriteReg(UartInstancePtr->Config.BaseAddress, XUARTPS_ISR_OFFSET, XUARTPS_IXR_RXOVR) ;/* 清除中断标志 */
ReceivedCount=XUartPs_Recv(UartInstancePtr, &RecvBufferPtr[TotalRecvCnt],500) ;
TotalRecvCnt+=ReceivedCount;
}else if(IsrStatus & (u32)XUARTPS_IXR_TOUT)
{
XUartPs_WriteReg(UartInstancePtr->Config.BaseAddress, XUARTPS_ISR_OFFSET, XUARTPS_IXR_TOUT) ;//清中断 接收超时中断
ReceivedCount=XUartPs_Recv(UartInstancePtr, &RecvBufferPtr[TotalRecvCnt], 500) ;
TotalRecvCnt+=ReceivedCount;
Uart_Send(RecvBufferPtr,50);
TotalRecvCnt=0;
memset(RecvBufferPtr,0,100);
}else if(IsrStatus &(u32)XUARTPS_IXR_TXEMPTY)
{
XUartPs_WriteReg(UartInstancePtr->Config.BaseAddress, XUARTPS_ISR_OFFSET, XUARTPS_IXR_TXEMPTY) ;
}
}
这部分代码是公共的,以后全部的中断都用我在开始申明的变量 XScuGic Intc。不能分开配置,否则配置不成功。
XScuGic_Config *IntcConfig;
IntcConfig = XScuGic_LookupConfig(DeviveID);
Status = XScuGic_CfgInitialize(Intc, IntcConfig, IntcConfig->CpuBaseAddress) ;
if (Status != XST_SUCCESS)
return XST_FAILURE ;
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, //中断异常配置
(Xil_ExceptionHandler)XScuGic_InterruptHandler,(void*)Intc);
Xil_ExceptionEnable(); //Enable GIC