2012-03-21 3 views
1

Я пытаюсь захватить входной номер через входной обработчик события UART и распечатать его с некоторыми умножениями этого числа. Он печатает строку просто отлично, но после ее печати программа больше не реагирует на ввод. Можно распечатать альфабет или отобразить сообщение об ошибке, но когда я использую функцию 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

+0

Я не вижу, чтобы g_rx_idx увеличивался в этом фрагменте, в то время как вы, кажется, потребляете байт. Может быть, ваш код управления циклическим буфером застрял где-нибудь (может быть, здесь)? – wildplasser

+1

Вы должны использовать 'isdigit()' для обнаружения цифр, не кодированных закодированными значениями. Если у вас нет 'isdigit()', используйте предложение @ pmg. – unwind

ответ

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

+0

Как wijze raad: не редактируйте длины строк. Пусть компилятор выполнит вычисления для вас, либо с помощью 'strlen()', либо 'sizeof buff -1' – wildplasser

0

Думаю, у вас есть две проблемы.

Во-первых, вы вызываете printf() внутри обработчика прерываний, и он висит. Возможно, на вашей платформе printf() не может быть вызван из контекста прерывания, потому что (угадывание) он пытается использовать вывод с прерыванием и ожидает прерывания завершения, которое никогда не появляется, потому что у вас отключены прерывания.

Вторая проблема связана с вашими ожиданиями относительно результата второго примера. Они смотрят на меня хорошо. Вы умножаете некоторые довольно большие числа, добавляя их к значению char. Это приведет к одному символу, который может быть буквой или символом, который вам не нужен. Например

'0' + 16 == '@' 

Что вы видите на одном из ваших примеров. Если вы хотите вывести «16», то есть два символа «1» и «6», и вам нужно сделать еще одну работу для вычисления отдельных символов (включая деление на 10).

+0

Когда я помещаю printf() за пределы обработчика, в основном цикле while с bool он по-прежнему дает ту же ошибку. Вы правы в значении char, глупо меня. Я использовал sprintf(), упомянутый wildplasser, чтобы автоматически преобразовать их! – Glenn

Смежные вопросы