C Uart检查接收缓冲区中断与轮询

C Uart检查接收缓冲区中断与轮询,c,buffer,uart,jtag,isr,C,Buffer,Uart,Jtag,Isr,您好,我正在学习如何通过在Nios中使用中断来使用Uart,我不知道如何启动。我在投票中做到了,但我不知道如何开始使用中断 任何帮助都将不胜感激 这是我的密码 #include <stdio.h> // for NULL #include <sys/alt_irq.h> // for irq support function #include "system.h" // f

您好,我正在学习如何通过在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] != '\0')
    {
        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 program\n\n");

  while (!done)
  {
      uint8 character_from_uart;
      if (uart_checkRecvBuffer(&character_from_uart))
      {
          uart_SendByte(character_from_uart);
      }

    // do nothing
  } /* while */

  uart_SendString((uint8*)"\n\nDetected '.'.\n");
  uart_SendString((uint8*)"Program existing....\n");
  return 0;

} /* main */
#包含//表示空
#包含//用于irq支持功能
#包括QSYS定义的“system.h”//
#包括标准嵌入式类型的“nios\u std\u types.h”//
#定义JTAG_数据_注册表_偏移量0
#定义JTAG\U CNTRL\U REG\U偏移量1
#定义JTAG_UART_WSPACE_掩码0xFFFF0000
#定义JTAG\U UART\U RV\U位掩码0x00008000
#定义JTAG\U UART\U数据掩码0x000000FF
易失性uint32*uartDataRegPtr=(uint32*)JTAG\u UART\u 0\u基;
易失性uint32*uartcontrlregptr=((uint32*)JTAG\u UART\u 0\u基+
JTAG_CNTRL_REG_OFFSET);
无效uart_发送字节(uint8字节);
无效uart_发送字符串(uint8*msg);
//uint32 uart_checkRecvBuffer(uint8*字节);
uint32 done=FALSE;
无效uart_发送字符串(uint8*msg)
{
int i=0;
while(msg[i]!='\0')
{
uart_SendByte(msg[i]);
i++;
}
}/*uart\u发送字符串*/
无效uart_发送字节(uint8字节)
{
uint32 WSPACE_Temp=*uartCntrlRegPtr;
while((WSPACE\u Temp&JTAG\u UART\u WSPACE\u MASK)==0)
{
WSPACE_Temp=*uartCntrlRegPtr;
}
*uartDataRegPtr=字节;
}/*uart\u发送字节*/
uint32通用异步收发器(uint8*字节)
{
uint32返回_值;
uint32 DataReg=*uartDataRegPtr;
*字节=(uint8)(DataReg&JTAG\uuart\udata\umask);
返回值=数据寄存器和JTAG UART RV位掩码;
返回值=返回值>>15;
返回_值;
}/*uart_checkRecvBuffer*/
无效uart_RecvBufferIsr(无效*上下文)
{
}/*uart_RecvBufferIsr*/
内部主(空)
{
uint8*测试消息=(uint8*)“这是一条测试消息。\n”;
//alt_ic_isr_寄存器();//用于中断启用时的第二部分
uart\u发送字符串(测试消息);
uart_SendString((uint8*)“输入“.”以存在程序\n\n”);
而(!完成)
{
来自uart的uint8字符;
if(uart\u checkRecvBuffer(&character\u from\u uart))
{
uart\u SendByte(来自uart的字符);
}
//无所事事
}/*当*/
uart_发送字符串((uint8*)“\n\n检测到”“。\n”);
uart_发送字符串((uint8*)“程序已存在…”\n“;
返回0;
}/*主要*/

我想使用uart_RecvBufferIsr而不是uart_checkRecvBuffer。如何处理这种情况?

您需要使用alt_ic_isr_register()注册中断处理程序,然后在引发中断时调用它。可以在Altera的NIOSII中找到详细信息(包括一些示例代码)

至于修改代码以使用中断,我将做以下几点:

删除uart_checkRecvBuffer()

将uart_RecvBufferIsr()更改为类似(抱歉,此处没有编译器,因此无法检查语法/功能):

上面代码的故事寓意是,您应该尽可能地缩短中断时间,并让任何严格不需要在外部执行的操作(可能通过简化我使用的recv_char和recv_标志的逻辑)

然后将循环更改为类似以下内容:

while (!done)
{
    if (recv_flag)
    {
        uart_SendByte(recv_byte);
        recv_flag = 0;
    }
}
请注意,根据端口的速度,我所做的操作可能会出现问题-如果接收字符太快,上面的“while”循环无法处理这些字符,则会丢失一些字符

最后,请注意,我将一些变量声明为“volatile”,以防止编译器将它们保存在寄存器中,例如while循环中


但希望这能让你走起来。

是的,我有这个,刚刚评论了一下。但我想我最大的困惑是如何创建函数以及如何将其放在主函数中。我一直在看Altera的PDF文件,但我个人不明白怎么看。(编码新手)添加了更多信息。非常感谢,这真的很有帮助!
while (!done)
{
    if (recv_flag)
    {
        uart_SendByte(recv_byte);
        recv_flag = 0;
    }
}