一,vivado工程搭建
1,共享中断配置

2,vivado工程效果

二,SDK给PS串口发数据
1,第一种不使用中断
(1)uart_intr.h和uart_intr.c
1,UART_Intr.h
#ifndef SRC_UART_INTR_H_
#define SRC_UART_INTR_H_
#include "xparameters.h"
#include "xuartps.h"
#include "xil_printf.h"
#include "sleep.h"
#define UART_DEVICE_ID XPAR_XUARTPS_0_DEVICE_ID
int Uart_Send(XUartPs* Uart_Ps, u8 *sendbuf, int length);
int Uart_Init(XUartPs* Uart_Ps, u16 DeviceId);
#endif
2,UART_Intr.c
#include "UART_Intr.h"
// UART格式
XUartPsFormat uart_format =
{
9600,
//XUARTPS_DFT_BAUDRATE, //默认波特率 115200
XUARTPS_FORMAT_8_BITS,
XUARTPS_FORMAT_NO_PARITY,
XUARTPS_FORMAT_1_STOP_BIT,
};
//--------------------------------------------------------------
// UART初始化函数
//--------------------------------------------------------------
int Uart_Init(XUartPs* Uart_Ps, u16 DeviceId)
{
int Status;
XUartPs_Config *Config;
/* 初始化UART设备 */
Config = XUartPs_LookupConfig(DeviceId);
if (NULL == Config)
{
return XST_FAILURE;
}
Status = XUartPs_CfgInitialize(Uart_Ps, Config, Config->BaseAddress);
if (Status != XST_SUCCESS)
{
return XST_FAILURE;
}
/* UART设备自检 */
Status = XUartPs_SelfTest(Uart_Ps);
if (Status != XST_SUCCESS)
{
return XST_FAILURE;
}
/* 设置UART模式与参数 */
XUartPs_SetOperMode(Uart_Ps, XUARTPS_OPER_MODE_NORMAL); //正常模式
XUartPs_SetDataFormat(Uart_Ps, &uart_format); //设置UART格式
return XST_SUCCESS;
}
int Uart_Send(XUartPs* Uart_Ps, u8 *sendbuf, int length)
{
int SentCount = 0;
while (SentCount < length)
{
SentCount += XUartPs_Send(Uart_Ps, &sendbuf[SentCount], 1);
}
return SentCount;
}
(2)主函数
#include "UART_Intr.h"
XUartPs Uart_Ps; /* The instance of the UART Driver */
int main(void)
{
int Status;
u8 sendbuf[]={0xEB,0x90,0x0A,0x00,0x00,0x0A,0x99,0x01,0x03,0x05,0x01};
/* 串口初始化 */
Status = Uart_Init(&Uart_Ps, UART_DEVICE_ID);
if (Status == XST_FAILURE)
{
xil_printf("Uartps Failed\r\n");
return XST_FAILURE;
}
while (1)
{
sleep(1);
Uart_Send(&Uart_Ps, sendbuf, 14);
}
return Status;
}
2,第二种,使用中断号检测中断
(1)头文件uart_paramter.h
#ifndef UART_PARAMETER_H_
#define UART_PARAMETER_H_
#include "xuartps.h"
u8 TxString[14] =
{
"Hello world!\r\n"
};
XUartPsFormat UartFormat =
{
115200,
XUARTPS_FORMAT_8_BITS,
XUARTPS_FORMAT_NO_PARITY,
XUARTPS_FORMAT_1_STOP_BIT
};
#endif (2)主函数
#include "xparameters.h"
#include <stdio.h>
#include "xil_printf.h"
#include "sleep.h"
#include "xscugic.h"
#include "uart_parameter.h"
#define UART_DEVICE_ID XPAR_XUARTPS_0_DEVICE_ID
#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID
#define UART_INT_IRQ_ID XPAR_XUARTPS_1_INTR
/* Statement */
#define UART_TX 0
#define UART_RXCHECK 1
#define UART_WAIT 2
/* maximum receiver length */
#define MAX_LEN 2000
/************************** Variable Definitions *****************************/
XUartPs Uart_PS; //Instance of the UART Device
XScuGic IntcInstPtr ;
/* UART receiver buffer */
u8 ReceivedBuffer[MAX_LEN] ;
/* UART receiver buffer pointer*/
u8 *ReceivedBufferPtr ;
/* UART receiver byte number */
volatile u32 ReceivedByteNum ;
volatile u32 ReceivedFlag ;
int UartPsSend(XUartPs *InstancePtr, u8 *BufferPtr, u32 NumBytes) ;
int UartPsRev (XUartPs *InstancePtr, u8 *BufferPtr, u32 NumBytes) ;
int SetupInterruptSystem(XScuGic *IntcInstancePtr, XUartPs *UartInstancePtr, u16 UartIntrId);
void Handler(void *CallBackRef);
int main(void)
{
int Status;
XUartPs_Config *Config;
u32 SendByteNum ;
u8 *SendBufferPtr ;
u8 state = UART_TX ;
ReceivedBufferPtr = ReceivedBuffer ;
ReceivedFlag = 0 ;
ReceivedByteNum = 0 ;
Config = XUartPs_LookupConfig(UART_DEVICE_ID);
if (NULL == Config)
{
return XST_FAILURE;
}
Status = XUartPs_CfgInitialize(&Uart_PS, Config, Config->BaseAddress);
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) ;
/*Set receiver FIFO interrupt trigger level, here set to 1*/
XUartPs_SetFifoThreshold(&Uart_PS,1) ;
/* Enable the receive FIFO trigger level interrupt and empty interrupt for the device */
XUartPs_SetInterruptMask(&Uart_PS,XUARTPS_IXR_RXOVR|XUARTPS_IXR_RXEMPTY);
SetupInterruptSystem(&IntcInstPtr, &Uart_PS, UART_INT_IRQ_ID) ;
while(1)
{
switch(state)
{
case UART_TX : /* Send string to pc */
{
SendBufferPtr = TxString ;
SendByteNum = sizeof(TxString) ;
//UartPsSend(&Uart_PS, SendBufferPtr, SendByteNum);
state = UART_RXCHECK ;
break ;
}
case UART_RXCHECK : /* Check receiver flag, send received data */
{
if (ReceivedFlag)
{
/* Reset receiver pointer, flag, byte number */
ReceivedBufferPtr = ReceivedBuffer ;
SendBufferPtr = ReceivedBuffer ;
SendByteNum = ReceivedByteNum ;
ReceivedFlag = 0 ;
ReceivedByteNum = 0 ;
//-----------------------------
uint8_t abc[8]={0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88};
UartPsSend(&Uart_PS, abc, 8);
//UartPsSend(&Uart_PS, SendBufferPtr, SendByteNum);
}
else
{
state = UART_WAIT ;
}
break ;
}
case UART_WAIT : /* Wait for 1s */
{
sleep(1) ;
state = UART_TX ;
break ;
}
default : break ;
}
}
}
int SetupInterruptSystem(XScuGic *IntcInstancePtr, XUartPs *UartInstancePtr, u16 UartIntrId)
{
int Status;
/* Configuration for interrupt controller */
XScuGic_Config *IntcConfig;
/* Initialize the interrupt controller driver */
IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
if (NULL == IntcConfig)
{
return XST_FAILURE;
}
Status = XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig,IntcConfig->CpuBaseAddress);
if (Status != XST_SUCCESS)
{
return XST_FAILURE;
}
/*
* Connect the interrupt controller interrupt handler to the
* hardware interrupt handling logic in the processor.
*/
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,(Xil_ExceptionHandler) XScuGic_InterruptHandler,IntcInstancePtr);
Status = XScuGic_Connect(IntcInstancePtr, UartIntrId,(Xil_ExceptionHandler) Handler,(void *) UartInstancePtr);
if (Status != XST_SUCCESS)
{
return XST_FAILURE;
}
XScuGic_Enable(IntcInstancePtr, UartIntrId);
Xil_ExceptionEnable();
return Status ;
}
void Handler(void *CallBackRef)
{
XUartPs *UartInstancePtr = (XUartPs *) CallBackRef ;
u32 ReceivedCount = 0 ;
u32 UartSrValue ;
UartSrValue = XUartPs_ReadReg(UartInstancePtr->Config.BaseAddress, XUARTPS_SR_OFFSET) & (XUARTPS_IXR_RXOVR|XUARTPS_IXR_RXEMPTY);
ReceivedFlag = 0 ;
if (UartSrValue & XUARTPS_IXR_RXOVR) /* check if receiver FIFO trigger */
{
ReceivedCount = UartPsRev(&Uart_PS, ReceivedBufferPtr, MAX_LEN) ;
ReceivedByteNum += ReceivedCount ;
ReceivedBufferPtr += ReceivedCount ;
/* clear trigger interrupt */
XUartPs_WriteReg(UartInstancePtr->Config.BaseAddress, XUARTPS_ISR_OFFSET, XUARTPS_IXR_RXOVR) ;
}
else if (UartSrValue & XUARTPS_IXR_RXEMPTY) //check if receiver FIFO empty
{
/* clear empty interrupt */
XUartPs_WriteReg(UartInstancePtr->Config.BaseAddress, XUARTPS_ISR_OFFSET, XUARTPS_IXR_RXEMPTY) ;
ReceivedFlag = 1 ;
}
}
int UartPsSend(XUartPs *InstancePtr, u8 *BufferPtr, u32 NumBytes)
{
u32 SentCount = 0U;
/* Setup the buffer parameters */
InstancePtr->SendBuffer.RequestedBytes = NumBytes;
InstancePtr->SendBuffer.RemainingBytes = NumBytes;
InstancePtr->SendBuffer.NextBytePtr = BufferPtr;
while (InstancePtr->SendBuffer.RemainingBytes > SentCount)
{
/* Fill the FIFO from the buffer */
if (!XUartPs_IsTransmitFull(InstancePtr->Config.BaseAddress))
{
XUartPs_WriteReg(InstancePtr->Config.BaseAddress,XUARTPS_FIFO_OFFSET,((u32)InstancePtr->SendBuffer.NextBytePtr[SentCount]));
/* Increment the send count. */
SentCount++;
}
}
/* Update the buffer to reflect the bytes that were sent from it */
InstancePtr->SendBuffer.NextBytePtr += SentCount;
InstancePtr->SendBuffer.RemainingBytes -= SentCount;
return SentCount;
}
int UartPsRev(XUartPs *InstancePtr, u8 *BufferPtr, u32 NumBytes)
{
u32 ReceivedCount = 0;
u32 CsrRegister;
/* Setup the buffer parameters */
InstancePtr->ReceiveBuffer.RequestedBytes = NumBytes;
InstancePtr->ReceiveBuffer.RemainingBytes = NumBytes;
InstancePtr->ReceiveBuffer.NextBytePtr = BufferPtr;
/*
* Read the Channel Status Register to determine if there is any data in
* the RX FIFO
*/
CsrRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress,
XUARTPS_SR_OFFSET);
/*
* Loop until there is no more data in RX FIFO or the specified
* number of bytes has been received
*/
while((ReceivedCount < InstancePtr->ReceiveBuffer.RemainingBytes)&&
(((CsrRegister & XUARTPS_SR_RXEMPTY) == (u32)0)))
{
InstancePtr->ReceiveBuffer.NextBytePtr[ReceivedCount] =
XUartPs_ReadReg(InstancePtr->Config.BaseAddress,XUARTPS_FIFO_OFFSET);
ReceivedCount++;
CsrRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress,XUARTPS_SR_OFFSET);
}
InstancePtr->is_rxbs_error = 0;
/*
* Update the receive buffer to reflect the number of bytes just
* received
*/
if(InstancePtr->ReceiveBuffer.NextBytePtr != NULL)
{
InstancePtr->ReceiveBuffer.NextBytePtr += ReceivedCount;
}
InstancePtr->ReceiveBuffer.RemainingBytes -= ReceivedCount;
return ReceivedCount;
}
3,比较复杂的一种带中断的写法
(1)uartps_intr.h和uart_intr.c
1,uartps_intr.h
#ifndef UARTPS_INTR_H_
#define UARTPS_INTR_H_
#include "xparameters.h"
#include "xplatform_info.h"
#include "xuartps.h"
#include "xil_exception.h"
#include "xil_printf.h"
#include "xscugic.h"
int Init_UartPsIntr(XUartPs *UartInstPtr,u16 DeviceId);
int UartPs_Setup_IntrSystem(XScuGic *IntcInstancePtr,XUartPs *UartInstancePtr,u16 UartIntrId);
void UartPs_Intr_Handler(void *CallBackRef, u32 Event, unsigned int EventData);
#define UART_DEVICE_ID XPAR_XUARTPS_0_DEVICE_ID
#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID
#define UART_INT_IRQ_ID XPAR_XUARTPS_1_INTR
#define TEST_BUFFER_SIZE 10
XUartPs UartPs;//uart
static u8 SendBuffer[TEST_BUFFER_SIZE]; /* Buffer for Transmitting Data */
static u8 RecvBuffer[TEST_BUFFER_SIZE]; /* Buffer for Receiving Data */
volatile int TotalReceivedCount;
volatile int TotalSentCount;
int TotalErrorCount;
#endif /* SRC_UARTPS_INTR_H_ */
2,uartps_intr.c
#include "uartps_intr.h"
int Init_UartPsIntr(XUartPs *UartInstPtr,u16 DeviceId )
{
int Status;
XUartPs_Config *Config;
u32 IntrMask;
if (XGetPlatform_Info() == XPLAT_ZYNQ_ULTRA_MP)
{
#ifdef XPAR_XUARTPS_1_DEVICE_ID
DeviceId = XPAR_XUARTPS_1_DEVICE_ID;
#endif
}
Config = XUartPs_LookupConfig(DeviceId);
if (NULL == Config)
{
return XST_FAILURE;
}
Status = XUartPs_CfgInitialize(UartInstPtr, Config, Config->BaseAddress);
if (Status != XST_SUCCESS)
{
return XST_FAILURE;
}
/* Setup the handlers for the UART that will be called from the
* interrupt context when data has been sent and received, specify
* a pointer to the UART driver instance as the callback reference
* so the handlers are able to access the instance data*/
XUartPs_SetHandler(UartInstPtr, (XUartPs_Handler)UartPs_Intr_Handler, UartInstPtr);
/*
* Enable the interrupt of the UART so interrupts will occur, setup
* a local loopback so data that is sent will be received.
*/
IntrMask =
XUARTPS_IXR_TOUT | XUARTPS_IXR_PARITY | XUARTPS_IXR_FRAMING |
XUARTPS_IXR_OVER | XUARTPS_IXR_TXEMPTY | XUARTPS_IXR_RXFULL |
XUARTPS_IXR_RXOVR;
if (UartInstPtr->Platform == XPLAT_ZYNQ_ULTRA_MP)
{
IntrMask |= XUARTPS_IXR_RBRK;
}
XUartPs_SetInterruptMask(UartInstPtr, IntrMask);
XUartPs_SetRecvTimeout(UartInstPtr, 8);
return XST_SUCCESS;
}
void UartPs_Intr_Handler(void *CallBackRef, u32 Event, unsigned int EventData)
{
int i = 0;
/* All of the data has been sent */
if (Event == XUARTPS_EVENT_SENT_DATA)
{
TotalSentCount = EventData;
}
/* All of the data has been received */
if (Event == XUARTPS_EVENT_RECV_DATA)
{
TotalReceivedCount = EventData;
if(TotalReceivedCount == TEST_BUFFER_SIZE)
{
for(i=0;i<TotalReceivedCount;i++)
{
SendBuffer[i] = RecvBuffer[i];
}
XUartPs_Send(&UartPs, SendBuffer, TotalReceivedCount);
XUartPs_Recv(&UartPs, RecvBuffer, TEST_BUFFER_SIZE);
TotalReceivedCount=0;
}
}
/*
* Data was received, but not the expected number of bytes, a
* timeout just indicates the data stopped for 8 character times
*/
if (Event == XUARTPS_EVENT_RECV_TOUT)
{
TotalReceivedCount = EventData;
for(i=0;i<TotalReceivedCount;i++)
{
SendBuffer[i] = RecvBuffer[i];
}
XUartPs_Send(&UartPs, SendBuffer, TotalReceivedCount);
XUartPs_Recv(&UartPs, RecvBuffer, TEST_BUFFER_SIZE);
TotalReceivedCount=0;
}
/*
* Data was received with an error, keep the data but determine
* what kind of errors occurred
*/
if (Event == XUARTPS_EVENT_RECV_ERROR)
{
TotalReceivedCount = EventData;
TotalErrorCount++;
}
/* Data was received with an parity or frame or break error, keep the data
* but determine what kind of errors occurred. Specific to Zynq Ultrascale+
* MP.*/
if (Event == XUARTPS_EVENT_PARE_FRAME_BRKE)
{
TotalReceivedCount = EventData;
TotalErrorCount++;
}
/*
* Data was received with an overrun error, keep the data but determine
* what kind of errors occurred. Specific to Zynq Ultrascale+ MP.
*/
if (Event == XUARTPS_EVENT_RECV_ORERR)
{
TotalReceivedCount = EventData;
TotalErrorCount++;
}
}
int UartPs_Setup_IntrSystem(XScuGic *IntcInstancePtr,XUartPs *UartInstancePtr,u16 UartIntrId)
{
int Status;
XScuGic_Config *IntcConfig; /* Config for interrupt controller */
/* Initialize the interrupt controller driver */
IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
if (NULL == IntcConfig)
{
return XST_FAILURE;
}
Status = XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig,IntcConfig->CpuBaseAddress);
if (Status != XST_SUCCESS)
{
return XST_FAILURE;
}
/*
* interrupt for the device occurs, the device driver handler
* performs the specific interrupt processing for the device
*/
Status = XScuGic_Connect(IntcInstancePtr, UartIntrId,
(Xil_ExceptionHandler) XUartPs_InterruptHandler,(void *) UartInstancePtr);
if (Status != XST_SUCCESS)
{
return XST_FAILURE;
}(2)sys_intr.h和sys_intr.c
#ifndef SYS_INTR_H_
#define SYS_INTR_H_
#include "xparameters.h"
#include "xil_exception.h"
#include "xdebug.h"
#include "xscugic.h"
#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID
XScuGic Intc; //GIC
int Init_Intr_System(XScuGic * IntcInstancePtr);
void Setup_Intr_Exception(XScuGic * IntcInstancePtr);
#endif
#include "sys_intr.h"
void Setup_Intr_Exception(XScuGic * IntcInstancePtr)
{
//从硬件使能中断
Xil_ExceptionInit();
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler)XScuGic_InterruptHandler,
(void *)IntcInstancePtr);
Xil_ExceptionEnable();
}
int Init_Intr_System(XScuGic * IntcInstancePtr)
{
int Status;
XScuGic_Config *IntcConfig;
IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
if (NULL == IntcConfig)
{
return XST_FAILURE;
}
Status = XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig,IntcConfig->CpuBaseAddress);
if (Status != XST_SUCCESS)
{
return XST_FAILURE;
}
return XST_SUCCESS;
}(3)主函数
#include "sys_intr.h"
#include "uartps_intr.h"
void init_intr_sys(void)
{
Init_UartPsIntr(&UartPs,UART_DEVICE_ID);
Init_Intr_System(&Intc);
Setup_Intr_Exception(&Intc);
UartPs_Setup_IntrSystem(&Intc, &UartPs, UART_INT_IRQ_ID);
}
int main(void)
{
init_intr_sys();
XUartPs_Recv(&UartPs, RecvBuffer, TEST_BUFFER_SIZE);
while(1);
return 0;
}三,SDK给PL axi_uartlitle串口发数据执行流程
1,PL串口把收到的数据回发,不加中断
#include "xuartlite.h"
#include "xparameters.h"
#include "sleep.h"
#include "xil_printf.h"
#include "string.h"
int main()
{
//实例化xuart2
XUartLite xuart2;//uart对象
//查找uart配置
XUartLite_Config *XUARTConfigPtr;
XUARTConfigPtr = XUartLite_LookupConfig(XPAR_UARTLITE_0_DEVICE_ID);//ID来源于xparameters.h
if (XUARTConfigPtr == NULL)
{
//在bsp中设置为uartlite0负责stdout
//print("failed XUartlite_LookupConfig\n\r");
return XST_FAILURE;
}
else
{
//print("succeed XUartlite_LookupConfig\n\r");
}
//uart初始化
int Status;
Status = XUartLite_Initialize(&xuart2, XPAR_UARTLITE_0_DEVICE_ID);
if (Status != XST_SUCCESS)
{
return XST_FAILURE;
}
//接收缓冲
u8 buf[64]={0x55,0x55,0x55,0x55,0x55};
u8 buf2[64]={0};
//接收字节数
u32 recv_cnt = 0;
while (TRUE)
{
usleep(500000);//等待500ms
recv_cnt = XUartLite_Recv(&xuart2, buf2, 64);//接收数据
if(recv_cnt>0)
{
XUartLite_Send(&xuart2, buf2,recv_cnt);
memset(buf2, 0, 64);
recv_cnt = 0;
}
}
return 0;
}2,使用中断号触发,从SDK空工程把串口号切换到PL串口
#include "stdio.h"
#include "xil_printf.h"
#include "xparameters.h"
#include "sleep.h"
#include "xuartlite.h"
#include "xuartlite_i.h"
#include "xscugic.h"
///xxx#include "xuartps.h"
#define SEND_BUFF_SIZE 128
#define RECV_BUFF_SIZE 1
//函数声明
void ScuGic_UartLite_handle(void *CallbackRef);
void SendENDHandle(void *CallbackRef,unsigned int ByteCount);
void RecvENDHandle(void *CallbackRef,unsigned int ByteCount);
//全局变量
XScuGic scugic_inst;
XScuGic_Config *scugic_cfg_ptr;
XUartLite PL_Extend_Uart_inst;
unsigned char SendBuff[SEND_BUFF_SIZE]={"FUCK THE WORLD ONCE,FUCK THE WORLD TWICE\r\n"};
unsigned char RecvBuff[RECV_BUFF_SIZE]={0};
unsigned int recvcount=0;
int main()
{
unsigned int state = 0;
//初始化实例
//state = XUartLite_Initialize( &PL_Extend_Uart_inst , XPAR_UARTLITE_0_DEVICE_ID );
state = XUartLite_Initialize( &PL_Extend_Uart_inst , XPAR_XUARTPS_0_DEVICE_ID );
xil_printf("initialize state=%d\r\n",state);
//设置发送buffer结束或接收buffer结束时的处理函数
XUartLite_SetSendHandler( &PL_Extend_Uart_inst, SendENDHandle, &PL_Extend_Uart_inst );
XUartLite_SetRecvHandler( &PL_Extend_Uart_inst, RecvENDHandle, &PL_Extend_Uart_inst );
PL_Extend_Uart_inst.ReceiveBuffer.NextBytePtr = RecvBuff;
PL_Extend_Uart_inst.ReceiveBuffer.RemainingBytes = RECV_BUFF_SIZE;
//自检
state = XUartLite_SelfTest( &PL_Extend_Uart_inst );
xil_printf("selftest state=%d\r\n",state);
//串口使能中断
XUartLite_EnableInterrupt( &PL_Extend_Uart_inst );
//scugic中断控制器初始化
scugic_cfg_ptr = XScuGic_LookupConfig( XPAR_PS7_SCUGIC_0_DEVICE_ID );
XScuGic_CfgInitialize( &scugic_inst,scugic_cfg_ptr,scugic_cfg_ptr->CpuBaseAddress );
//设置优先级,中断触发类型
XScuGic_SetPriorityTriggerType( &scugic_inst , XPAR_FABRIC_UARTLITE_0_VEC_ID , 0x0a , 0x03 );
//将中断ID与中断处理函数相关联
XScuGic_Connect( &scugic_inst,XPAR_FABRIC_UARTLITE_0_VEC_ID,ScuGic_UartLite_handle,&PL_Extend_Uart_inst );
//使能AXI_GPIO中断
XScuGic_Enable( &scugic_inst,XPAR_FABRIC_UARTLITE_0_VEC_ID );
//设置并打开中断异常处理功能
Xil_ExceptionInit();
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,(Xil_ExceptionHandler)XScuGic_InterruptHandler, &scugic_inst);
Xil_ExceptionEnable();
//xil_printf("len=%d\r\n",strlen((char *)SendBuff));
while(1)
{
//将buffer中的数据全发送出去
//XUartLite_Send( &PL_Extend_Uart_inst,SendBuff,strlen((char *)SendBuff));
sleep(1);
//xil_printf("RemainingBytes=%d\r\n",PL_Extend_Uart_inst.SendBuffer.RemainingBytes);
state = XUartLite_ReadReg(PL_Extend_Uart_inst.RegBaseAddress,XUL_STATUS_REG_OFFSET);
xil_printf("state=%d recvcount=%d\r",state,recvcount);
XUartLite_Send( &PL_Extend_Uart_inst,RecvBuff,strlen((char *)RecvBuff));
sleep(1);
}
return 0;
}
//该函数内部最好不要放打印函数,因为打印函数速度慢,会导致接收异常
void ScuGic_UartLite_handle(void *CallbackRef)
{
//xil_printf("enter intr\r\n");
XUartLite_InterruptHandler( &PL_Extend_Uart_inst );
}
//该函数内部最好不要放打印函数,尤其是需要使用扩展串口向外传输大量连续数据的时候,因为打印函数速度慢,会导致发送异常
void SendENDHandle(void *CallbackRef,unsigned int ByteCount)
{
xil_printf("send end\r\n");
}
//该函数内部最好不要放打印函数,因为打印函数速度慢,会导致接收异常
void RecvENDHandle(void *CallbackRef,unsigned int ByteCount)
{
recvcount++;
xil_printf( "%s\n",RecvBuff );
memset(RecvBuff,0,RECV_BUFF_SIZE);
PL_Extend_Uart_inst.ReceiveBuffer.RemainingBytes = RECV_BUFF_SIZE;
PL_Extend_Uart_inst.ReceiveBuffer.NextBytePtr = RecvBuff;
XUartLite_EnableInterrupt( &PL_Extend_Uart_inst );
}3,INTC带中断控制的方法,从SDK空工程把串口号切换到PL串口,使用microblaze软盒加中断控制器INTC模块
(1)sys_intr.h和sys_intr.c
#ifndef SYS_INTR_H_
#define SYS_INTR_H_
#include "xparameters.h"
#include "xil_exception.h"
#include "xdebug.h"
#include "XIntc.h"
int Init_Intr_System(XIntc * IntcInstancePtr);
void Intc_Enable(XIntc *IntcInstancePtr,u16 Intr_Id);
int Intc_Start(XIntc *IntcInstancePtr);
void setup_Intr_Exception(XIntc * IntcInstancePtr);
#endif
#include "sys_intr.h"
#define INTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID
void Setup_Intr_Exception(XIntc * IntcInstancePtr)
{
/* Enable interrupts from the hardware */
Xil_ExceptionInit();
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler)XIntc_InterruptHandler,
(void *)IntcInstancePtr);
Xil_ExceptionEnable();
}
int Init_Intr_System(XIntc * IntcInstancePtr)
{
int Status;
Status = XIntc_Initialize(IntcInstancePtr, INTC_DEVICE_ID);
if (Status != XST_SUCCESS)
{
return XST_FAILURE;
}
return XST_SUCCESS;
}
void Intc_Enable(XIntc *IntcInstancePtr,u16 Intr_Id)
{
XIntc_Enable(IntcInstancePtr, Intr_Id);
}
int Intc_Start(XIntc *IntcInstancePtr)
{
int Status = XIntc_Start(IntcInstancePtr, XIN_REAL_MODE);
if(Status != XST_SUCCESS)
{
return XST_FAILURE;
}
return XST_SUCCESS;
}(2)UART_Intr.h和UART_Intr.c
#ifndef SRC_UART_INTR_H_
#define SRC_UART_INTR_H_
#include "xintc.h"
#include "xuartlite.h"
#include "xuartlite_l.h"
void uart_intr_handler(void *CallbackRef);
int Uart_SetupIntrSystem(XIntc* IntcInstancePtr,XUartLite* UartInstancePtr,u16 IntrId);
#endif
#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);
}
}
int Uart_SetupIntrSystem(XIntc* IntcInstancePtr,XUartLite* UartInstancePtr,u16 IntrId)
{
int Status;
Status = XIntc_Connect(IntcInstancePtr, IntrId,(XInterruptHandler)uart_intr_handler,(void *)UartInstancePtr);
if (Status != XST_SUCCESS)
{
return XST_FAILURE;
}
XUartLite_EnableInterrupt(UartInstancePtr);
return XST_SUCCESS;
}(3)主函数
#include "UART_Intr.h"
#include "xparameters.h"
#include "sys_intr.h"
#define UART_DEV_ID XPAR_UARTLITE_0_DEVICE_ID
#define UART_INTR_ID XPAR_INTC_0_UARTLITE_0_VEC_ID
static XIntc Intc; //GIC
static XUartLite Uart;//timer
int main(void)
{
XUartLite_Initialize(&Uart, UART_DEV_ID);
Init_Intr_System(&Intc); // initial DMA interrupt system
Uart_SetupIntrSystem(&Intc,&Uart,UART_INTR_ID);
Intc_Start(&Intc);
Intc_Enable(&Intc,UART_INTR_ID);
Setup_Intr_Exception(&Intc);
while(1);
}4, 使用寄存器方法
(1)功能:AXI-UART模块配置
void AxiUartConfig(void)
{
PsWriteWord(ADDR_INTR_CLEAR, 0);
PsWriteWord(ADDR_INTR_CLEAR, 1);
PsWriteWord(ADDR_INTR_CLEAR, 2);
PsWriteWord(ADDR_INTR_CLEAR, 3);
PsWriteWord(ADDR_INTR_EN, 0xFFFF); // interrupt enable
// TEST_UART TTL
PsWriteWord(ADDR_UART0_RST, 1);
DelayUs(1);
PsWriteWord(ADDR_UART0_RST, 0);
PsWriteWord(ADDR_UART0_BAUD, 52); // 12 = 460800 = 100M / 460800 / 16 - 1
PsWriteWord(ADDR_UART0_PARITY, 0);
PsWriteWord(ADDR_UART0_STOP, 0);
PsWriteWord(ADDR_UART0_EN, 1);
// PL_UART1 RS422
PsWriteWord(ADDR_UART1_RST, 1);
DelayUs(1);
PsWriteWord(ADDR_UART1_RST, 0);
PsWriteWord(ADDR_UART1_BAUD, 52); // 52 = 115200
PsWriteWord(ADDR_UART1_PARITY, 0);
PsWriteWord(ADDR_UART1_STOP, 0);
PsWriteWord(ADDR_UART1_EN, 1);
// PL_UART2 RS422
PsWriteWord(ADDR_UART2_RST, 1);
DelayUs(1);
PsWriteWord(ADDR_UART2_RST, 0);
PsWriteWord(ADDR_UART2_BAUD, 52); // 52 = 115200
PsWriteWord(ADDR_UART2_PARITY, 0);
PsWriteWord(ADDR_UART2_STOP, 0);
PsWriteWord(ADDR_UART2_EN, 1);
}(2)获取串口控制台数据
Uint8 ConsoleAcquireData(int port)
{
Uart_stu *mUart;
Uint8 rXor = 0; // 异或校验码
Uint16 ckSum = 0; // 校验和
uint16_t i;
uint8_t *buf;
comm2upper_stu *comm_pt;
if(port == IF_UART)
{
if(!(Ctl_param.comm2upper.if_sw & uart_enable))
return 0;
mUart = &Ctl_param.uart_console;
Ctl_param.comm2upper.err = 0;
while (mUart->rb.rx_head != mUart->rb.rx_tail )
{
mUart->frm_rx_buf[mUart->frm_rx_idx] = mUart->rb.rx[mUart->rb.rx_tail];
__BUF_INCR(mUart->rb.rx_tail);
mUart->frm_rx_idx++;
switch(mUart->frm_rx_idx)
{
// 长度码
case 1: if(mUart->frm_rx_buf[0] != 0x55)
mUart->frm_rx_idx = 0;
break;
case 2: if(mUart->frm_rx_buf[1] != 0xAA)
mUart->frm_rx_idx = 0;
break;
case 3: if(mUart->frm_rx_buf[2] != 0x01)
mUart->frm_rx_idx = 0;
break;
case 4: if(mUart->frm_rx_buf[3] != 0x36)
mUart->frm_rx_idx = 0;
else
mUart->frm_length = 0x36;
break;
default:
if(mUart->frm_rx_idx == mUart->frm_length) // 数据段读完
{
for(i=2; i<53; i++)//3~52字节求和
{
ckSum += mUart->frm_rx_buf[i];
}
ckSum &= 0xFF; // 取低八位
if(ckSum == mUart->frm_rx_buf[mUart->frm_length - 2] &&
0x0D == mUart->frm_rx_buf[mUart->frm_length - 1]) // success
{
comm_pt = &Ctl_param.comm2upper;
buf = &mUart->frm_rx_buf[0];
comm_pt->load_info.missile_longitude = *(int32_t *)(buf+5);
comm_pt->load_info.latitude = *(int32_t *)(buf+9);
comm_pt->load_info.height = *(int32_t *)(buf+13);
comm_pt->load_info.nVelocity = *(int32_t *)(buf+15);
comm_pt->load_info.sVelocity = *(int32_t *)(buf+17);
comm_pt->load_info.eVelocity = *(int32_t *)(buf+19);
comm_pt->load_info.target_longitude = *(int32_t *)(buf+21);
comm_pt->load_info.target_latitude = *(int32_t *)(buf+25);
comm_pt->load_info.target_height = *(int32_t *)(buf+29);
comm_pt->load_info.pitch = *(int32_t *)(buf+31);
comm_pt->load_info.yaw = *(int32_t *)(buf+33);
comm_pt->load_info.roll = *(int32_t *)(buf+35);
comm_pt->load_info._wx = *(int32_t *)(buf+37) & 0x00FFFFFF;
comm_pt->load_info._wy = *(int32_t *)(buf+40) & 0x00FFFFFF;
comm_pt->load_info._wz = *(int32_t *)(buf+43) & 0x00FFFFFF;
comm_pt->load_info.target_distance = *(int32_t *)(buf+46);
comm_pt->load_info.frm_cnt = *(int32_t *)(buf+50);
mUart->frm_rx_idx = 0;
}
}
break;
}
}
mUart->frm_rx_idx = 0;
mUart->rb.rx_head = 0;
mUart->rb.rx_tail = 0;
版权声明:本文为wangjie36原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。