#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); }
|