簡體   English   中英

如何正確配置STM32L476RG uC中的USART_BRR寄存器?

[英]How to properly configure the USART_BRR register in STM32L476RG uC?

我正在嘗試在 STM32L476RG Nucleo 板上編寫自己的 USART_TX 驅動程序。 這里是數據表參考手冊

我正在使用 Keil uVision 5,並在“管理”對話框中設置:

  • CMSIS > 核心
  • 設備 > 啟動
  • Xtal=16MHz

我想創建一個單字符發射器。 根據 Sec 中的手冊說明。 40 p 1332 我寫了這段代碼:

// APB1 connects USART2
// The USART2 EN bit on APB1ENR1 is the 17th
// See alternate functions pins and label for USART2_TX! PA2 is the pin and AF7 (AFRL register) is the function to be set


#include "stm32l4xx.h"                  // Device header

#define MASK(x) ((uint32_t) (1<<(x)));

void USART2_Init(void);
void USART2_Wr(int ch);
void delayMs(int delay);

int main(void){
    USART2_Init();


    while(1){
    USART2_Wr('A');
    delayMs(100);


    }
}

void USART2_Init(void){
    RCC->APB1ENR1 |= MASK(17); // Enable USART2 on APB1
    // we know that the pin that permits the USART2_TX is the PA2, so...
    RCC->AHB2ENR |= MASK(0); // enable GPIOA

    // Now, in GPIOA 2 put the AF7, which can be set by placing AF7=0111 in AFSEL2 (pin2 selected)
    // AFR[0] refers to GPIOA_AFRL register
    // Remember: each pin asks for 4 bits to define the alternate functions. see pg. 87 
    // of the datasheet
    GPIOA->AFR[0] |= 0x700; 
    GPIOA->MODER &= ~MASK(4);// now ... we set the PA2 directly with moder as alternate function "10"

    // USART Features -----------

    //USART2->CR1 |=MASK(15); //OVER8=1
    USART2->BRR = 0x683; //USARTDIV=16Mhz/9600?
    //USART2->BRR = 0x1A1; //This one works!!!
    USART2->CR1 |=MASK(0); //UE
    USART2->CR1 |=MASK(3); //TE

}

void USART2_Wr(int ch){
    //wait when TX buffer is empty
    while(!(USART2->ISR & 0x80)) {} //when data is transfered in the register the ISR goes 0x80.
        //then we lock the procedure in a while loop until it happens
        USART2->TDR =(ch & 0xFF); 

}

void delayMs(int delay){
int i;
    for (; delay>0; delay--){
        for (i=0; i<3195; i++);
    }
}

現在,問題:

系統工作,但不正常。 我的意思是:如果我以 9600 波特率使用 RealTerm,如 USART_BRR reg 中的 0x683 所配置,它會顯示錯誤的字符,但如果我將 2400 設置為實際波特率,它會起作用!

為了在 USART_BRR reg 中提取 0x683,我參考了Sec。 40.5.4 USART 波特率生成,如果 OVER8=0,USARTDIV=BRR。 就我而言,USARTDIV=16MHz/9600=1667d=683h。

我認為問題在於這個代碼行:

USART2->BRR = 0x683; //USARTDIV=16Mhz/9600?

因為如果我將其替換為

USART2->BRR = 0x1A1; //USARTDIV=16Mhz/9600?

系統以 9600 波特率工作。

我的代碼或 USARTDIV 計算理解有什么問題?

預先感謝您對我們的支持。

真誠的,通用汽車

USART 的默認時鍾源是PCLK1 (圖 15) PCLK1SYSCLK / AHB_PRESC / AHB1_PRESC 如果0x1A1導致波特率為 9600,則表明PCLK1 = 4MHz。

當從內部 MSI RC 振盪器運行時,4MHz 恰好是您的處理器(和PCLK1 )在啟動時的默認頻率。 所以最可能的解釋是您沒有配置時鍾樹,並且沒有像您認為的那樣從 16MHz HSE 運行。

將時鍾樹配置為使用 16MHz 源,或對 MSI 頻率執行計算。 MSI 精度在正常溫度范圍內幾乎足夠好,可以保持足夠准確的波特率,但並不理想。

關於克利福德的回答(謝謝!)有沒有一種簡單的方法可以在啟動之外更改SYSCLK

例如,通過對RCC_CR寄存器中的MSIRANGE位域進行編程?

謝謝你,通用汽車

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM