您好,欢迎来到纷纭教育。
搜索
您的当前位置:首页学习ALINX_ZYNQ(7Z020开发板SDK)第二天——RS485串口

学习ALINX_ZYNQ(7Z020开发板SDK)第二天——RS485串口

来源:纷纭教育
第一路 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);
		    }

}

 

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- fenyunshixun.cn 版权所有 湘ICP备2023022495号-9

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务