天天看点

GD32系列总结 - 时钟树总结及CubeMX生成代码写在前面时钟树CubeMX配置CubeMX的整体感受

GD32系列总结 - 时钟树总结及CubeMX生成代码

  • 写在前面
  • 时钟树
    • HSE振荡器时钟(高速外部时钟信号)
      • HSE用户外部时钟(旁路模式)
      • HSE外部晶体/陶瓷谐振器
    • HSI振荡器时钟
    • PLL时钟
    • LSE时钟
    • LSI时钟
    • 片内时钟关系
  • CubeMX配置
    • LL库集成
    • CubeMX关键配置
      • Port配置
      • 时钟树
      • Debug
      • 其他配置
  • CubeMX的整体感受

写在前面

由于手里暂时没有GD32的板子,只有一个同系列的STM32,但是封装不一样,不能替换,公司的GD32不好拿来自己玩,鉴于GD32的目标就是完美替换STM32,因此,在我拥有GD32板子之前,先就用STM32F103VE系列为例吧,如果遇见一些GD32的独立问题,我会单独写出来。

关于STM32目前有四种开发方式,寄存器编程,固件库编程,Hal库编程,LL库编程,下面是ST 中文官网上一篇《关于ST库函数的代码性能对比》的文章中对比了各种库的性能的图示:

GD32系列总结 - 时钟树总结及CubeMX生成代码写在前面时钟树CubeMX配置CubeMX的整体感受

寄存器编程无疑是最快的,但是开发难度较大,耗时较长,固件库在公司就是玩这个,不想在家也玩这个,有点不思进取,HAL库为了适配不同型号的移植,内部实现比较耗时,LL库,开发速度较快,功能完善,还能用CubeMX快速生成初始化代码,由于我之前一直用的英飞凌和NXP旗下的EB软件,自己以前在公司里也做过一款这样的配置工具,所以对ST的CubeMX一直很感兴趣,刚好趁这个机会玩一玩,于是果断选择LL库,官网的资料也很丰富,下面我会先就时钟树原理和CubedMX的配置两部分展开。

时钟树

GD32系列总结 - 时钟树总结及CubeMX生成代码写在前面时钟树CubeMX配置CubeMX的整体感受

时钟一共有五种类型时钟:

● HSI振荡器时钟

● HSE振荡器时钟

● PLL时钟

● LSE时钟

● LSI时钟

其中可以用作系统时钟源的有三种:HSI振荡器时钟,HSE振荡器时钟,PLL时钟(蓝色标记)

另外两种时钟:LSE时钟,LSI时钟只能 用于特定外设,不能用于系统时钟源(黑色标记)

HSE振荡器时钟(高速外部时钟信号)

主要产生源为:

● HSE外部晶体/陶瓷谐振器

● HSE用户外部时钟

GD32系列总结 - 时钟树总结及CubeMX生成代码写在前面时钟树CubeMX配置CubeMX的整体感受

下面分别介绍:

HSE用户外部时钟(旁路模式)

(OSC_OUT必须为高阻态)
           

等于外部是一个完整的时钟电路,可以直接输出可供单片机内部使用的方波信号,也就是说不需要单片机内部整形电路参与,上电该电路便能直接产生需要的时钟频率信号,因此,单片机内部的内部整形电路应该被短路(旁路),所以在程序设计时,针对该时钟电路需要用到CR寄存器中的HSEBYP和HSEON位。大致软件流程为:

LL_RCC_DeInit();
	/* Enable HSE oscillator */
	LL_RCC_HSE_EnableBypass();
	LL_RCC_HSE_Enable();
	while(LL_RCC_HSE_IsReady() != 1)
	{
	};
           

HSE外部晶体/陶瓷谐振器

这类时钟由于谐振器+电容的形式只能产生正弦波,所以要产生供单片机内部数字电路使用的方波时钟,还需要使用单片机内部整形电路的参与,然后通过MCU去检测时钟是否稳定,待时钟稳定之后,即在时钟控制寄存器RCC_CR中的HSERDY位被硬件置’1’。时钟才被释放出来。如果在时钟中断寄存器RCC_CIR中允许产生中断,将会产生相应中断。大致软件流程为:

LL_RCC_DeInit();
	LL_RCC_HSE_Enable();
	while(LL_RCC_HSE_IsReady() != 1)
	{
	};
           

HSI振荡器时钟

HSI时钟信号由内部8MHz的RC振荡器产生,可直接作为系统时钟或在2分频后作为PLL输入。HSI RC振荡器能够在不需要任何外部器件的条件下提供系统时钟。它的启动时间比HSE晶体振荡器短。然而,即使在校准之后它的时钟频率精度仍较差。如果HSE晶体振荡器失效,HSI时钟会被作为备用时钟源。大致软件流程为:

RCC->GCCR |= ((uint32_t)RCC_GCCR_HSIEN);
	
	  /* Wait till HSE is ready and if Time out is reached exit */
	  do
	  {
		HIEStatus = RCC->GCCR & RCC_GCCR_HSISTB;
		StartUpCounter++;  
	  } while((HIEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
		
		if ((RCC->GCCR & RCC_GCCR_HSISTB) != RESET)
	  {
		HIEStatus = (uint32_t)0x01;
	  }
	  else
	  {
		HIEStatus = (uint32_t)0x00;
	  }  
           

PLL时钟

根据时钟树来看,PLL时钟的时钟源有两个,分别是HSI时钟二分频之后传入或者HSE时钟经PLLXTPRE不分频或者二分频之后传入,两种时钟源的选择是通过PLLSRC位决定,然后通过倍频后作为PLL时钟输出。大致软件流程为:

/* Main PLL configuration and activation */
	  LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE_DIV_1, LL_RCC_PLL_MUL_9);
	  LL_RCC_PLL_Enable();
	  while(LL_RCC_PLL_IsReady() != 1)
	  {
	  };
           

LSE时钟

LSE晶体是一个32.768kHz的低速外部晶体或陶瓷谐振器。它为实时时钟或者其他定时功能提供一个低功耗且精确的时钟源。目前没有用过该时钟源,所以无相关经验,数据手册说明,该模式只能工作在旁路模式下。

LSI时钟

该时钟是一个内部低速时钟,主要用于独立看门狗的时钟参考,以保证在主时钟失效的情况下,看门狗依旧可以正常工作,在使用看门狗之前,必须将此时钟使能并等他在稳定状态。软件大致流程为:

/****************IRC40K Enable***************/
	  RCC_LSI_Enable(ENABLE);
	  /* wait till IRC40K is ready */
	  while((RCC->GCSR & RCC_GCSR_LSISTB) != RCC_GCSR_LSISTB)
	  {
		
	  }
           

片内时钟关系

在主时钟产生之后,通过各钟预分频配置,最终得到各个外设需要的时钟参考,其中主要的预分频器有:AHB,APB1,APB2。AHB时钟主要是多系统时钟的倍频操作,以便后面经过APB1或者APB2分频或者倍频之后,能产生更多类型的时钟频率,所以在外设初始化之前,应该先保证输出的外设的时钟稳定且是想要的频率,毕竟时钟就是单片机的钟表,如果世界上的表都不准了,时间系统紊乱了,还谈什么996,007的奉献呢?

CubeMX配置

LL库集成

集成大致没什么说的,去官网搜索对应型号的Cube库,如

en.stm32cubef1_v1.8.0

,然后下载完就把启动文件,LL库文件什么的移植到工程里去,好像大概就是这些,可能会有一些报错,具体情况根据报错信息解决,在keil里面可以全局定义几个宏

STM32F103xE,USE_FULL_ASSERT,USE_FULL_LL_DRIVER

,分别是指明MCU型号,开启ASSERT功能(检查实参是否合法,需要实现对应的assert_failed函数),指明使用LL库,其他的好像就没什么了。

GD32系列总结 - 时钟树总结及CubeMX生成代码写在前面时钟树CubeMX配置CubeMX的整体感受

CubeMX关键配置

相关的配置说明文档可以去官网下载

um1718-stm32cubemx-for-stm32-configuration-and-initialization-c-code-generation-stmicroelectronics.pdf``um2739-how-to-create-a-software-pack-enhanced-for-stm32cubemx-using-stm32-pack-creator-tool-stmicroelectronics.pdf

Port配置

GD32系列总结 - 时钟树总结及CubeMX生成代码写在前面时钟树CubeMX配置CubeMX的整体感受

找到你想要配置的PortPin,然后单击选择PortPin的属性即可,选择完之后可以去下图对每个PortPin的输出方式,默认状态,别名等配置。

GD32系列总结 - 时钟树总结及CubeMX生成代码写在前面时钟树CubeMX配置CubeMX的整体感受

时钟树

最开始时钟树界面的外部时钟是不可以修改的,需要先去RCC界面使能外部时钟之后,才能在时钟树界面激活相关的配置,这一点也挺有逻辑的。

GD32系列总结 - 时钟树总结及CubeMX生成代码写在前面时钟树CubeMX配置CubeMX的整体感受

选择是旁路模式还是谐振器模式

GD32系列总结 - 时钟树总结及CubeMX生成代码写在前面时钟树CubeMX配置CubeMX的整体感受

然后在时钟树界面就可以对每一个节点去配置时钟了,图里面都是按照最高频率配置的,如果配错了,他会用红色来提醒你

Debug

GD32系列总结 - 时钟树总结及CubeMX生成代码写在前面时钟树CubeMX配置CubeMX的整体感受

在系统界面还可以对应修改调试器模式,在程序中体现为对调试端口的复用

GD32系列总结 - 时钟树总结及CubeMX生成代码写在前面时钟树CubeMX配置CubeMX的整体感受

其他配置

GD32系列总结 - 时钟树总结及CubeMX生成代码写在前面时钟树CubeMX配置CubeMX的整体感受

红框处可以选择编译器类型

GD32系列总结 - 时钟树总结及CubeMX生成代码写在前面时钟树CubeMX配置CubeMX的整体感受

在Advanced Setting可以选择每个模块对应的库,LL库和HAL库是可以同时用的

最后右上角Generate Code即可生成代码

CubeMX的整体感受

整体来说使用起来逻辑上还是很好接受的,可能生成代码的结构我不太喜欢,比如main.c里面东西太多了,但是可以自己调整一下,也还能接受,整体的UI什么感觉比EB做的好,配置起来也挺简单的,喜欢后面GD32销量上去了也能推出一款类似CubeMX一样的软件,听说GD32今年销量已经有3亿了,国产芯片走到这一步,真不容易,GD32网上有一个类似软件,不过只支持一个型号,好像还不是官方正式版,是在论坛里传出来的,后面有可能GD32真的实现了硬件PIN对PIN,软件完全移植,也就不需要再去开发一个了,直接用CubeMX不香吗?hhhh

继续阅读