你好,我正在学习如何通过在Nios中使用中断来使用Uart,但我不知道如何启动。我在轮询中做到了,但我不知道如何开始使用中断。
如有任何帮助,将不胜感激
这是我的代码
#include <stdio.h> // for NULL
#include <sys/alt_irq.h> // for irq support function
#include "system.h" // for QSYS defines
#include "nios_std_types.h" // for standard embedded types
#define JTAG_DATA_REG_OFFSET 0
#define JTAG_CNTRL_REG_OFFSET 1
#define JTAG_UART_WSPACE_MASK 0xFFFF0000
#define JTAG_UART_RV_BIT_MASK 0x00008000
#define JTAG_UART_DATA_MASK 0x000000FF
volatile uint32* uartDataRegPtr = (uint32*)JTAG_UART_0_BASE;
volatile uint32* uartCntrlRegPtr = ((uint32*)JTAG_UART_0_BASE +
JTAG_CNTRL_REG_OFFSET);
void uart_SendByte (uint8 byte);
void uart_SendString (uint8 * msg);
//uint32 uart_checkRecvBuffer (uint8 *byte);
uint32 done = FALSE;
void uart_SendString (uint8 * msg)
{
int i = 0;
while(msg[i] != ' ')
{
uart_SendByte(msg[i]);
i++;
}
} /* uart_SendString */
void uart_SendByte (uint8 byte)
{
uint32 WSPACE_Temp = *uartCntrlRegPtr;
while((WSPACE_Temp & JTAG_UART_WSPACE_MASK) == 0 )
{
WSPACE_Temp = *uartCntrlRegPtr;
}
*uartDataRegPtr = byte;
} /* uart_SendByte */
uint32 uart_checkRecvBuffer (uint8 *byte)
{
uint32 return_value;
uint32 DataReg = *uartDataRegPtr;
*byte = (uint8)(DataReg & JTAG_UART_DATA_MASK);
return_value = DataReg & JTAG_UART_RV_BIT_MASK;
return_value = return_value >> 15;
return return_value;
} /* uart_checkRecvBuffer */
void uart_RecvBufferIsr (void* context)
{
} /* uart_RecvBufferIsr */
int main(void)
{
uint8* test_msg = (uint8*)"This is a test message.n";
//alt_ic_isr_register ( ); // used for 2nd part when interrupts are enabled
uart_SendString (test_msg);
uart_SendString ((uint8*)"Enter a '.' to exist the programnn");
while (!done)
{
uint8 character_from_uart;
if (uart_checkRecvBuffer(&character_from_uart))
{
uart_SendByte(character_from_uart);
}
// do nothing
} /* while */
uart_SendString((uint8*)"nnDetected '.'.n");
uart_SendString((uint8*)"Program existing....n");
return 0;
} /* main */
我想使用uart_checkRecvBufferIsr而不是uart_ccheckRecvBuffer。如何应对这种情况?
您需要使用alt_ic_isr_register()注册中断处理程序,然后在引发中断时调用它。详细信息(包括一些示例代码)可以在Altera的NIOSIPDF文档中找到。
至于修改代码以使用中断,以下是我要做的:
删除uart_checkRecvBuffer();
将uart_RecvBufferIsr()更改为类似的内容(很抱歉这里没有编译器,因此无法检查语法/功能):
volatile uint32 recv_flag = 0;
volatile uint8 recv_char;
void uart_RecvBufferIsr(void *context)
{
uint32 DataReg = *uartDataRegPtr;
recv_char = (uint8)(DataReg & JTAG_UART_DATA_MASK);
recv_flag = (DataReg & JTAG_UART_RV_BIT_MASK) >> 15;
}
上面代码的寓意是,你应该尽可能缩短中断时间,让任何不严格必要的事情都在外面完成(也许可以简化我在recv_char和recv_flag中使用的逻辑)。
然后将您的循环更改为类似的内容
while (!done)
{
if (recv_flag)
{
uart_SendByte(recv_byte);
recv_flag = 0;
}
}
请注意,根据您端口的速度,我所做的操作可能会出现问题——如果接收到的字符太快,而上面的"while"循环无法处理这些字符,则会丢失一些字符。
最后,请注意,我将一些变量声明为"volatile",以防止编译器将它们保存在寄存器中,例如while循环中。
但希望这能让你继续前进。