2021/1/10 学习日志

  • STM32f1库函数开发学习
    • 软件基础
      • 固件库与CMSIS标准
      • 文件夹结构
      • C语言基础
      • STM32系统架构
      • STM32时钟系统

STM32f1库函数开发学习

软件基础

固件库与CMSIS标准

ARM是一个芯片标准设计公司,负责架构设计;
ST、TI是芯片公司,根据ARM公司提供的芯片内核标准(例如Cortex-M3)设计芯片,内核结构都相同,不同在于存储器容量、片上外设、串口数量、控制方法。

为了让不同商家制造的Cortex-M3内核芯片基本兼容,ARM公司与芯片生产商共同提出了CMSIS标准(Cortex Microcontroller Software Interface Standard,ARM Cortex^TM 微控制器软件接口标准):

CMSIS分为3个基本功能层:

  • 核内外访问层:ARM公司提供的访问,定义处理器内部寄存器地址及其功能函数
  • 中间件访问层:ARM公司提供的访问,定义访问中间件的通用API
  • 外设访问层:定义硬件寄存器的地址以及外设的访问函数

简而言之,CMSIS规定了库函数的一些规范,例如系统初始化函数必须叫SystemInit,下拉输出模式必须交GPIO_ResetBits




文件夹结构

一. 官方库文件夹

Libraries

  • CMSIS 存放启动文件
    • CM3\CoreSupport\core_cm3.c/h,ARM公司提供的M3内核接口
    • DeviceSupport\ST\STM32F10x
      • system_stm32f10x.c/h,设置系统时钟,SystemInit函数
      • stm32f10x.h,系统寄存器定义申明以及包装内存
      • startup\arm
        • startup_stm32f10x_ld.s
          103系列小容量产品启动文件
          FLASH <= 32K
        • startup_stm32f10x_md.s
          103系列中等容量产品
          64K <= FLASH <= 128K
        • startup_stm32f10x_hd.s
          103系列大容量产品(RCT6)
          256K <= FLASH
        • 启动文件
          堆栈初始化、中断向量表、中断函数定义
    • STM32F10x_StdPeriph_Driver 存放固件库源代码文件
      • inc存放stm32f10x_xxx.h头文件
      • src存放stm32f10x_xxx.c固件库源代码
  • Project
    • STM32F10x_StdPeriph_Examples存放ST官方提供的固件实例参考代码
    • STM32F10x_StdPeriph_Template存放工程模板
  • Utilities文件下存放官方评估版的源代码(可忽略)

二. 工程文件夹结构

结构介绍:

  • USER
    • Template.uvprojx 工程文件
    • main.c 文件
    • system_stm32f10x.c 文件
    • stm32f10x.h
    • stm32f10x_conf.h
    • system_stm32f10x.c/h
    • stm32f10x_it.c/h
    • DebugConfig 自动生成的调试配置文件夹
    • Listings 自动生成的编译中间文件夹(删)
    • Objects 自动生成的编译中间文件夹(删)
  • OBJ(隐) 替换自动生成的Listing/Objects文件夹,存放编译过程文件、hex文件
  • CORE 官方固件库启动文件
    • core_cm3.c/h
    • startup_stm32f10x_hd.s RCT6 FLASH 256KB,使用大容量类型
  • FWLib 存放官方库函数源代码
    • src 存放 .c 文件,每个外设对应一个文件,在工程里选择对应的C文件加入
    • inc 存放 .h 文件,每个外设对应一个文件,在魔术棒里添加头文件路径
  • HARDWARE 需要用到的外设代码,例如:
    • LED
    • PWM
  • SYSTEM 存放每个实验都要用的共用代码
    • sys
    • usart
    • delay
  • README 备注文件

C语言基础

  1. 位操作
运算符 含义 运算符 含义
& 按位与 ~ 取反
| 按位或 << 左移
^ 按位异或 >> 右移
  1. define宏定义
    #define 标识符 字符串
    
    #define SYSCLK_FREQ_72MHz 72000000
    
  2. ifdef条件编译
    #ifdef 标识符
    程序段 1 
    #else 
    程序段 2 
    #endif
    
  3. extern外部变量申明
    extern u16 USART_RX_STA;
    
  4. typedef类型别名
    为现有类型创建一个新的名字,或称为类型别名,用来简化变量的定义。
    typedef struct
    {
     __IO uint32_t CRL;
     __IO uint32_t CRH;
    …
    } GPIO_TypeDef;
    
    //GPIO_TypeDef是大括号内的统称别名
    //于是可用GPIO_TypeDef定义结构体变量
    
    GPIO_TypeDef _GPIOA,_GPIOB;
    
    //简而言之:
    typedef int abc; 
    //将 abc作为 int 的别名
    
  5. 结构体
    Struct 结构体名{
    成员列表; 
    }变量名列表;
    
    //例如
    Struct U_TYPE {
    Int BaudRate
    Int WordLength; 
    }usart1,usart2;
    

关于结构体的用法,详见下文:


结构体的用法





STM32系统架构

架构图:

  • 四个驱动单元

    • 内核DCode总线
    • 系统总线
    • 通用DMA1
    • 通用DMA2
  • 四个被动单元

    • AHB到APB的桥,连接所有的APB设备
    • 内部FLASH闪存
    • 内部SRAM
    • FSMC

几个总线:

ICode总线:将 M3 内核指令总线和闪存指令接口相连,指令的预取在该总线上面完成
DCode总线: 将 M3 内核的 DCode 总线与闪存存储器的数据接口相连接,常量加载和调试访问在该总线上面完成
系统总线:连接 M3 内核的系统总线到总线矩阵,总线矩阵协调内核和 DMA 间访问
DMA总线:将 DMA 的 AHB 主控接口与总线矩阵相连,总线矩阵协调 CPU 的 DCode 和 DMA 到 SRAM,闪存和外设的访问
总线矩阵: 协调内核系统总线和 DMA 主控总线之间的访问仲裁,仲裁利用轮换算法
AHB/APB桥:这两个桥在 AHB 和 2 个 APB 总线间提供同步连接,APB1 操作速度限于36MHz,APB2 操作速度全速

目前还未深入了解总线结构,学成再做补充。




STM32时钟系统

时钟系统是CPU的脉搏,下面是STM32的时钟系统图:


时钟源

  • 高速时钟
    • HSI (High Speed Internal),高速内部时钟,RC振荡器,8MHz
    • HSE (High Speed External),高速外部时钟,石英/陶瓷谐振器/外部时钟源,4~16MHz
    • PLL (Phase Locked Loop),锁相环倍频输出,可2~16倍频,最大不超过72MHz
  • 低速时钟
    • LSI (Low Speed Internal),低速内部时钟,RC振荡器,40kHz。独立看门狗只能使用LSI;可作为RTC (Real Time Clock,实时时钟)时钟源
    • LSE (Low Speed External),低速外部时钟,石英晶体频率32.768kHz,RTC的主要时钟源

时钟图解剖:
A. MCO 是 STM32 的一个时钟输出 IO(PA8),它可以选择一个时钟信号输出,可以选择为 PLL 输出的 2 分频、HSI、HSE、或者系统时钟。这个时钟可以用来给外部其他系统提供时钟源。


B. RTC 时钟源,从图上可以看出,RTC 的时钟源可以选择 LSI,LSE,以及HSE 的 128 分频。


C. 此处 USB 的时钟是来自 PLL 时钟源。STM32 中有一个全速功能的 USB 模块,其串行接口引擎需要一个频率为 48MHz 的时钟源。该时钟源只能从 PLL 输出端获取,可以选择为 1.5 分频或者 1 分频,也就是,当需要使用 USB模块时,PLL 必须使能,并且时钟频率配置为 48MHz 或 72MHz。


D. STM32 的系统时钟 SYSCLK,它是供 STM32 中绝大部分部件工作的时钟源。系统时钟可选择为 PLL 输出、HSI 或者 HSE,最大频率为 72MHz,可以超频,不过为了系统稳定性不建议超频。


E. 其他所有外设。从时钟图上可以看出,其他所有外设的时钟最终来源都是 SYSCLK。SYSCLK 通过 AHB 分频器分频后送给各模块使用。这些模块包括:


① AHB 总线、内核、内存和 DMA 使用的 HCLK 时钟。
② 通过 8 分频后送给 Cortex 的系统定时器时钟,也就是 systick 了。
③ 直接送给 Cortex 的空闲运行时钟 FCLK。
④ 送给 APB1 分频器。APB1 分频器输出一路供 APB1 外设使用(PCLK1,最大频率 36MHz),另一路送给定时器(Timer) 2、3、4 倍频器使用。
⑤ 送给 APB2 分频器。APB2 分频器分频输出一路供 APB2 外设使用(PCLK2,最大频率 72MHz),另一路送给定时器(Timer) 1 倍频器使用。

APB1 和 APB2 的区别
APB1 上面连接的是低速外设,包括电源接口、备份接口、CAN、USB、I2C1、I2C2、UART2、UART3 等等


APB2 上面连接的是高速外设,包括 UART1、SPI1、Timer1、ADC1、ADC2、所有普通 IO 口(PA~PE)、第二功能 IO 口等


STM32时钟系统的配置除了初始化的时候在 system_stm32f10x.c 中的 SystemInit() 函数中之外,其他的配置主要在 stm32f10x_rcc.c 文件里。