首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >STM32 UART2 BRR未给出预期结果

STM32 UART2 BRR未给出预期结果
EN

Stack Overflow用户
提问于 2021-07-04 05:14:33
回答 1查看 85关注 0票数 1

我目前正在使用发现板上的STM32F407VG。我正在检查外围设备,并试图通过仅操作寄存器(无HAL)来使每个外围设备正常工作。

我使用示波器(大约每位8-9 us )和Putty中的波特率(111,111波特率来显示实际字符)来测量这一点。

我是最大的时钟速度的芯片168 MHz SYSCLK,APB1预分频器"/4",APB2预分频器"/2“。我非常确定我的时钟是在它们应该的位置,以验证我设置了TIMER12,它共享APB1时钟,并将预分频器设置为8400,并且每当存在比较匹配(CCR = 5000)和溢出时都会生成一个中断。我用示波器测量了一下,我得到了一个预期的1 Hz方波,这意味着定时器12的APB1是84 MHz。

这是我的时钟初始化代码:

代码语言:javascript
复制
void SysClockConfig ( void ){

    //setting up the MCO output to see the clock signal
    //RCC->CFGR |= ( 6 << 24 ) | (3 << 21 ) | ( 4 << 27 );

    //1. ENABLE HSE and wait for the HSE to become Ready
    RCC->CR |= RCC_CR_HSEON;
    while (!(RCC->CR & RCC_CR_HSERDY));

    // 2. Set the POWER ENABLE CLOCK and VOLTAGE REGULATOR
    RCC->APB1ENR  |= RCC_APB1ENR_PWREN;
    PWR->CR |= PWR_CR_VOS;

    // 3. Configure the FLASH PREFETCH and the LATENCY Related Settings
    FLASH->ACR = FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_PRFTEN | FLASH_ACR_LATENCY_5WS;

    //4. Configure the PRESCALARS HCLK, PCLK1, PCLK2
    // AHB PR
    RCC->CFGR |= RCC_CFGR_HPRE_DIV1;

    // APB1 PR
    RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;

    // APB2 PR
    RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;

    //5. Configure the MAIN PLL
    RCC->PLLCFGR = (PLL_M << RCC_PLLCFGR_PLLM_Pos) | (PLL_N << RCC_PLLCFGR_PLLN_Pos) | (PLL_Q << RCC_PLLCFGR_PLLQ_Pos) | (RCC_PLLCFGR_PLLSRC_HSE);

    //6. Enable the PLL and wait for it to become ready
    RCC->CR |= RCC_CR_PLLON;
    while (!(RCC->CR & RCC_CR_PLLRDY));

    //7. Set source
    RCC->CFGR |= RCC_CFGR_SW_PLL;
    while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL);
}

这是我的UART2配置代码:

代码语言:javascript
复制
void UART2_Config ( void )
{
    RCC->APB1ENR |= RCC_APB1ENR_USART2EN;  //clock UART
    RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;   //clock GPIOA
    GPIOA->MODER |= ( 2 << GPIO_MODER_MODER2_Pos ) | ( 2 << GPIO_MODER_MODER3_Pos ); //set PA2 and PA3 alternate function
    GPIOA->OSPEEDR |= ( 3 << GPIO_OSPEEDR_OSPEED2_Pos ) | ( 3 << GPIO_OSPEEDR_OSPEED3_Pos ); //clock GPIO pin at fastest speed
    GPIOA->AFR[0] |= ( 7 << GPIO_AFRL_AFSEL2_Pos ) | ( 7 << GPIO_AFRL_AFSEL3_Pos ); //set PA2 and PA3 to alt func UART2

    USART2->CR1 = 0;
    USART2->CR1 |= USART_CR1_UE;  //UART Enable
    //USART2->BRR = (0x16 << USART_BRR_DIV_Mantissa_Pos) | (0xc << USART_BRR_DIV_Fraction_Pos);  //Set Baud rate
    USART2->BRR = 4300;
    //USART2->CR1 |= USART_CR1_RE;  //Receiver enable
    USART2->CR1 |= USART_CR1_TE;  //Transmitter enable
    //Baud rate is off by a factor of 12ish
}

最后,我的main和while循环包含用于发送字符的函数:

代码语言:javascript
复制
void UART2_SendChar ( uint8_t c )
{
    USART2->DR = c;
    while ( !(USART_SR_TC));
}

int main ( void )
{
    SysClockConfig();
    GPIO_Config();
    TIM10_Config();
    TIM12_Config();
    UART2_Config();
    //NVIC_SetPriority (TIM1_UP_TIM10_IRQn, 1);
    //NVIC_EnableIRQ(TIM1_UP_TIM10_IRQn);

    NVIC_SetPriority (TIM8_BRK_TIM12_IRQn, 1);
    NVIC_EnableIRQ(TIM8_BRK_TIM12_IRQn);
    while ( 1 )
    {
        //GPIOD->BSRR |= (1<<12);
        //delay(2000000);
        //GPIOD->BSRR |= (1<<28);
        delay(4000000);
        UART2_SendChar('a');
    }
}

我在参考手册中找不到任何东西来解释这种行为。这告诉我我做错了什么,但我似乎找不到它。

EN

回答 1

Stack Overflow用户

发布于 2021-07-04 15:30:57

我最近回答了一个类似的问题here,所以让我复制这个问题:

BRRQ12.4格式的定点数,选择OVER8方式时需要进行一次额外的运算。

OP的问题是关于STM32F4的,但如果查看STM32F030参考手册,他/她可以找到相同的逻辑,但由不同的公式表示。国际海事组织,其中一个(F030)更清晰,更容易理解。

要将uint16_t (Q16.0)转换为Q12.4,需要将其乘以16。

基本上,对于OVER16来说,BRR简单地变成了PeripheralClock / BaudRate

对于OVER8,您首先需要将临时变量计算为temp = 2 * PeripheralClock / BaudRate。将其写入BRR时,需要将其低4位右移一次。

请参见示例代码:

代码语言:javascript
复制
void setBaudRate(uint32_t baud, bool over8)
{
    const uint32_t pClock = 42000000ull; // Hard-code or call a function to obtain it
    uint32_t usartDiv = (over8) ? (2 * pClock / baud) : (pClock / baud);

    uint32_t reg = USART1->BRR;
    reg &= ~0xffff; // Clear the lower 16 bits
    if (over8) {
        reg |= (usartDiv & 0xfff0) | ((usartDiv & 0xf) >> 1);
    }
    else { // over16
        reg |= usartDiv;
    }
    USART1->BRR = reg;
}

因此,对于您的情况,BRR的正确值是4375

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68240003

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档