2012-03-21 46 views
1

我試圖通過輸入UART事件處理程序捕獲輸入數字,並用該數字的一些乘法打印回來。它打印字符串很好,但打印完成後程序不再對任何輸入做出反應。可以打印alfabet或顯示錯誤消息,但是當我使用printf函數時,終端停止響應輸入,並且光標位於下一行的中間位置。Printf停止工作的終端

這是C代碼:

#include "mss_uart.h" 
#include <stdio.h> 

#define RX_BUFF_SIZE 64 
#define MSS_UART_57600_BAUD  57600 
uint8_t g_rx_buff[RX_BUFF_SIZE]; 
uint8_t g_rx_idx; 

void uart0_rx_handler(mss_uart_instance_t * this_uart) 
{ 
MSS_UART_get_rx(&g_mss_uart0, &g_rx_buff[g_rx_idx], sizeof(g_rx_buff)); 
if(g_rx_buff[g_rx_idx] > 96 && g_rx_buff[g_rx_idx] < 123) 
{ 
    uint8_t message[55] = "De letter was: x, de uppercase letter van : x is y.\n\r"; 
    message[15] = g_rx_buff[g_rx_idx]; 
    message[44] = g_rx_buff[g_rx_idx]; 
    message[49] = g_rx_buff[g_rx_idx] - 32; 

    MSS_UART_polled_tx(&g_mss_uart0, message, sizeof(message)); 
} 
else if(g_rx_buff[g_rx_idx] > 64 && g_rx_buff[g_rx_idx] < 91) 
{ 
    uint8_t message[55] = "De letter was: x, de lowercase letter van : x is y.\n\r"; 
    message[15] = g_rx_buff[g_rx_idx]; 
    message[44] = g_rx_buff[g_rx_idx]; 
    message[49] = g_rx_buff[g_rx_idx] + 32; 

    MSS_UART_polled_tx(&g_mss_uart0, message, sizeof(message)); 
} 
else if(g_rx_buff[g_rx_idx] > 47 && g_rx_buff[g_rx_idx] < 58) 
{ 
    int number = g_rx_buff[g_rx_idx] - '0'; 
      int number2 = number * number; 
      int number3 = number2 * number; 
      int number4 = number3 * number; 

    printf("Getallenreeks: %d, %d, %d, %d.\n\r", number, number2, number3, number4); 

} 
else 
{ 
    uint8_t message[10] = "Error.\n\r"; 
    MSS_UART_polled_tx(&g_mss_uart0, message, sizeof(message)); 
} 
} 

int main(void) 
{ 
MSS_UART_init 
(
     &g_mss_uart0, 
     MSS_UART_57600_BAUD, 
     MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT 
); 

MSS_UART_set_rx_handler(&g_mss_uart0, uart0_rx_handler, MSS_UART_FIFO_SINGLE_BYTE ); 

while (1) 
{} 
return(0); 
} 

空隙uart0_rx_handler是intterupt處理程序和MSS_UART_get_rx放輸入在g_rx_buff [g_rx_idx]。

我試着用相同的號碼打印號碼MSS_UART_polled_tx函數我用於字符,但沒有運氣。它打印錯誤ASCII值:

if(g_rx_buff[g_rx_idx] > 47 && g_rx_buff[g_rx_idx] < 58) 
{ 
    int number = g_rx_buff[g_rx_idx] - '0'; 
    int number2 = number * number; 
    int number3 = number2 * number; 
    int number4 = number3 * number; 

    uint8_t message[15] = "Getallenreeks: "; 
    uint8_t komma[2] = ", "; 
    uint8_t end[5] = ".\n\r"; 

    char numberstring2[2]; 
    char numberstring3[3]; 
    char numberstring4[4]; 

    sprintf(numberstring2, "%d", number2); 
    sprintf(numberstring3, "%d", number3); 
    sprintf(numberstring4, "%d", number4); 

    uint8_t messagenumber[1]; 
    uint8_t messagenumber2[1]; 
    uint8_t messagenumber3[1]; 
    uint8_t messagenumber4[1]; 

    messagenumber[0] = '0' + number; 
    messagenumber2[0] = '0' + number2; 
    messagenumber3[0] = '0' + number3; 
    messagenumber4[0] = '0' + number4;  

    http://imageshack.us/photo/my-images/843/testlan.jpg/(&g_mss_uart0, message, sizeof(message)); 
    MSS_UART_polled_tx(&g_mss_uart0, messagegetal, sizeof(messagenumber)); 
    MSS_UART_polled_tx(&g_mss_uart0, komma, sizeof(komma)); 
    MSS_UART_polled_tx(&g_mss_uart0, messagegetal2, sizeof(messagenumber2)); 
    MSS_UART_polled_tx(&g_mss_uart0, komma, sizeof(komma)); 
    MSS_UART_polled_tx(&g_mss_uart0, messagegetal3, sizeof(messagenumber3)); 
    MSS_UART_polled_tx(&g_mss_uart0, komma, sizeof(komma)); 
    MSS_UART_polled_tx(&g_mss_uart0, messagegetal4, sizeof(messagenumber4)); 
    MSS_UART_polled_tx(&g_mss_uart0, end, sizeof(end));  
} 

代碼輸出例如:http://imageshack.us/photo/my-images/843/testlan.jpg/ 左終端示出使用的printf功能,右末端示出了用於數字使用MSS_UART_polled_tx功能(在第二碼塊中所示)。

+1

考慮使用「0」和「9」(以及「> =」和「<=」)而不是「47」和「58」。 – pmg 2012-03-21 10:48:10

+0

我沒有看到g_rx_idx在這個片段中增加,而你似乎在消耗一個字節。也許你的循環緩衝區管理代碼卡在某處(也許在這裏)? – wildplasser 2012-03-21 10:50:10

+1

你應該使用'isdigit()'來檢測數字,而不是硬編碼的編碼值。如果你沒有'isdigit()',使用@ pmg的建議。 – unwind 2012-03-21 12:11:08

回答

1

我認爲最大的錯誤是將「\ r \ n」的長度計爲4(它是2),另一個是使用'sizeof stringarray',它包含終止NUL字節所使用的空間。

/** added */ 
#include <stdint.h> 
#include <stdio.h> 

struct xx; 
typedef struct xx mss_uart_instance_t; 

void MSS_UART_get_rx(mss_uart_instance_t * the_uart, uint8_t buff[] , size_t len); 
void MSS_UART_polled_tx(mss_uart_instance_t * the_uart, uint8_t buff[] , size_t len); 
    /** End added */ 

#define RX_BUFF_SIZE 64 
#define MSS_UART_57600_BAUD  57600 

uint8_t g_rx_buff[RX_BUFF_SIZE]; 
uint8_t g_rx_idx; 

void uart0_rx_handler(mss_uart_instance_t * this_uart) 
{ 
    MSS_UART_get_rx(this_uart, &g_rx_buff[g_rx_idx], sizeof g_rx_buff); 
    if(g_rx_buff[g_rx_idx] >= 'a' && g_rx_buff[g_rx_idx] <= 'z') 
    { 
     uint8_t message[] = "De letter was: x, de uppercase letter van : x is y.\n\r"; 
     message[15] = g_rx_buff[g_rx_idx]; 
     message[44] = g_rx_buff[g_rx_idx]; 
     message[49] = g_rx_buff[g_rx_idx] - ('a' - 'A'); 

     MSS_UART_polled_tx(this_uart, message, strlen(message)); /* 52 */ 
    } 
    else if(g_rx_buff[g_rx_idx] >= 'A' && g_rx_buff[g_rx_idx] <= 'Z') 
    { 
     uint8_t message[] = "De letter was: x, de lowercase letter van : x is y.\n\r"; 
     message[15] = g_rx_buff[g_rx_idx]; 
     message[44] = g_rx_buff[g_rx_idx]; 
     message[49] = g_rx_buff[g_rx_idx] + ('a' - 'A'); 

     MSS_UART_polled_tx(this_uart, message, strlen(message)); /* 52 */ 
    } 
    else if(g_rx_buff[g_rx_idx] >= '0' && g_rx_buff[g_rx_idx] <= '9') 
    { 
     uint8_t bigbuff[70] ; 
     size_t buflen; 
     int number = g_rx_buff[g_rx_idx] - '0'; 
       int number2 = number * number; 
       int number3 = number2 * number; 
       int number4 = number3 * number; 

     buflen = sprintf(bigbuff, "Getallenreeks: %d, %d, %d, %d.\n\r", number, number2, number3, number4); 
     MSS_UART_polled_tx(this_uart, bigbuff, buflen); 

    } 
    else 
    { 
     uint8_t message[] = "Error.\n\r"; 
     MSS_UART_polled_tx(this_uart, message, strlen(message)); /* 8 */ 
    } 
} 
+0

好的作品,謝謝! sprintf函數完成了這項工作,我也編輯了字符串長度。 – Glenn 2012-03-21 17:38:11

+0

作爲一個wijze raad:不要編輯字符串長度。讓編譯器通過'strlen()'或'sizeof buff -1'來爲你做計算 – wildplasser 2012-03-21 17:41:45

0

我認爲你有兩個問題。

其中之一就是您在中斷處理程序中調用printf()並掛起。也許在你的平臺上,printf()不能從中斷上下文中調用,因爲(猜測)它試圖使用中斷驅動的輸出,並等待因禁止中斷而永遠不會發生的完成中斷。

第二個問題是關於你對第二個例子的輸出的期望。他們看起來對我很好。你正在增加一些非常大的數字,然後將它們添加到char值。這將導致單個字符可能是您不想要的字母或符號。例如,

'0' + 16 == '@' 

您在其中一個示例中看到的內容。如果你想輸出「16」,即兩個字符'1'和'6',你需要做更多的工作來計算單個字符(涉及除法10)。

+0

當我在處理程序之外放置printf()時,在帶有bool的main while循環中它仍然會給出相同的錯誤。你對char的價值是正確的,愚蠢的我。我使用了wildplasser提到的sprintf()來自動轉換它們! – Glenn 2012-03-21 17:40:55