Top.Mail.Ru
Уведомления
Очистить все

[Закреплено] STM32 для начинающих

Страница 23 / 23
(@aleksej-6)
Level 4

Нашёл ответ на свой вопрос. I2C на плате сделан программный..  


ОтветитьЦитата
Размещено : 10.11.2025 11:05
(@arm-programmer)
New member

Всем привет.

Занимаюсь реализацией TUI через UART на STM32F1xx с HAL. Описание функциональности:

- Неблокирующий ввод

- Завершение ввода при нажатии Enter

- При нажатии на Backspace предыдущий символ удаляется (при наличии)

- Видимые символы отображаются

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

При написании кода использую кольцевой буфер (ring/circular buffer) для хранения строк. Он представляет из себя отдельную библиотеку.

Вот код проекта:

static UART_HandleTypeDef *console_uart = NULL;
static char line_buffer[CONSOLE_MAX_RX_DATA_LENGTH];
static uint16_t line_len = 0;

// TX Buffer
static ring_buffer_t tx_buffer;
static volatile uint8_t tx_busy = 0;
static volatile uint8_t tx_byte;

// RX Buffer
static ring_buffer_t rx_buffer;
static volatile uint8_t rx_byte;
static volatile uint8_t rx_ready = 0;

static void console_rx_callback(UART_HandleTypeDef *);
static void console_tx_callback(UART_HandleTypeDef *);

uint8_t console_init(UART_HandleTypeDef *huart) {
    if (huart == NULL || console_uart != NULL) {
        return 1;
    }

    console_uart = huart;

    ring_buffer_init(&tx_buffer);
    tx_busy = 0;    

    ring_buffer_init(&rx_buffer);
    rx_ready = 0;

    HAL_UART_RegisterCallback(
        console_uart,
        HAL_UART_RX_COMPLETE_CB_ID,
        console_rx_callback
    );

    HAL_UART_RegisterCallback(
        console_uart,
        HAL_UART_TX_COMPLETE_CB_ID,
        console_tx_callback
    );

    HAL_UART_Receive_IT(console_uart, (uint8_t *) &rx_byte, 1);
    return 0;
}

void console_print(const char *str) {
    HAL_UART_Transmit(console_uart, (uint8_t *) str, strlen(str), 10);
    // ring_buffer_write(&tx_buffer, (uint8_t *) str, strlen(str));

    // if (tx_busy == 0) {
    //     tx_busy = 1;
    //     tx_byte = ring_buffer_pop(&tx_buffer);
    //     HAL_UART_Transmit_IT(console_uart, &tx_byte, 1);
    // }
}

void console_clear() {
    console_print("\033[2J\033[H");
}

// Берет на себя всю обработку символов: backspace, enter и echo
void console_poll() {
    while (ring_buffer_get_length(&rx_buffer) > 0 && rx_ready == 0) {
        uint8_t ch = ring_buffer_pop(&rx_buffer);
        if ((ch == '\b' || ch == 0x7F) && line_len > 0) {
            line_len--;
            console_print("\b \b");
        }
        else if (ch == '\r' || ch == '\n') {
            line_buffer[line_len] = '\0';
            rx_ready = 1;
            console_print("\r\n");
            return;
        }
        else if (line_len < CONSOLE_MAX_RX_DATA_LENGTH - 1) {
            line_buffer[line_len++] = ch;
            char echo[2] = {ch, 0};
            console_print(echo);
        }
    }
}

uint8_t console_ready() {
    return rx_ready;
}

void console_read(char *buffer) {
    if (buffer == NULL || rx_ready == 0) {
        return;
    }
    
    strcpy(buffer, line_buffer);
    rx_ready = 0;
    line_len = 0;
    line_buffer[0] = '\0';
}

static void console_tx_callback(UART_HandleTypeDef *console) {
    if (ring_buffer_get_length(&tx_buffer) == 0) {
        tx_busy = 0;
    }
    else {
        tx_byte = ring_buffer_pop(&tx_buffer);
        HAL_UART_Transmit_IT(console_uart, &tx_byte, 1);
    }
}

static void console_rx_callback(UART_HandleTypeDef *console) {
    ring_buffer_push(&rx_buffer, rx_byte);
    HAL_UART_Receive_IT(console_uart, &rx_byte, 1);
}

Использование в приложении примерно такое:

while(1) {
    console_poll();
    if (console_ready()) {
        console_read(consoleBuffer);
        // Действия с console buffer
    }
}

 

При подключении через утилиту screen на скорости 115200 выводит следующее (вводил просто '?'):

Rebooeot system
?. menu
cm>>
Unknoan
oy en
symenu
cm

То есть вывод максимально ломаный.

Знающие люди, подскажите, пожалуйста, что не так с этим кодом и в чем именно проблема. Нейронки не помогают, а в DMA сейчас не планирую лезть - хочу сперва разобраться с прерываниями.

Благодарю за любую помощь, спасибо!


ОтветитьЦитата
Размещено : 12.02.2026 14:01
Страница 23 / 23
Поделиться:
Обзор конфиденциальности

На этом сайте используются файлы cookie, что позволяет нам обеспечить наилучшее качество обслуживания пользователей. Информация о файлах cookie хранится в вашем браузере и выполняет такие функции, как распознавание вас при возвращении на наш сайт и помощь нашей команде в понимании того, какие разделы сайта вы считаете наиболее интересными и полезными.