STM32F407标准库学习笔记-RCC

STM32F407标准库学习笔记-RCC

- rcc.h

typedef struct
{
  uint32_t SYSCLK_Frequency; /*!<  SYSCLK clock frequency expressed in Hz */
  uint32_t HCLK_Frequency;   /*!<  HCLK clock frequency expressed in Hz   */
  uint32_t PCLK1_Frequency;  /*!<  PCLK1 clock frequency expressed in Hz  */
  uint32_t PCLK2_Frequency;  /*!<  PCLK2 clock frequency expressed in Hz  */
}RCC_ClocksTypeDef;
时钟频率集合

之后有大量宏定义,主要用途有:
时钟源开关、时钟源选择、分/倍频系数、启动标志、中断标志、外设时钟使能

#define RCC_HSE_OFF                      ((uint8_t)0x00)
#define RCC_LSE_HIGHDRIVE_MODE         	 ((uint8_t)0x01)
#define RCC_PLLSAIDivR_Div16             ((uint32_t)0x00030000)
#define RCC_PLLSource_HSE                ((uint32_t)0x00400000)
#define RCC_SYSCLKSource_HSE             ((uint32_t)0x00000001)
#define RCC_IT_HSIRDY                    ((uint8_t)0x04)
#define RCC_AHB1ClockGating_APB1Bridge   ((uint32_t)0x00000001)
#define RCC_AHB1Periph_GPIOA             ((uint32_t)0x00000001)

函数声明

void        RCC_HSEConfig(uint8_t RCC_HSE);
...

- rcc.c

#define RCC_OFFSET                (RCC_BASE - PERIPH_BASE)
/* --- CR Register ---*/
/* Alias word address of HSION bit */
#define CR_OFFSET                 (RCC_OFFSET + 0x00)
#define HSION_BitNumber           0x00
#define CR_HSION_BB               (PERIPH_BB_BASE + (CR_OFFSET * 32) + (HSION_BitNumber * 4))
rcc寄存器中各位对应的位带区寄存器地址计算
  • 内外时钟\PLL\CSS\MCO配置函数段
void RCC_DeInit(void)
直接使用HSI作为系统时钟;
HSE\PLL相关\CSS\MCO\中断关闭
各总线分频系数设为1
没有改动外设时钟、低速时钟源、RTC
void RCC_HSEConfig(uint8_t RCC_HSE)
{
  /* Reset HSEON and HSEBYP bits before configuring the HSE ------------------*/
  *(__IO uint8_t *) CR_BYTE3_ADDRESS = RCC_HSE_OFF;

  /* Set the new HSE configuration -------------------------------------------*/
  *(__IO uint8_t *) CR_BYTE3_ADDRESS = RCC_HSE;
}
	HSE配置函数
		用于 开 关 旁路 HSE时钟源;
		执行中会先复位各位(关闭HSE);
		同时会关闭CSS;
		打开HSE后应等待HSERDY位置位,以确定HSE工作正常;
		被通过PLL用作系统时钟时,HSE不可关闭,应先更换时钟源;
		关闭HSE后,HSERDY会在6个时钟周期后复位清零。
ErrorStatus RCC_WaitForHSEStartUp(void)
{
  __IO uint32_t startupcounter = 0;
  ErrorStatus status = ERROR;
  FlagStatus hsestatus = RESET;
  /* Wait till HSE is ready and if Time out is reached exit */
  do
  {
    hsestatus = RCC_GetFlagStatus(RCC_FLAG_HSERDY);
    startupcounter++;
  } while((startupcounter != HSE_STARTUP_TIMEOUT) && (hsestatus == RESET));

  if (RCC_GetFlagStatus(RCC_FLAG_HSERDY) != RESET)
  {
    status = SUCCESS;
  }
  else
  {
    status = ERROR;
  }
  return (status);
}
等待HSE启动函数
借助 RCC_GetFlagStatus(RCC_FLAG_HSERDY); 函数与 do while 循环判断HSE启动状况
使用了标志位状态枚举变量
返回值是错误状态枚举变量
void RCC_AdjustHSICalibrationValue(uint8_t HSICalibrationValue)
HSI时钟矫正函数
可用于根据电压 温度来矫正HSI频率准确度
标准的读 复位 改 写
void RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t PLLM, uint32_t PLLN, uint32_t PLLP, uint32_t PLLQ)
{
  RCC->PLLCFGR = PLLM | (PLLN << 6) | (((PLLP >> 1) -1) << 16) | (RCC_PLLSource) |
                 (PLLQ << 24);
}
PLL配置函数
选择PLL时钟源,设置一系列分频倍频系数
注意PLLP的计算方法,系数与写入值并非直接对应,需要变化。
推荐 时钟源/PLLM = 2Mhz (1~2M之间)
在PLL关闭时才能生效
void RCC_PLLCmd(FunctionalState NewState)
{
  *(__IO uint32_t *) CR_PLLON_BB = (uint32_t)NewState;
}
PLL开关函数
开启PLL后应等待启动完成

后面还有许多模块的PLL时钟配置与开关,大同小异

void RCC_ClockSecuritySystemCmd(FunctionalState NewState)
开启CSS功能
如果HSE发生故障,会主动关闭HSE并且产生一个CSS中断
使得MCU运行紧急操作,并且该中断与M4内核中断相链接。
  • 系统\各总线配置函数段
void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource)
{
  uint32_t tmpreg = 0;
  tmpreg = RCC->CFGR;
  /* Clear SW[1:0] bits */
  tmpreg &= ~RCC_CFGR_SW;
  /* Set SW[1:0] bits according to RCC_SYSCLKSource value */
  tmpreg |= RCC_SYSCLKSource;
  /* Store the new value */
  RCC->CFGR = tmpreg;
}
选择sysclk时钟源
配置 RCC->CFGR 的 SW 位;
uint8_t RCC_GetSYSCLKSource(void)
{
  return ((uint8_t)(RCC->CFGR & RCC_CFGR_SWS));
}
查询sysclk时钟源
返回 RCC->CFGR 的 SWS 位(bit2~3)
void RCC_HCLKConfig(uint32_t RCC_SYSCLK)
设置AHB总线分频系数,产生HCLK时钟
后面是设置APB总线频率的两个函数,雷同
void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks)
查询 sysclk/hclk/pclk 频率
注意 右移一位=除以2 两位=除以4 ……
构造了一个数组来对应寄存器位值与右移位数
  • 外设时钟配置函数段
    一系列与I2S、RTC、低功耗、备份寄存器相关的始终设置
    一系列总线外设的时钟开关、外设复位、低功耗时钟等
  • 中断与标志位管理函数段
void RCC_ITConfig(uint8_t RCC_IT, FunctionalState NewState)
{
  if (NewState != DISABLE)
  {
    /* Perform Byte access to RCC_CIR[14:8] bits to enable the selected interrupts */
    *(__IO uint8_t *) CIR_BYTE2_ADDRESS |= RCC_IT;
  }
  else
  {
    /* Perform Byte access to RCC_CIR[14:8] bits to disable the selected interrupts */
    *(__IO uint8_t *) CIR_BYTE2_ADDRESS &= (uint8_t)~RCC_IT;
  }
}
使能特定RCC准备中断
FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG)
可以用不同的位段包含不同的信息
	比如后五位代表BIT位数
	前面代表位于哪个寄存器
	RCC_FLAG_HSERDY    0x31   0b110001     0b1=1=RCC_CR    0b10001=17=bit17
获取 RCC准备 标志位
void RCC_ClearFlag(void)
清除各种复位标志
ITStatus RCC_GetITStatus(uint8_t RCC_IT)
检查RCC中断标志位
void RCC_ClearITPendingBit(uint8_t RCC_IT)
复位RCC中断标志
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值