Skip to content

sdk模板程序:ps_uart_irq

minichao9901 edited this page May 1, 2024 · 1 revision

说明

  • 这个程序是中断程序的框架的典范。由于uart硬件带有接收超时机制,因此非常方便使用。否则一般要构造定时器中断来产生超时。
  • 每一个中断标志位,设置一个Flag变量,在main程序中检测Flag变量,并进行处理。
  • 这个程序可以被用作中断处理程序的典范。
/**
  *****************************************************************************
  * 					存放用户中断处理函数,方便统一处理
  *****************************************************************************
  *
  * @File   : ISR.c
  * @By     : Sun
  * @Version: V0.5
  * @Date   : 2022 / 06 / 01
  * @Shop	: https://xiaomeige.taobao.com/
  *
  *****************************************************************************
**/

#include "ISR.h"

//中断里使用的标志位
volatile int Send_All_Flag = 0;	//全部发送标志
volatile int Recv_All_Flag = 0;	//全部接收标志
volatile int TimeOut_Flag = 0;	//超时标志
/**
  *****************************************************
  * @brief	私有定时器中断处理程序
  * @tag	本函数用来处理私有定时器中断,在内部加入用户程序即可
  *****************************************************
**/
void ScuTimer_IRQ_Handler(void *CallBackRef)
{
	/* ↓↓↓用户处理↓↓↓ */

	/* ↑↑↑结束处理↑↑↑ */
    XScuTimer_ClearInterruptStatus(&ScuTimer);
}

/**
  *****************************************************
  * @brief	私有定时器中断处理程序
  * @tag	本函数用来处理私有定时器中断,在内部加入用户程序即可
  *****************************************************
**/
void ScuF2P_IRQ_Handler(void *CallBackRef)
{
	/* ↓↓↓用户处理↓↓↓ */

	/* ↑↑↑结束处理↑↑↑ */
}


void PS_UART0_IRQ_Handler(void *CallBackRef, uint32_t Event, unsigned int EventData)
{
	//发送完成
	if(Event == XUARTPS_EVENT_SENT_DATA){
		Send_All_Flag = 1;
	}

	//接收完成
	if(Event == XUARTPS_EVENT_RECV_DATA){	//如果中断事件为串口接收中断
		Recv_All_Flag = 1;
	}

	//超时
	if(Event == XUARTPS_EVENT_RECV_TOUT){
		TimeOut_Flag = 1;
	}

}
#include "ACZ702_Lib/COMMON.h"

uint8_t Receive_Buffer[10];

int main(void)
{
	uint8_t Data[10];
	uint32_t Timeout;
	uint8_t i;

	//开启通用中断控制器
	ScuGic_Init();

	//初始化AXI_UART
	//AXI_UartLite_Init(&AXI_UART0, XPAR_AXI_UARTLITE_0_DEVICE_ID);
	PS_UART_Init(&UartPs1,XPAR_PS7_UART_0_DEVICE_ID, XUARTPS_OPER_MODE_NORMAL, 115200);

	//初始化AXI_UART中断
	//AXI_UARTLite_Intr_Init(&AXI_UART0, XPAR_FABRIC_AXI_UARTLITE_0_INTERRUPT_INTR,
	//		AXI_UART0_Send_IRQ_Handler,AXI_UART0_Recv_IRQ_Handler);
	PS_UART_Intr_Init(&UartPs1, PS_UART0_IRQ_ID, 8, (void *)PS_UART0_IRQ_Handler);

	//UART发送
	//AXI_UARTLite_SendString(&AXI_UART0,"00 01 02 03 04 05 06 07 08 09 10 "
	//		"11 12 13 14 15 16 17 18 19 20 21 22 23 24 25\n");
	PS_Uart_SendString(&UartPs1,"00 01 02 03 04 05 06 07 08 09 10 "
			"11 12 13 14 15 16 17 18 19 20 21 22 23 24 25\n");

	//等待上一轮发送完成
	while(!Send_All_Flag);
	Send_All_Flag = 0;

	//AXI_UARTLite_SendString(&AXI_UART0,"UART send done!!!\n");
	PS_Uart_SendString(&UartPs1,"UART send done!!!\n");

	//等待上一轮发送完成
	while(!Send_All_Flag);
	Send_All_Flag = 0;

	while(1) {
		//UART接收10个字符
		//AXI_UARTLite_RecvData(&AXI_UART0, Receive_Buffer, 10);
		PS_Uart_RecvData(&UartPs1, Receive_Buffer, 10);

		//等待10字节接收完成或接收超时
		while(!(Recv_All_Flag || TimeOut_Flag));

		if(Recv_All_Flag) {
			//清除接收完成标志
			Recv_All_Flag = 0;

			//处理接受到的数据,帧头'S' 帧尾'E',中间有效数据长度为8字节
			if((Receive_Buffer[0] == 'S') && (Receive_Buffer[9] == 'E')) {
				for(i=0;i<8;i++) {
					Data[i] = Receive_Buffer[i+1];
				}

				for(i=0;i<10; i++){/*重复发送10遍*/
					//回发8位有效数据
					//XUartLite_Send(&AXI_UART0,Data,8);
					XUartPs_Send(&UartPs1,Data,8);

					//换行
					//AXI_UARTLite_SendString(&AXI_UART0,"\n");
					PS_Uart_SendString(&UartPs1,"\n");
					while(!Send_All_Flag);
					Send_All_Flag = 0;
				}
			}
		}

		//接收超时则重新接收
		if(TimeOut_Flag) {
			//清除接收超时标志
			TimeOut_Flag = 0;
		}
	}

	return 0;
}

image

Clone this wiki locally