3

我正在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 bps)、每个字的位、奇偶校验控制无济于事 - 即使在重新编程后效果仍然保持不变(例如,导致每个字节真正异常的 2 个奇偶校验位)。或者,至少,根据我的程序的工作流程,UASRT 正在初始化并以通常的顺序使用。

修复它的唯一方法是让 main() 函数执行以下操作:

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

有了这个,在重新编程和重新启动后,前几个字节(最多 5 个)被传输,但随后一切正常,并通过进一步的重新启动和重新编程继续正常工作。

STM32F427在相同布局的 2 个物理上不同的板上的2 个不同的 s 上观察到这种效果。它的外观没有规律性。信号极性和电平符合 USART 要求,在调查期间未检测到噪音或接触不良。从我的程序中使用的其他代码(无论是我的还是库代码)的方向来看,UASRT1 似乎没有任何影响,或者它被深深地掩埋了。在项目中CMSIS-OS用作 RTOS,带有Keil uVision 5.0.5.RTX OS

需要帮忙。

4

1 回答 1

1

在 STM 中,您可以为 usart / uart 传输指定字长,但字长是数据位和位奇偶校验的总和。因此,如果您想要 8 位数据甚至奇偶校验位,则必须指定UART_WORDLENGTH_9Band 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 位置(如果 M=1,则插入第 9 位;如果 M=0,则插入第 8 位)并对接收到的数据进行奇偶校验。该位由软件设置和清除。一旦置位,PCE 在当前字节后激活(接收和发送)。

于 2017-04-11T15:16:50.123 回答