2014-02-13 71 views
0

您好我正在學習如何使用Uart通過在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 */ 

我想用uart_RecvBufferIsr代替uart_checkRecvBuffer。如何解決這種情況?

回答

0

您需要使用alt_ic_isr_register()註冊中斷處理程序,然後在引發中斷時調用它。可以在Altera的NIOS II PDF document中找到詳細信息(包括一些示例代碼)。

至於修改代碼以使用中斷,這裏是我會做什麼:

刪除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; 
    } 
} 

注意,有可能是與我根據​​您的端口的速度做了什麼問題 - 如果收到太快了「,而字符「上面的循環來處理它們,你會失去一些字符。

最後,請注意,我將一些變量聲明爲「volatile」,以防止編譯器將它們保留在寄存器中,例如在while循環中。

但希望這會讓你走。

+0

是的,我在那裏,只是註釋掉了。但我想我的大混亂是真正創造了這個功能,以及如何將它放在主體中。我一直在查看來自Altera的PDF文件,但我個人不知道如何。 (編碼新手) – user3304099

+0

增加了一些信息。 – rfernandes

+0

非常感謝,這真的幫了大忙! – user3304099