第一路
RS485
用的是
PS
端的
UART0
主程序流程:
初始化DS485_0 DE->设置MIO 9为输出->使能MIO 9->UART
初始化->设置 UART 模式->设置数据格式->串口中断设置
中断程序流程:
中断初始化->设置接收器FIFO中断触发级别,这里设置为32,
即收到32个数据就中断->设置超时时间->打开RX FIFO触发中断和超时中断->RS485为发送
中断服务程序:
读取中断ID寄存器,判断触发的是哪种中断->清除相应中断->判断数据是否发送完->数据全部发送完,RS485为接收,否则继续发送
代码如下:
/* Definitions for peripheral PS7_GPIO_0 */
//串口器件ID
#define RS485_DEVICE_ID XPAR_PS7_UART_0_DEVICE_ID
#define RS485_INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID//中断的设备ID
#define RS485_UART_INT_IRQ_ID XPAR_XUARTPS_0_INTR//串口的中断号
#define XPAR_PS7_GPIO_0_DEVICE_ID 0
XUartPsFormat UartFormat =
{
9600,
XUARTPS_FORMAT_8_BITS,
XUARTPS_FORMAT_NO_PARITY,
XUARTPS_FORMAT_1_STOP_BIT
};
//串口
int uart_init(void)
{
static int status;
//设置RS485
PsGpioSetup();
//串口初始化
status = uart_config();
//串口中断初始化
uart_intr();
return status;
}
int PsGpioSetup(void)
{
int Status;
/* Initial RS485_0 DE */
XGpioPs_Config *GPIO_CONFIG ;
GPIO_CONFIG = XGpioPs_LookupConfig(XPAR_PS7_GPIO_0_DEVICE_ID) ;
Status = XGpioPs_CfgInitialize(&rs485_0_de, GPIO_CONFIG, GPIO_CONFIG->BaseAddr) ;
if (Status != XST_SUCCESS)
{
return XST_FAILURE ;
}
/* set MIO 9 as output */
XGpioPs_SetDirectionPin(&rs485_0_de, 9, 1) ;
/* enable MIO 9 output */
XGpioPs_SetOutputEnablePin(&rs485_0_de, 9, 1) ;
return XST_SUCCESS ;
}
//串口初始化
int uart_config(void)
{
int Status;
XUartPs_Config *Config;
//根据器件ID查找配置信息
Config = XUartPs_LookupConfig(RS485_DEVICE_ID);
if (NULL == Config) {
return XST_FAILURE;
}
//根据配置信息对PS UART进行初始化
Status = XUartPs_CfgInitialize(&Uart_PS, Config, Config->BaseAddress);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/* Check hardware build./检查硬件搭配是否正确 */
Status = XUartPs_SelfTest(&Uart_PS);
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) ;
return 1;
}
//串口中断初始化
int uart_intr(void)
{
/*Set receiver FIFO interrupt trigger level, here set to 32*/
XUartPs_SetFifoThreshold(&Uart_PS,32);
//超时时间
XUartPs_SetRecvTimeout(&Uart_PS,10);
//RX FIFO trigger interrupt Timeout error interrupt
XUartPs_SetInterruptMask(&Uart_PS,XUARTPS_IXR_RXOVR|XUARTPS_IXR_TOUT);
SetupInterruptSystem(&IntcInstPtr, &Uart_PS, RS485_UART_INT_IRQ_ID) ;
XGpioPs_WritePin(&rs485_0_de, 9, 0) ;
return 2;
}
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(RS485_INTC_DEVICE_ID);
if (NULL == IntcConfig) {
return XST_FAILURE;
}
Status = XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig,
IntcConfig->CpuBaseAddress);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
//设置并打开中断异常处理功能
Xil_ExceptionInit();
/*
* 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 UartSrValue ;
//读取中断ID寄存器,判断触发的是哪种中断
UartSrValue = XUartPs_ReadReg(UartInstancePtr->Config.BaseAddress,XUARTPS_IMR_OFFSET);
UartSrValue &= XUartPs_ReadReg(UartInstancePtr->Config.BaseAddress,XUARTPS_ISR_OFFSET);
if (UartSrValue & XUARTPS_IXR_RXOVR) /* check if receiver FIFO trigger */
{
if(uart.Received_OK == TRUE)
{
XUartPs_WriteReg(UartInstancePtr->Config.BaseAddress,XUARTPS_ISR_OFFSET, XUARTPS_IXR_RXOVR);
XUartPs_WriteReg(UartInstancePtr->Config.BaseAddress,XUARTPS_ISR_OFFSET, XUARTPS_IXR_TOUT) ;
return;
}
/* clear trigger interrupt */
XUartPs_WriteReg(UartInstancePtr->Config.BaseAddress, XUARTPS_ISR_OFFSET, XUARTPS_IXR_RXOVR) ;
uart.rx_realnumber = XUartPs_Recv(&Uart_PS, uart.Buffer_R_temp, 1000) ;
if(uart.rx_totalnumber+uart.rx_realnumber>1000)
{
uart.rx_totalnumber = 0;
return;
}
else
{
memcpy(&uart.RX_buff[uart.rx_totalnumber],uart.Buffer_R_temp,uart.rx_realnumber);
}
uart.rx_totalnumber += uart.rx_realnumber;
}
else if (UartSrValue & (u32)XUARTPS_IXR_TOUT)
{
if(uart.Received_OK == TRUE)
{
XUartPs_WriteReg(UartInstancePtr->Config.BaseAddress,XUARTPS_ISR_OFFSET, XUARTPS_IXR_RXOVR);
XUartPs_WriteReg(UartInstancePtr->Config.BaseAddress,XUARTPS_ISR_OFFSET, XUARTPS_IXR_TOUT) ;
return;
}
//清除中断标志
XUartPs_WriteReg(UartInstancePtr->Config.BaseAddress,XUARTPS_ISR_OFFSET, XUARTPS_IXR_TOUT) ;
uart.rx_realnumber = XUartPs_Recv(&Uart_PS,uart.Buffer_R_temp,1000);
if(uart.rx_totalnumber+uart.rx_realnumber>1000)
{
uart.rx_totalnumber = 0;
return;
}
else
{
memcpy(&uart.RX_buff[uart.rx_totalnumber],uart.Buffer_R_temp,uart.rx_realnumber);
}
uart.rx_totalnumber += uart.rx_realnumber;
uart.whitch_Num_R=uart.rx_totalnumber;
if(uart.whitch_Num_R>1)
{
uart.Received_OK=TRUE;
XGpioPs_WritePin(&rs485_0_de, 9, 1) ;
//接收数据处理
PROTOCOL_Analysis((u8 *)uart.RX_buff,uart.whitch_Num_R);
uart.whitch_Num_R = 0;
uart.Received_OK = FALSE;
}
else
{
XUartPs_EnableUart(&Uart_PS);
}
uart.rx_totalnumber = 0;
}
else if (UartSrValue & (u32)XUARTPS_IXR_TXEMPTY)
{
XUartPs_WriteReg(UartInstancePtr->Config.BaseAddress,XUARTPS_ISR_OFFSET, XUARTPS_IXR_TXEMPTY) ;
u32 rx_cnt=0;
rx_cnt=XUartPs_SendBuffer(&Uart_PS);
// printf("%ld\r\n",rx_cnt);
if(rx_cnt==0)
{
//数据全部发送,485为接收
XGpioPs_WritePin(&rs485_0_de, 9, 0);
}
else
{
}
}
else
{
XUartPs_WriteReg(UartInstancePtr->Config.BaseAddress,XUARTPS_ISR_OFFSET, XUARTPS_IXR_MASK);
}
}