设置 | 登录 | 注册

目前共有2篇帖子。

【程序】STM32L476RG用寄存器通過PLL將MSI時鐘倍頻到72MHz並設為系統時鐘

1楼 巨大八爪鱼 2017-6-20 19:59
#include <stdio.h>
#include <stm32l476xx.h>

int fputc(int ch, FILE *fp)
{
    if (fp == &__stdout)
    {
        if (ch == '\n')
        {
            while ((USART2->ISR & USART_ISR_TXE) == 0);
            USART2->TDR = '\r';
        }
        while ((USART2->ISR & USART_ISR_TXE) == 0);
        USART2->TDR = ch;
    }
    return ch;
}

int main(void)
{
    uint8_t flag = 0;
    RCC->APB1ENR1 |= RCC_APB1ENR1_PWREN;
    PWR->CR1 |= PWR_CR1_DBP; // 允許訪問備用區域寄存器
    
    // 打開LSE
    if ((RCC->BDCR & RCC_BDCR_LSEON) == 0)
    {
        RCC->BDCR |= RCC_BDCR_LSEON;
        while ((RCC->BDCR & RCC_BDCR_LSERDY) == 0); // 等待LSE穩定
        flag = 1;
    }
    RCC->CR = (RCC->CR & ~RCC_CR_MSIRANGE) | RCC_CR_MSIRANGE_7 | RCC_CR_MSIRGSEL // MSI選8MHz時鐘
                | RCC_CR_MSIPLLEN; // 且使用LSE校準MSI
    
    // 配置PLL: MSI/M*N/R=8MHz/1*18/2=72MHz
    RCC->PLLCFGR = RCC_PLLCFGR_PLLREN | RCC_PLLCFGR_PLLN_4 | RCC_PLLCFGR_PLLN_1 | RCC_PLLCFGR_PLLSRC_MSI;
    RCC->CR |= RCC_CR_PLLON;
    while ((RCC->CR & RCC_CR_PLLRDY) == 0); // 等待PLL穩定
    
    // 根據參考手冊3.3.3 Read access latency, Table 11. Number of wait states according to CPU clock (HCLK) frequency
    // CPU時鐘要達到64MHz以上, LATENCY必須為4WS
    // 由PWR_CR1_VOS可知當前V_CORE為Range 1 (最高時鐘頻率80MHz)
    FLASH->ACR |= FLASH_ACR_LATENCY_4WS; // 參閱: Increasing the CPU frequency
    while ((FLASH->ACR & FLASH_ACR_LATENCY) != FLASH_ACR_LATENCY_4WS);
    
    // 將PLL選作系統時鐘
    RCC->CFGR |= RCC_CFGR_SW;
    while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS);
    
    // LED燈配置
    RCC->AHB2ENR = RCC_AHB2ENR_GPIOAEN;
    GPIOA->MODER &= ~GPIO_MODER_MODE5_1;
    GPIOA->BSRR = GPIO_BSRR_BS5; // LED燈亮
    
    // 配置串口2
    RCC->APB1ENR1 |= RCC_APB1ENR1_USART2EN;
    GPIOA->MODER &= ~(GPIO_MODER_MODE2_0 | GPIO_MODER_MODE3_0 | GPIO_MODER_MODE9_0 | GPIO_MODER_MODE10_0);
    GPIOA->AFR[0] = GPIO_AFRL_AFSEL2_2 | GPIO_AFRL_AFSEL2_1 | GPIO_AFRL_AFSEL2_0;
    GPIOA->AFR[0] |= GPIO_AFRL_AFSEL3_2 | GPIO_AFRL_AFSEL3_1 | GPIO_AFRL_AFSEL3_0;
    USART2->BRR = 72000000 / 115200; // 被除數為時鐘頻率, 除數為波特率
    USART2->CR1 = USART_CR1_UE | USART_CR1_TE;
    
    // 需要延時一會兒才能使用USART2, 否則會亂碼
    // 使用定時器2延時
    RCC->APB1ENR1 |= RCC_APB1ENR1_TIM2EN;
    //TIM2->ARR = 9999; // 10kHz/10000=1Hz -> 1s
    TIM2->ARR = 9; // 10kHz/10=1kHz -> 1ms
    TIM2->PSC = 7199; // 72MHz/7200=10kHz
    TIM2->CR1 = TIM_CR1_OPM | TIM_CR1_URS;
    TIM2->EGR = TIM_EGR_UG;
    TIM2->CR1 |= TIM_CR1_CEN;
    while ((TIM2->SR & TIM_SR_UIF) == 0);
    
    printf("It works!!!\n");
    if (flag)
        printf("LSE has been connected!\n"); // 只有上電時才會顯示這句話
    printf("PWR->CR1=0x%08x\n", PWR->CR1);
    printf("RCC->BDCR=0x%08x\n", RCC->BDCR);
    printf("RCC->CFGR=0x%08x\n", RCC->CFGR);
    printf("RCC->CR=0x%08x\n", RCC->CR);
    printf("RCC->PLLCFGR=0x%08x\n", RCC->PLLCFGR);
    printf("USART2->BRR=%d\n", USART2->BRR);
    GPIOA->BRR = GPIO_BRR_BR5; // LED燈滅
    
    while (1);
}
2楼 巨大八爪鱼 2017-6-20 20:15
【程序運行結果】
It works!!!
PWR->CR1=0x00000300
RCC->BDCR=0x00000003
RCC->CFGR=0x0000000f
RCC->CR=0x0300007f
RCC->PLLCFGR=0x01001201
USART2->BRR=625

内容转换:

回复帖子
内容:
用户名: 您目前是匿名发表。
验证码:
看不清?换一张
©2010-2025 Purasbar Ver3.0 [手机版] [桌面版]
除非另有声明,本站采用知识共享署名-相同方式共享 3.0 Unported许可协议进行许可。