ST意法半导体
直播中

孙成红

8年用户 1451经验值
私信 关注
[问答]

如何通过写入RCC和FLASH寄存器以配置时钟呢?

我正在学习 Udemy 课程,我们正在学习从头开始制作驱动程序。我知道,这不实用,但它教会了我如何做到这一点,并帮助我学会了如何更好地阅读数据表。无论如何,我已经编写了以下代码来写入 RCC 和 FLASH 寄存器以配置时钟。虽然我怎么能测试这个?我试图打开和关闭输出引脚,它看起来非常慢,大约 1.4MHz。我也在直接操作输出寄存器。对这个 32 位初学者有什么提示吗?

回帖(1)

张建

2023-1-9 14:32:27
感谢大家的投入!看完这个,研究其他地方,经过更多的修补,我终于让它工作了。尽管学习如何从头开始制作我自己的驱动程序很有价值(我现在更了解其他驱动程序现在所做的事情),但我决定使用 CMSIS 标头定义我已经足够自在了。尽管我仍然对使用 ST HAL 犹豫不决,因为我正在做的事情从直接寄存器操作(模拟游戏控制器协议)中受益匪浅。下面是我对 STM32F407VG 的最终代码,以 180MHz 运行,使用 8MHz 外部晶振,以便将来其他人受益。


  • static void configure_clock()
  • {
  •         /* Clock Settings for 168MHz
  •            HCLK = 168
  •            PLL: M = 8, N = 336, P = 2, Q = 7
  •            AHB prescaler = 1
  •            APB prescaler1 = 4, APB prescaler2 = 2
  •            MCO1 prescaler = 2 */

  •         // Configures flash latency.
  •         // LATENCY: bits 2-0
  •         MODIFY_REG(FLASH->ACR,
  •                 FLASH_ACR_LATENCY,
  •                 _VAL2FLD(FLASH_ACR_LATENCY,
  •                 FLASH_ACR_LATENCY_5WS) //FLASH_ACR_LATENCY_5WS << FLASH_ACR_LATENCY_Pos
  •         );

  •         // Enables HSE.
  •         // HSE_ON: bit 16
  •         SET_BIT(RCC->CR, RCC_CR_HSEON);

  •         // Waits until HSE is stable.
  •         // HSERDY: bit 17
  •         while (!READ_BIT(RCC->CR, RCC_CR_HSERDY));

  •         // Configures PLL: source = HSE, PLLCLK = 168MHz.
  •         // M: bits 5-0, N: bits 14-6, P: bits 17-16, PLLSRC: bit 22, Q: bits 27-24
  •         MODIFY_REG(RCC->PLLCFGR,RCC_PLLCFGR_PLLM | RCC_PLLCFGR_PLLN | RCC_PLLCFGR_PLLQ | RCC_PLLCFGR_PLLSRC
  •                         | RCC_PLLCFGR_PLLP,_VAL2FLD(RCC_PLLCFGR_PLLM, 8) | _VAL2FLD(RCC_PLLCFGR_PLLN, 336)
  •                         | _VAL2FLD(RCC_PLLCFGR_PLLQ, 7) | RCC_PLLCFGR_PLLSRC_HSE);

  •         // Enables PLL module.
  •         // PLLON: bit 24
  •         SET_BIT(RCC->CR, RCC_CR_PLLON);

  •         // Waits until PLL is stable.
  •         // PLLRDY: bit 25
  •         while (!READ_BIT(RCC->CR, RCC_CR_PLLRDY));

  •         // Switches system clock to PLL.
  •         // SW: bits 1-0
  •         MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, _VAL2FLD(RCC_CFGR_SW, RCC_CFGR_SW_PLL));

  •         // Configures PPRE1 = 4
  •         MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, _VAL2FLD(RCC_CFGR_PPRE1, 5));

  •         // Configures PPRE2 = 2
  •         MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, _VAL2FLD(RCC_CFGR_PPRE1, 4));

  •         // Configures HPRE = 1
  •         MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, _VAL2FLD(RCC_CFGR_PPRE1, 1));

  •         // Waits until PLL is used.
  •         while(READ_BIT(RCC->CFGR, RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL);

  •         // Disables HSI.
  •         CLEAR_BIT(RCC->CR, RCC_CR_HSION);
  • }

  • void configure_mco1()
  • {
  •         // Configures MCO1: source = PLLCLK, MCO1PRE = 2.
  •         MODIFY_REG(RCC->CFGR,
  •                 RCC_CFGR_MCO1 | RCC_CFGR_MCO1PRE,
  •                 _VAL2FLD(RCC_CFGR_MCO1, 3) | _VAL2FLD(RCC_CFGR_MCO1PRE, 7)
  •         );

  •         // Enables GPIOA (MCO1 is connected to PA8).
  •         SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOAEN);

  •         // Configures PA8 as medium speed.
  •         MODIFY_REG(GPIOA->OSPEEDR,
  •                 GPIO_OSPEEDR_OSPEED8,
  •                 _VAL2FLD(GPIO_OSPEEDR_OSPEED8, 1)
  •         );

  •         // Configures PA8 to work in alternate function mode.
  •         MODIFY_REG(GPIOA->MODER,
  •                 GPIO_MODER_MODER8,
  •                 _VAL2FLD(GPIO_MODER_MODER8, 2)
  •         );
  • }
举报

更多回帖

发帖
×
20
完善资料,
赚取积分