STM32F103RCT6开发板M3单片机教程05--RCC配置

2023-12-18 06:29:41


前言


首先了解一下是什么RCC(Reset Clock Control),复位和时钟控制(RCC)
小容量产品是指闪存存储器容量在16K32K字节之间的STM32F101xx,?STM32F102xxSTM32F103xx微控制器。
中容量产品是指闪存存储器容量在64K128K字节之间的STM32F101xx,?STM32F102xxSTM32F103xx微控制器。
大容量产品是指闪存存储器容量在256K512K字节之间的STM32F101xxSTM32F103xx微控制器。
除非特别说明,本章节描述的模块应用于整个STM32F103xx微控制器系列,因为我们使用是STM32F103RCT6开发板是mini最小系统板。
本教程使用是(光明谷SUN_STM32mini开发板
?



一、复位
?

STM32F10xxx支持三种复位形式,分别为系统复位、上电复位和备份区域复位。



1.1?系统复位


系统复位将复位除时钟控制寄存器CSR中的复位标志和备份区域中的寄存器以外的所有寄存器

当以下事件中的一件发生时,产生一个系统复位:
1. NRST管脚上的低电平(外部复位)
2.?窗口看门狗计数终止(WWDG复位)
3.?独立看门狗计数终止(IWDG复位)
4.?软件复位(SW复位)
5.?低功耗管理复位
可通过查看RCC_CSR控制状态寄存器中的复位状态标志位识别复位事件来源。
软件复位
通过将Cortex?-M3中断应用和复位控制寄存器中的SYSRESETREQ位置’1’,可实现软件复位。请参考Cortex?-M3技术参考手册获得进一步信息。
低功耗管理复位
在以下两种情况下可产生低功耗管理复位:
1.?在进入待机模式时产生低功耗管理复位:
通过将用户选择字节中的nRST_STDBY位置’1’将使能该复位。这时,即使执行了进入待机模式的过程,系统将被复位而不是进入待机模式。
2.?在进入停止模式时产生低功耗管理复位:
通过将用户选择字节中的nRST_STOP位置’1’将使能该复位。这时,即使执行了进入停机模式的过程,系统将被复位而不是进入停机模式。
关于用户选择字节的进一步信息,请参考STM32F10xxx闪存编程手册。


1.2?电源复位

当以下事件中之一发生时,产生电源复位:
1.?上电/掉电复位(POR/PDR复位)
2.?从待机模式中返回
电源复位将复位除了备份区域外的所有寄存器。?(见图3)
图中复位源将最终作用于RESET管脚,并在复位过程中保持低电平。复位入口矢量被固定在地
0x0000_0004。更多细节,参阅stm32f10xxx参考手册表36

?



1.3 备份域复位


当以下事件中之一发生时,产生备份区域复位。
1.?软件复位,备份区域复位可由设置备份区域控制寄存器RCC_BDCR中的BDRST位产生。
2.?VDD和VBAT两者掉电的前提下,?VDD或VBAT上电将引发备份区域复位。



二、?时钟


2.1?时钟源


三种不同的时钟源可被用来驱动系统时钟(SYSCLK)
●?HSI振荡器时钟
●?HSE振荡器时钟
●?PLL时钟
这些设备有以下2种二级时钟源:
●?40kHz低速内部RC,可以用于驱动独立看门狗和通过程序选择驱动RTC。?RTC用于从停机/待机模式下自动唤醒系统。

●?32.768kHz低速外部晶体也可用来通过程序选择驱动RTC(RTCCLK)
当不被使用时,任一个时钟源都可被独立地启动或关闭,由此优化系统功耗。
复位和时钟控制?STM32F10xxx参考手


2.2 备份域复位


当以下事件中之一发生时,产生备份区域复位。
1.?软件复位,备份区域复位可由设置备份区域控制寄存器RCC_BDCR中的BDRST位产生。
2.?VDD和VBAT两者掉电的前提下,?VDD或VBAT上电将引发备份区域复位。
?


更多细节,参阅?STM32F10xxx参考手册


2.3 RCC设置流程 

  1、将RCC寄存器重新设置为默认值    RCC_DeInit
  2、打开外部高速时钟晶振HSE      RCC_HSEConfig(RCC_HSE_ON)
  3、等待外部高速时钟晶振工作      HSEStartUpStatus = RCC_WaitForHSEStartUp();
  4、设置AHB时钟            RCC_HCLKConfig
  5、设置高速APB时钟          RCC_PCLK2Config
  6、设置低速APB时钟          RCC_PCLK1Config
  7、设置PLL              RCC_PLLConfig
  8、打开PLL              RCC_PLLCmd(ENABLE)
  9、等待PLL工作            while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET)
  10、设置系统时钟           RCC_SYSCLOCKConfig
  11、判断是否PLL是系统时钟      while(RCC_GetSYSCLKSource()!=0x08)
  12、打开要使用的外设时钟      RCC_APB2PerphClockCmd()/RCC_APB1PeriphClockCmd()


了解基础知识下面实操吧
以前我们其实也有配置,但不具体,基本都本MCU默认的配置,真正用好STM32,还得熟悉RCC.


三、编写程序代码


复制上节工程文件夹打开(这个方法比较方便)

  • 码字:编辑main.c, 在上节基础上增加RCC配置函数。
/**********************************************************************************

* Sun STM32 mini Demo

*? ?Description
? ?

? ? RCC Config Demo
? ?

* Version? ? Date? ?? ? Auther? ?? ?Reversed History

??----------------------------------------------------------------------------

??V1.0.0? ? 2021-11-07??Lojam Fan??Fisrt Created
??

* (C) Sunshine Silicon Corporation

*??Website: http://www.sunsili.com??http://sunsili.taobao.com http://bbs.sunsili.com

*??E-Mail : fan@sunsili.com


**********************************************************************************/


#include "stm32f10x.h"
#include "usart.h"
#include "SysTick.h"
#include "led.h"
#include "key.h"
#include <stdio.h>


extern vu8 Usart1_R_Buff[USART1_REC_MAXLEN];? ?? ???//串口1数据接收缓冲区
extern vu8 Usart1_R_State;? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?//串口1接收状态
extern vu16 Usart1_R_Count;? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?//当前接收数据的字节数? ?? ?? ?
void RCC_Configuration(void);

/*******************************************************************************
* 函数名??: main
* 描述? ? : 主函数,用户程序从main函数开始运行

* 输入? ? : 无
* 输出? ? : 无

* 返回值??: int:返回值为一个16位整形数

* 说明? ? : 无

*******************************************************************************/

int main(void)
{
? ? u8 keyVal;

? ? RCC_Configuration();
? ? SysTick_Init_Config();

? ??USART1_Init_Config(115200);//USART1初始化配置

? ? LED_GPIO_Config();
? ? Key_GPIO_Config();

? ? printf ("*===================================================*\n");
? ? printf ("*??*??Name: Sun STM32 mini Demo Code.? ? *************\n");
? ? printf ("*??* (C) Sunshine Silicon Corporation? ? *************\n");
? ? printf ("*??*??Website: http://www.sunsili.com? ? *************\n");
? ? printf ("*??*? ?E-Mail : fan@sunsili.com? ?? ?? ? *************\n");
? ? printf ("*===================================================*\n");

? ? printf ("* Sun STM32 mini Key Demo code .*\n");? ?

? ?? ??? while (1)
? ?? ???{

? ?? ???        keyVal = Key_Down_Scan();

? ?? ?? ?? ?? ? if(Usart1_R_State == 1)//一帧数据接收完成
? ?? ?? ?? ?? ? {
? ?? ?? ?? ?? ?? ?? ?? ?USART1_SendData((u8 *)Usart1_R_Buff, Usart1_R_Count);? ?//USART1发送数据缓冲区数据(发送刚接收完成的一帧数据)

? ?? ?? ?? ?? ?? ?? ?? ?Usart1_R_State =0;
? ?? ?? ?? ?? ?? ?? ?? ?Usart1_R_Count =0;
? ?? ?? ?? ?? ? }

? ?? ???if(keyVal)
? ?? ???{
? ?? ?? ?? ?printf("KeyVal:%d\r", keyVal);

? ?? ?? ?? ?if(keyVal & 0x01) LED3_ON();?
? ?? ?? ?? ?else if(keyVal & 0x02) LED4_ON();?
? ?? ???}
? ?? ???else LED_ALL_OFF();
? ?? }
}


/*******************************************************************************
* 函数名??: RCC_Configuration

* 描述? ? : 设置系统时钟为72MHZ(这个可以根据需要改)

* 输入? ? : 无
* 输出? ? : 无

* 返回值??: 无

* 说明? ? : STM32F107x和STM32F105x系列MCU与STM32F103x系列MCU时钟配置有所不同

*******************************************************************************/

void RCC_Configuration(void)
{
??ErrorStatus HSEStartUpStatus;? ?? ?? ?? ?? ?//外部高速时钟(HSE)的工作状态变量?

??RCC_DeInit();? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? //将所有与时钟相关的寄存器设置为默认值
??RCC_HSEConfig(RCC_HSE_ON);? ?? ?? ?? ?? ?? ?//启动外部高速时钟HSE
??HSEStartUpStatus = RCC_WaitForHSEStartUp(); //等待外部高速时钟(HSE)稳定


??if(SUCCESS == HSEStartUpStatus)? ?? ?? ?? ? //如果外部高速时钟已经稳定
??{
? ? /* Enable Prefetch Buffer */
? ? FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //Flash设置

? ? /* Flash 2 wait state */
? ? FLASH_SetLatency(FLASH_Latency_2);???

? ? RCC_HCLKConfig(RCC_SYSCLK_Div1); //设置AHB时钟等于系统时钟(1分频)/72MHZ
? ? RCC_PCLK2Config(RCC_HCLK_Div1);??//设置APB2时钟和HCLK时钟相等/72MHz(最大为72MHz)
? ? RCC_PCLK1Config(RCC_HCLK_Div2);??//设置APB1时钟是HCLK时钟的2分频/36MHz(最大为36MHz)? ?

? ? RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); //PLLCLK = 8MHz * 9 = 72 MHz

? ? RCC_PLLCmd(ENABLE); //使能PLL
? ? while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); //等待PLL稳定
? ? RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);? ?? ?? ? //设置系统时钟的时钟源为PLL
? ? while(RCC_GetSYSCLKSource() != 0x08);? ?? ?? ?? ?? ?//检查系统的时钟源是否是PLL
? ? RCC_ClockSecuritySystemCmd(ENABLE);? ?? ?? ?? ?? ???//使能系统安全时钟

? ? RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO,ENABLE);

??}

}




/******************* (C) COPYRIGHT SUNSHINE SILICON??**************************
********************? ?? ???END OF FILE main.c? ?? ???*******************/

四 、编译调试

4.1?编译

保存直接编译,发现编译出错,提示FLASH_PrefetchBufferCmd 和 FLASH_SetLatency函数未定义。解决方法添加库文件stm32f10x_flash.c
重新编译,通过。
?

4.2 调试

方法不再重复,经过前两节练习,大家应该是会了.
效果与前一节是一样,只是我们多了RCC配置。现在效果一样,但是真正项目里RCC是配置不一样,是致命的。

课后作业
改变CPU运行频率

工程源码

查看原文,可下载工程学源码

文章来源:https://blog.csdn.net/u011407864/article/details/135025242
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。