USART1 в STM32F427 иногда устанавливает 8-й бит данных, как если бы это был бит четности

Я работаю с STM32F427 UASRT1 через следующий класс:

void DebugUartOperator::Init() {
    // for USART1 and USART6 
    ::RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
    // USART1 via PORTA 
    ::RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); 

    ::GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);
    ::GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);

    GPIO_InitTypeDef GPIO_InitStruct;

    // fills the struct with the default vals: 
    // all pins, mode IN, 2MHz, PP, NOPULL
    ::GPIO_StructInit(&GPIO_InitStruct); 

    // mission-specific settings:
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
    ::GPIO_Init (GPIOA, &GPIO_InitStruct);

    USART_InitTypeDef USART_InitStruct;

    // 9600/8/1/no parity/no HWCtrl/rx+tx
    ::USART_StructInit(&USART_InitStruct); 

    USART_InitStruct.USART_BaudRate = 921600;
    USART_InitStruct.USART_WordLength = USART_WordLength_9b;
    USART_InitStruct.USART_StopBits = USART_StopBits_1;
    USART_InitStruct.USART_Parity = USART_Parity_Odd;
    ::USART_Init(USART1, &USART_InitStruct);

    ::USART_Cmd(USART1, ENABLE);
    }

void DebugUartOperator::SendChar(char a) {
    // wait for TX register to become empty
    while(::USART_GetFlagStatus(USART1, USART_FLAG_TXE) != SET);
    ::USART_SendData(USART1, static_cast<uint8_t>(a));
    }

Проблема заключается в том, что время от времени USART начинает игнорировать фактический 8-й бит данных и устанавливает его в качестве бита четности (нечетная четность, если быть точным). Самое странное, что это иногда случается даже после длительного отключения питания, без какого-либо предварительного перепрограммирования или чего-то еще. Например, вчера вечером все было в порядке, затем на следующее утро я прихожу на работу, включаю устройство, и оно начинает работать, как описано. Но это не ограничивается этим, оно может случайно появиться после некоторого следующего перезапуска.

Этот эффект хорошо виден на осциллографе и на различных UART-USB преобразователях, используемых с различными программами. Возможно даже после появления этого эффекта перепрограммировать микроконтроллер для передачи наборов тестовых данных. Например, от 0x00 до 0xFF в бесконечном цикле. Это не влияет на проблему. Изменение скоростей (до 9600 бит / с), бит на слово, контроль четности не помогает - эффект остается неизменным даже после перепрограммирования (что приводит, например, к действительно ненормальным 2 битам четности на байт). Или, по крайней мере, пока UASRT инициализируется и используется в обычном порядке в соответствии с рабочим процессом моей программы.

Единственный способ исправить это - заставить функцию main() сделать следующее:

int main() {
    DebugUartOperator dua;
    dua.Init();
    while(1) {
        uint8_t i;
        while(++i)
            dua.SendChar(i);
        dua.SendChar(i);
        }
    }

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

Этот эффект наблюдается на 2 разных STM32F427s на 2 физически разных досках одинаковой раскладки. Никакой закономерности в его внешности не замечено. Полярность и уровни сигнала соответствуют требованиям USART, во время исследования не обнаруживаются шумы или плохие контакты. Кажется, нет никакого отношения к UASRT1 со стороны другого кода, используемого в моей программе (моей или библиотечной), или он глубоко скрыт. CMSIS-OS используется в качестве RTOS в проекте, с KeiluVision 5.0.5"s RTX OS,

Нужна помощь.

1 ответ

В STM вы можете указать длину слова для передачи usart / uart, но длина слова - это сумма битов данных и четности битов. Поэтому, если вы хотите иметь 8-битные данные и даже бит четности, вы должны указать UART_WORDLENGTH_9B а такжеUART_PARITY_EVEN,

Вы также можете иметь 9 бит данных без четности. В справочном руководстве для F427 раздел 30.6.4, Bit 12 мы видим, что должно быть возможно установить 9 бит данных, но срок data bits также применимо к биту четности.

Бит 12M: длина слова
Этот бит определяет длину слова. Это устанавливается или очищается программным обеспечением.
0: 1 стартовый бит, 8 бит данных, n стоповый бит
1: 1 стартовый бит, 9 битов данных, n стоповый бит

Окончательный ответ в 30.6.4, Bit 10

Этот бит выбирает аппаратный контроль четности (генерация и обнаружение). Когда контроль четности включен, вычисленная четность вставляется в позицию MSB (9-й бит, если M=1; 8-й бит, если M=0), и четность проверяется на полученных данных. Этот бит устанавливается и сбрасывается программным обеспечением. Как только он установлен, PCE активен после текущего байта (при приеме и при передаче).

Другие вопросы по тегам