STM32F0库应用技术笔记——iar工程建立&时钟管理

来源:互联网 发布:法线贴图转换软件 编辑:程序博客网 时间:2024/06/06 22:42

开发环境

我目前是在如下开发环境下操作的,
软件

  • iar for arm开发工具
  • STM32F0xx_StdPeriph_Lib_V1.5.0库

硬件

  • STM32F030F4P6最小系统板
  • ST Link V2调试工具
  • TTL转USB串口工具

创建iar for arm工程

拷贝库文件到工程

STM32F0xx_StdPeriph_Lib_V1.5.0库中Libraries放到工程目录中。同时拷贝库中Projects\STM32F0xx_StdPeriph_Templates路径下以下三个文件到工程目录中

stm32f0xx_conf.hstm32f0xx_it.cstm32f0xx_it.hsystem_stm32f0xx.c

工程options...配置

C++ Compiler -> Preprocessor -> Additional include directiries:(one per line)配置如下,要注意的是CMSIS库头文件搜索路径设置为iar安装路径中最新的头文件,这是因为 iar 版本升级后,使用STM32F0xx_StdPeriph_Lib_V1.5.0中CMSIS老的库头文件编译会出错。

$PROJ_DIR$\$TOOLKIT_DIR$\CMSIS\Include$PROJ_DIR$\..\..\Libraries\CMSIS\Device\ST\STM32F0xx\Include$PROJ_DIR$\..\..\Libraries\STM32F0xx_StdPeriph_Driver\inc

C++ Compiler -> Preprocessor -> Defined symbols:(one per line)添加如下宏定义

USE_STDPERIPH_DRIVERSTM32F030

Debugger -> Setup -> Driver中,选择ST-LINK
Debugger -> Setup -> Download中,复选框,选中Verify download以及Use flash loader(s)

组织工程文件

在工程中添加system_stm32f0xx.cstartup_stm32f030.s文件,在main.c文件中,添加#include "stm32f0xx_conf.h",如下图所示,
这里写图片描述

工程创建完毕。
工程中如果需要使用某个驱动库,直接添加进图示STM32F0xx_StdPeriph_Driver组中,
如果需要使用到中断添加stm32f0xx_it.c到工程中即可。

接下来才正式进入主题。这里会从时钟管理,接口技术一步步建立库使用例程。在实际开发中,只需要拷贝+修改就可以快速完成功能模块开发。

STM32F0——时钟管理

概述

这一部分主要是配置系统时钟(CPU主频)及各总线时钟,包括了AHB,APB,IIC,USART,RTC等。在工程组织文件system_stm32f0xx.c中提供了1个变量3个函数,如下所示

SystemCoreClock变量为系统时钟(CPU主频),单位Hzvoid SystemInit(void)函数static void SetSysClock(void)函数void SystemCoreClockUpdate(void)函数

在启动文件startup_stm32f030.s中,程序在进入main函数之前调用SystemInit(void)函数,对时钟进行配置,SystemInit(void)函数首先复位各时钟寄存器,然后调用SetSysClock(void)函数对时钟进行配置。

而在用户app中,如果重新初始化配置了系统时钟,配置完成后,可以运行一次SystemCoreClockUpdate(void)函数,它会更新SystemCoreClock变量,用户可以获取该变量的值确定当前系统时钟。毕竟,该值是有用的,可以依据此配置sys定时器,通信接口速率等。

代码实操

时钟配置代码只需在SetSysClock(void)函数修改即可定制以适应各种需求。见STM32F0寄存器配置参考文件90页clock配置图。芯片默认CPU主频(SYSCLK)时钟源为HSI(高速内部时钟8MHz),本例中,外部时钟(HSE)晶振8MHz,

  • 配置HCLK,PCLK=CPU主频
  • 配置PLL输入,选择外部时钟HSE(分频为1)作为PLL时钟源,8MHz
  • 配置PLL输出,6倍频,PLL输出48MHz
  • 配置CPU主频时钟源为PLL时钟:48MHz
static void SetSysClock(void){  __IO uint32_t StartUpCounter = 0, HSEStatus = 0;  /* SYSCLK, HCLK, PCLK configuration ----------------------------------------*/  /* Enable HSE */      RCC->CR |= ((uint32_t)RCC_CR_HSEON);  /* Wait till HSE is ready and if Time out is reached exit */  do  {    HSEStatus = RCC->CR & RCC_CR_HSERDY;    StartUpCounter++;    } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));  if ((RCC->CR & RCC_CR_HSERDY) != RESET)//HSERDY: HSE 时钟就绪标志    1: HSE 振荡器就绪  {    HSEStatus = (uint32_t)0x01;  }  else  {    HSEStatus = (uint32_t)0x00;  }    if (HSEStatus == (uint32_t)0x01)  {    /* Enable Prefetch Buffer and set Flash Latency */    FLASH->ACR = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY;    /* HCLK = SYSCLK */    RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;//位 7:4 HPRE: HCLK 预分频(HCLK prescaler)    /* PCLK = HCLK */    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE_DIV1;//位 10:8 PPRE: PCLK 预分频(PCLK prescaler)    /* PLL configuration = HSE * 6 = 48 MHz */    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));    //位 16 PLLSRC: PLL 输入时钟源   1:HSE/PREDIV 作为PLL 输入时钟    //位 17 PLLXTPRE: HSE 分频器作为PLL 输入   0: HSE 不分频    //位 21:18 PLLMUL: PLL 倍频系数    0100: PLL 输入时钟的6 倍频    RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLMULL6);    /* Enable PLL */    RCC->CR |= RCC_CR_PLLON;    /* Wait till PLL is ready */    while((RCC->CR & RCC_CR_PLLRDY) == 0)    {    }    /* Select PLL as system clock source */    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));    RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;        /* Wait till PLL is used as system clock source */    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)RCC_CFGR_SWS_PLL)    {    }  }  else  { /* If HSE fails to start-up, the application will have wrong clock          configuration. User can add here some code to deal with this error */  }  }
0 0