嵌入式开发笔记:蓝桥杯STM32G431(HAL库)- CT117E学习笔记03:G4时钟结构

系列文章目录

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记01:赛事介绍与硬件平台

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记02:开发环境安装

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记03:G4时钟结构

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记04:从零开始创建工程模板并开始点灯

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记05:Systick滴答定时器

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记06:按键输入

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记07:ADC模数转换

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记08:LCD液晶屏

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记09:EEPROM

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记10:USART串口通讯


目录

系列文章目录

前言

一、时钟结构介绍

二、时钟初始化程序

1.生成程序

2.程序分析

总结


前言

上一篇讲了开发环境的安装,这一篇讲一下STM32G4的时钟结构。

时钟是STM32的很重要的内容,时钟主要就是用来为STM32提供一个工作频率,比如我们的板子就是配置的80MHz的主频,如果加法运算需要四个时钟周期(微机原理的内容),那么4/80M 秒就能完成这个工作。所以我们可以理解为80MHz就是为系统提供的一个时间基准,决定了它运行的速度。

G4的时钟结构是比较复杂的,因为它可以给不同的外设配置不同的时钟频率,比如主频80,定时器可以设置成40,等等。这样做可以降低功耗,还有一个考虑就是有些外设不需要太高的频率。


一、时钟结构介绍

我们打开CubeMX,选择“ACCESS TO MCU CELECTOR",即可根据MCU型号新建工程,然后左上角选择STM32G431RBT6,即进入HAL的初始化,在这里可以配置引脚、时钟等,我们点击clock configuration就可以看到G4芯片的时钟树了,就是在这里配置时钟。

我们先看高速时钟,高速时钟主要有两个,一个是HSE,是指外部的高速时钟,我们看了原理图的话就可以知道芯片外接了一个24MHz的晶振,这里HSE就是来自于外接的晶振。所以我们要把”input frequency“改成24MHz。还有一个是HSI,这个是指内部的高速时钟,它来自于芯片内部的RC振荡,它的频率是固定的,为16MHz,是每个芯片自带的,我们不能通过外设的改变来更改。(这里因为我们前面引脚配置的地方没有配置外部时钟所以改不了HSE,配置引脚就在"Pinout&Configuration"点击”system core“,然后在HSE栏选择crystal晶振就可以自动配好了。配好之后再点”clock configuration“就可以发现HSE可以更改了。我们改成24。)

系统的工作主频是由”system clock mux“这个复选框三选一得到的,既可以直接由HSI和HSE决定,也可以根据PLLCLK决定。前两个都是固定的不能更改,后者是一个锁相环,它可以对频率进行倍频或者分频的处理,所以通过PLLCLK就可以对HSI或HSE进行更改,从而得到不一样的工作主频。所以我们要得到80MHz的主频就要选择PLLCLK。PLLCLK的输入可以选择HSE或者HSI,后面再选择倍频和分频的倍数,通过这个地方的更改就可以得到80MHz,这里如果我们选择内部时钟16MHz的话,就可以采用如下的配置来得到80MHz。

当然我们也可以使用外部时钟,准确度会更高,选择HSE即可,如果分频框出现了红色说明不符合硬件要求,更改一下即可。后面如何配置不加赘述。

现在我们得到了系统主频,那么主频有什么用呢?主频直接连接后面的”power“,即系统功耗控制,这里可以对芯片设置成低功耗的模式等等,一般我们用的不多。也可以通过System后面的分频框更改一些外设的高速时钟。这里比较重要的是APB1和APB2两个分频,分别对应着一些不同的外设。我们可以查看手册看一下分别对应了哪些。

可以看到APB1可以控制定时器、LPUSART、I2C总线等等。

APB2同理。

讲完高速时钟看一下低速时钟,低速也分为外接晶振LSE和内部RC震荡LSI,它的主要作用就是给RTC,即实时时钟,可以进行计时,利用这个可以做STM32的时钟。还有一个就是看门狗,主要是用于STM32出错时进行一些复位操作。但是我们这个板子外部晶振是没有接的,所以只能用内部的RC震荡。

其他的时钟我们用的不多,后续要用的话再讲。

二、时钟初始化程序

1.生成程序

我们按照上一节的步骤设置好引脚和80MHz的时钟后,继续点project manager,设置好项目名字和工程位置,application structure选择basic(advanced一般用于rtos),然后IDE选择MDK-ARM。然后点击左侧的Code Genarator,在Genarated files里面选择第一个生成.c和.h文件。

全部完成后点击Genarate Code即可生成文件。

2.程序分析

打开文件,点击main.c,找到systemclock_config(),右击选择go to definition就可以看到了时钟函数的定义了。

oid SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Configure the main internal regulator output voltage
  */
  HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV1;
  RCC_OscInitStruct.PLL.PLLN = 10;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
  RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}

代码都是CubeMX自己生成的,能看懂通就行,代码的含义就是我们上一章进行的时钟配置。主要是通过  RCC_OscInitTypeDef RCC_OscInitStruct 、  RCC_ClkInitTypeDef RCC_ClkInitStruct 两个结构体的定义完成的。


总结

这一章的主要内容就是如何通过CubeMX进行时钟的初始化,并且自动生成代码。生成的代码与我们的配置是一一对应的,所以就算我们要更改时钟的配置,也不一定要重新在CubeMX里生成,也可以直接在代码上改。

下一章我们会讲GPIO的第一个输出——LED。

作者:我不是板神

物联沃分享整理
物联沃-IOTWORD物联网 » 嵌入式开发笔记:蓝桥杯STM32G431(HAL库)- CT117E学习笔记03:G4时钟结构

发表评论