STM32F407-RCC配置 联系客服

发布时间 : 星期日 文章STM32F407-RCC配置更新完毕开始阅读3c11ec1925c52cc58bd6bed8

现。

我们借助CAN总线的例子继续说明RCC的作用。

接着上面的例子,例如:

我们使用 STM32F407 与 STM32F103 进行CAN通信,且到这一步已经保证所有的配置都正确,波特率 为 1 M/s。

其中STM32F407 与 STM32103 的CAN 都配置成:

CAN_InitStruct.CAN_Prescaler = 2; CAN_InitStruct.CAN_SJW = CAN_SJW_1tq; CAN_InitStruct.CAN_BS1 = CAN_BS1_9tq; CAN_InitStruct.CAN_BS2 = CAN_BS2_8tq;

这样 STM32F407 与 STM32F103 在绝大多数情况下是无法通信的,原因如下:

启动后,STM32F407 自动执行 SystemInit() ,并配置成如下规格:(可在库函数中找到)

根据上图,即可知启动后的STM32F407:

SYSCLK = 168MHz

HCLK = SYSCLK/1 = 168MHz PCLK1 = HCLK/4 = 42MHz

STM32F407 的 CAN属于 APB1,又由于CAN_InitStruct.CAN_Prescaler = 2; 则 CAN的时钟为 PCLK1/2 = 21 MHz。

根据前面我们对CAN的配置:

CAN_InitStruct.CAN_Prescaler = 2; CAN_InitStruct.CAN_SJW = CAN_SJW_1tq; CAN_InitStruct.CAN_BS1 = CAN_BS1_9tq; CAN_InitStruct.CAN_BS2 = CAN_BS2_8tq;

我们CAN的波特率实际上是:

CAN 波特率 = (1+9+8)/ 21 = 0.857 M/s (并非 1 M/s)

而同样对于STM32103,默认情况下:

SYSCLK = 72 MHz

HCLK = SYSCLK/1 = 72MHz PCLK = HCLK/2 = 36MHz,

因而根据配置:

CAN_InitStruct.CAN_Prescaler = 2; CAN_InitStruct.CAN_SJW = CAN_SJW_1tq; CAN_InitStruct.CAN_BS1 = CAN_BS1_9tq; CAN_InitStruct.CAN_BS2 = CAN_BS2_8tq; CAN时钟 = 18 MHz。

因此对于STM32F103:

CAN波特率 = (1+9+8)/18 = 1 M/s

STM32F407 CAN为 0.857 M/s ,而STM32F103 CAN为 1 M/s,因此无法通信。

为了实现通信,我们需要使得 STM32F407 和 STM32F103 CAN的最终时钟相一致,这一点可以通过配置RCC 实现。在这个例子中可以直接通过修改CAN的预分频,但归根结底就是要正确配置RCC。

(写到这里,有一点我不确定:APB外设的时钟是否有最大值限制?因为根据参考手册 图标上有:

是不是外设的最高时钟只能到 48MHz ? 这一点希望各位深入研究一下。)

下面介绍RCC库函数的使用

在V1.0.0版本的库中,提供了如下函数:

(选择stm32f4xx_rcc.h把文件拉到最后,所有的文件都可以这么做来查看函数)

这里介绍棕色标记的函数。

/* Function used to set the RCC clock configuration to the default reset state */ /*用于配置RCC时钟和复位的函数*/ void RCC_DeInit(void);

/* Internal/external clocks, PLL, CSS and MCO configuration functions *****/ /*内部外部时钟,PLL,CSS,MCO配置函数*/ void RCC_HSEConfig(uint8_t RCC_HSE); ErrorStatus RCC_WaitForHSEStartUp(void);

void RCC_AdjustHSICalibrationValue(uint8_t HSICalibrationValue); void RCC_HSICmd(FunctionalState NewState); void RCC_LSEConfig(uint8_t RCC_LSE); void RCC_LSICmd(FunctionalState NewState);

void RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t PLLM, uint32_t PLLN, uint32_t PLLP, uint32_t PLLQ);

void RCC_PLLCmd(FunctionalState NewState);

void RCC_PLLI2SConfig(uint32_t PLLI2SN, uint32_t PLLI2SR); void RCC_PLLI2SCmd(FunctionalState NewState);

void RCC_ClockSecuritySystemCmd(FunctionalState NewState);

void RCC_MCO1Config(uint32_t RCC_MCO1Source, uint32_t RCC_MCO1Div); void RCC_MCO2Config(uint32_t RCC_MCO2Source, uint32_t RCC_MCO2Div);

/* System, AHB and APB busses clocks configuration functions ******************/ /*系统时钟,AHB时钟,APB时钟配置函数*/

void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource);

uint8_t RCC_GetSYSCLKSource(void);

void RCC_HCLKConfig(uint32_t RCC_SYSCLK); void RCC_PCLK1Config(uint32_t RCC_HCLK); void RCC_PCLK2Config(uint32_t RCC_HCLK);

void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks);

/* Peripheral clocks configuration functions **********************************/ /*外设时钟配置函数*/

void RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource); void RCC_RTCCLKCmd(FunctionalState NewState);

void RCC_BackupResetCmd(FunctionalState NewState); void RCC_I2SCLKConfig(uint32_t RCC_I2SCLKSource);

void RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState); void RCC_AHB2PeriphClockCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState); void RCC_AHB3PeriphClockCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState); void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState); void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);

void RCC_AHB1PeriphResetCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState); void RCC_AHB2PeriphResetCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState); void RCC_AHB3PeriphResetCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState); void RCC_APB1PeriphResetCmd(uint32_t RCC_APB1Periph, FunctionalState NewState); void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);

void RCC_AHB1PeriphClockLPModeCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState);

void RCC_AHB2PeriphClockLPModeCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState);

void RCC_AHB3PeriphClockLPModeCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState);

void RCC_APB1PeriphClockLPModeCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);

void RCC_APB2PeriphClockLPModeCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);

/* Interrupts and flags management functions **********************************/ /*中断和标志管理函数*/

void RCC_ITConfig(uint8_t RCC_IT, FunctionalState NewState); FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG); void RCC_ClearFlag(void);

ITStatus RCC_GetITStatus(uint8_t RCC_IT); void RCC_ClearITPendingBit(uint8_t RCC_IT);