我需要在不使用 HAL 库的情况下执行一些任务。我正在使用 CMSIS。
首先,我设置了一个带定时器的闪烁 LED。
我按照附图对时钟进行了编程。
tiM6 的源时钟应为 60 MHz,但 LED 的行为与 30 MHz 相同。它以一半的速度闪烁。
当我预计有 500 毫秒的延迟时,LED 会保持亮起(或熄灭)1 秒。我不明白这个因素 2 从何而来。
我究竟做错了什么?
这是代码
- #include
- #include "STM32f2xx.h"
- #if !defined(__SOFT_FP__) && defined(__ARM_FP)
- #warning "FPU is not initialized, but the project is compiling for an FPU. Please initialize the FPU before use."
- #endif
- static void SystemClock_Config();
- void TIM6Config (void);
- void Delay_us (uint16_t us);
- void Delay_ms (uint16_t ms);
- int main(void)
- {
- // uint32_t i;
- SystemClock_Config();
- //NVIC_SetPriority
- RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN;
- GPIOB->MODER |= 0x01 << GPIO_MODER_MODER14_Pos;
- GPIOB->OSPEEDR |= 0x01 << 29;
- //uart (not yet implemented, to be completed)
- //ENABLE PORT D AND USART 3
- RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN;
- RCC->APB1ENR |= RCC_APB1ENR_USART3EN;
- GPIOD->AFR[1] |= (7<<0); //ALTERNATE PD8
- GPIOD->AFR[1] |= (7<<4); //ALTERNATE PD9
- GPIOD->OSPEEDR |= (3<<16) | (3<<18); //HIGH SPEED FOR PD8 AND PD9
- TIM6Config ();
- /* Loop forever */
- while(1) {
- GPIOB->ODR ^= GPIO_ODR_ODR_14;
- Delay_ms (500);
- }
- }
- static void SystemClock_Config()
- {
- #define PLL_M_SETTING 8
- #define PLL_N_SETTING 240
- #define PLL_P_SETTING 0 //PLLP = 2
- // Start HSE in Bypass Mode
- RCC->CR |= RCC_CR_HSEBYP;
- RCC->CR |= RCC_CR_HSEON;
- while(!(RCC->CR & RCC_CR_HSERDY));
- RCC->CFGR |= RCC_CFGR_HPRE_DIV1;
- RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;
- RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;
- RCC->PLLCFGR |= (PLL_M_SETTING << 0) | (PLL_N_SETTING << 6) | (PLL_P_SETTING << 16) | (RCC_PLLCFGR_PLLSRC_HSE);
- RCC->CR |= RCC_CR_PLLON;
- while(!(RCC->CR & RCC_CR_PLLRDY));
- RCC->CFGR |= RCC_CFGR_SW_PLL;
- while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL);
- SystemCoreClockUpdate();
- }
- void TIM6Config (void)
- {
- // 1. Enable Timer clock
- RCC->APB1ENR |= (1<<4); // Enable the timer6 clock
- // 2. Set the prescalar and the ARR
- TIM6->PSC = 60-1; // 1 MHz ~~ 1 uS delay
- TIM6->ARR = 0xffff; // MAX ARR value
- // 3. Enable the Timer, and wait for the update Flag to set
- TIM6->CR1 |= (1<<0); // Enable the Counter
- while (!(TIM6->SR & (1<<0)));
- }
- void Delay_us (uint16_t us)
- {
- TIM6->CNT = 0;
- while (TIM6->CNT < us);
- }
- void Delay_ms (uint16_t ms)
- {
- for (uint16_t i=0; i {
- Delay_us (1000); // delay of 1 ms
- }
- }