文章目錄
- 1.ZYNQ 串口持續觸發 TX FIFO EMPTY中斷(XUARTPS_IXR_TXEMPTY)
- 問題描述:
- 產生原因:
- 解決辦法:
1.ZYNQ 串口持續觸發 TX FIFO EMPTY中斷(XUARTPS_IXR_TXEMPTY)
問題描述:
? ZYNQ 7020 串口作業為中斷觸發模式,使用XUartPs_Send()函式發送完成資料之后,會產生一個 TX FIFO EMPTY中斷(盡管串口初始化中斷時并沒有使能XUARTPS_IXR_TXEMPTY中斷),同時會呼叫串口中斷處理函式,如果沒有清除處中斷標志位,除非關閉中斷XScuGic_Disable()否則會持續呼叫中斷處理函式,影響程式正常運行,
產生原因:
? 呼叫XUartPs_Send()函式時,會先關閉TX EMPTY和TX FULL中斷
/*
* Disable the UART transmit interrupts to allow this call to stop a
* previous operation that may be interrupt driven.
*/
XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_IDR_OFFSET,
(XUARTPS_IXR_TXEMPTY | XUARTPS_IXR_TXFULL));
BytesSent = XUartPs_SendBuffer(InstancePtr);
? 然后呼叫XUartPs_SendBuffer()函式,在該函式中,如果開啟了接收中斷,則會開啟TX EMPTY的中斷,
/*
* If interrupts are enabled as indicated by the receive interrupt, then
* enable the TX FIFO empty interrupt, so further action can be taken
* for this sending.
*/
ImrRegister =
XUartPs_ReadReg(InstancePtr->Config.BaseAddress,
XUARTPS_IMR_OFFSET);
if (((ImrRegister & XUARTPS_IXR_RXFULL) != (u32)0) ||
((ImrRegister & XUARTPS_IXR_RXEMPTY) != (u32)0)||
((ImrRegister & XUARTPS_IXR_RXOVR) != (u32)0)) {
XUartPs_WriteReg(InstancePtr->Config.BaseAddress,
XUARTPS_IER_OFFSET,
ImrRegister | (u32)XUARTPS_IXR_TXEMPTY);//使能TX EMPTY中斷
}
解決辦法:
(1)在中斷處理函式中對發送FIFO中斷進行判斷,如果觸發該中斷,則清除中斷標志,
(2)使用XUartPs_SendByte()按位元組發送資料,
串口發送代碼:
void Ublox_Cfg(u8 type)
{
switch(type)
{
case Hot:
{
unsigned char uart_send[] ={0xB5, 0x62, 0x06, 0x04, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x10, 0x68};
XUartPs_Send(&Uart_Ps, uart_send, 12);
break;
}
default:
break;
}
}
中斷處理函式代碼:
void uart_handler(void *call_back_ref)
{
XUartPs *uart_instance_ptr = (XUartPs *) call_back_ref;
u32 IsrStatus;
u32 rx_realnumber;
//讀取中斷 ID 暫存器,判斷觸發的是哪種中斷
IsrStatus = XUartPs_ReadReg(uart_instance_ptr->Config.BaseAddress,
XUARTPS_IMR_OFFSET);
IsrStatus &= XUartPs_ReadReg(uart_instance_ptr->Config.BaseAddress,
XUARTPS_ISR_OFFSET);
if((IsrStatus & (u32)XUARTPS_IXR_TXEMPTY))
{
XUartPs_WriteReg(uart_instance_ptr->Config.BaseAddress, XUARTPS_ISR_OFFSET, XUARTPS_IXR_TXEMPTY) ;//clear TX FIFO中斷
}
if((IsrStatus & (u32)XUARTPS_IXR_RXOVR))//接收FIFO觸發中斷
{
rx_realnumber = XUartPs_Recv(uart_instance_ptr,&uart_recv[uart_totalnumber],512);//讀取FIFO資料到陣列,回傳實際接收長度
uart_totalnumber += rx_realnumber;//計算總接收長度
XUartPs_WriteReg(uart_instance_ptr->Config.BaseAddress, XUARTPS_ISR_OFFSET, XUARTPS_IXR_RXOVR) ;//clear 中斷
}
}
串口初始化代碼:
int uartps_init(XUartPs* uart_ps)
{
int status;
XUartPs_Config *uart_cfg;
XScuGic_Config *intc_cfg;
uart_cfg = XUartPs_LookupConfig(UART_DEVICE_ID);
if (NULL == uart_cfg)
return XST_FAILURE;
status = XUartPs_CfgInitialize(uart_ps, uart_cfg, uart_cfg->BaseAddress);
if (status != XST_SUCCESS)
return XST_FAILURE;
XUartPs_SetOperMode(uart_ps, XUARTPS_OPER_MODE_NORMAL);
XUartPs_SetBaudRate(uart_ps,UART_BAUD);
XUartPs_SetFifoThreshold(uart_ps,60);
Xil_ExceptionInit();
intc_cfg = XScuGic_LookupConfig(INTC_DEVICE_ID);
if (NULL == intc_cfg)
return XST_FAILURE;
status = XScuGic_CfgInitialize(&Intc, intc_cfg,intc_cfg->CpuBaseAddress);
if (status != XST_SUCCESS)
return XST_FAILURE;
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT,(Xil_ExceptionHandler)XScuGic_InterruptHandler,(void *)&Intc);
XScuGic_Connect(&Intc,UART_INT_IRQ_ID,(Xil_ExceptionHandler)uart_handler,(void *)uart_ps);
//設定 UART 的中斷觸發方式
XUartPs_SetInterruptMask(uart_ps,XUARTPS_IXR_RXOVR); //此處沒有打開XUARTPS_IXR_TXEMPTY中斷
Xil_ExceptionEnable();
XScuGic_Enable(&Intc,UART_INT_IRQ_ID);
return XST_SUCCESS;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/277123.html
標籤:其他
上一篇:【單片機】數碼管應用
