STM32系列概述
本内容是基于江协科技STM32视频学习之后,并参考【重写】简析stm32启动过程-CSDN博客和STM32 最小系统_stm32最小系统-CSDN博客以及其他资料综合整理而成。
1. STM32
1.1 STM32简介
1.2 ARM
A系列:应用(application),主要用于手机,苹果手机、高通手机芯片、联发科手机芯片;
R系列:RealTime,主要面向实时性很高的场景,硬盘控制器
M系列:Microcontroller,主要应用在单片机领域;
1.3 STM32F103C8T6:
系列:主流系列STM32F1
内核:ARM Cortex-M3
主频:72MHz
RAM:20K (SRAM)
ROM:64K (Flash)
供电:2.0~3.6V (标准3.3V)
封装:LQFP48
1.4 片上资源/外设
英文缩写 | 名称 | 英文缩写 | 名称 |
---|---|---|---|
NVIC | 嵌套向量中断控制器 | CAN | CAN通信 |
SysTick | 系统滴答定时器 | USB | USB通信 |
RCC | 复位和时钟控制 | RTC | 实时时钟 |
GPIO | 通用IO口 | CRC | CRC校验 |
AFIO | 复用IO口 | PWR | 电源控制 |
EXTI | 外部中断 | BKP | 备份寄存器 |
TIM | 定时器 | IWDG | 独立看门狗 |
ADC | 模数转换器 | WWDG | 窗口看门狗 |
DMA | 直接内存访问 | DAC | 数模转换器 |
USART | 同步/异步串口通信 | SDIO | SD卡接口 |
I2C | I2C通信 | FSMC | 可变静态存储控制器 |
SPI | SPI通信 | USB OTG | USB主机接口 |
1.5 STM32命名规则
1.6 STM32F013C8T6引脚定义
类型中:
I/O口电平:代表IO口所能容忍的电压;有FT代表能容忍5V的电压,没有FT只能容忍3.3V的电压。如果没有FT的需要接5V的电平,就需要加装电平转换电路了
主功能:上电后默认的功能,一般和引脚名称相同。如果不同的话,引脚的实际功能是主功能而不是引脚名称的功能。
默认复用功能:是IO口上同时连接的外设功能引脚。配置IO口的时候可以选择是通用IO口还是复用功能。
重定义功能:如果有两个功能同时复用在了一个IO口上,而你确实需要用到这两个功能,那么可以把其中一个复用功能重映射到其他端口上。当然前提是,这个重定义功能的表里有对应的端口。
1号VBAT:是备用电池供电的引脚,可以接一个3.3V的电池。当系统电源断电时,备用电池可以给内部的RTC时钟和备份寄存器提供电源。
2号引脚:是IO口或侵入检测或RTC。
3、4号引脚:是IO口或者接32.768KHz的RTC晶振
5、6号引脚:接系统的主晶振,一般是8MHz的。芯片内部有锁相环电路,可以对这个8MHz的频率进行倍频,最终产生72MHz的频率,作为系统的主时钟
7号NRST:是系统复位引脚,N代表低电平复位
8、9号引脚:是内部模拟部分的电源,如ADC、RC震荡器。VSS是负极,接GND,VDD是正极,接3.3V。
10~19号引脚:都是IO口。PA0兼具了WKUP的功能,可以用于唤醒处于待机模式的STM32。
20号引脚:IO口或BOOT1引脚。BOOT1是用来配置启动模式的。
21、22号引脚:IO口
23、24号引脚:VSS_1和VDD_1是系统的主电源口。另外VSS_2、VDD_2、VSS_3、VDD_3,都是系统的主电源口。这里STM32内部采用了分区供电的方式。
25~33号引脚:都是IO口
34、37~40号引脚:都是IO口或者调试端口。默认的主功能是调试端口。调试端口是用来调试程序和下载程序的。支持SWD和JTAG两种调试方法。SWD需要两根线,分别是SWDIO和SWCLK。JTAG需要5根线,分别是JTMS、JTCK、JTDI、JTDO、NJTRST。当采用SWD方式时,其他的端口可以当做普通的IO口,但要在程序中进行配置,否则还是当作调试端口
41-43、45-46号引脚:都是IO口;
44号引脚:BOOT0,也是用来做启动配置的。
1.7 STM32最小系统板
晶振电路的两根引脚分别通过两个网络标号,接到STM32的5、6号引脚。还需要接两个20pF的电容,作为起振电容,电容的另一端接地
如果需要RTC功能,则需要接一个32.768KHz的晶振,电路和这个一样,接在3、4号引脚。32768是2的15次方,内部RTC电路经过2的15次方分频,就可以生成1秒的时间信号了。
1.8 STM32开发方式
STM32的开发有基于寄存器、基于标准库也就是库函数的方式和基于HAL库的方式。
基于寄存器:
// 配置寄存器,点灯
// 1. RCC寄存器,来使能GPIOC的时钟,GPIO都是APB2的外设,
// 因此APB2外设时钟使能寄存器RCC_APB2ENR里面配置
// IOPCEN是使能GPIOC的时钟
// 2. 配置PC13口的模式
// 配置高寄存器GPIOx_CRH,x对应A~E中任意一个字母,
// CNF13和MODE13用来配置13号口
// CNF13配置为00和MODE13配置为11
// 3. 端口输出数据寄存器GPIOx_ODR,低电平亮,高电平灭。
RCC->APB2ENR = 0x00000010;
GPIOC->CRH = 0x00300000;
GPIOC->ODR = 0x00002000;
基于库函数:
// 使用库函数来点灯
// 1. 使能时钟,第一个参数选择外设,第二个选择新的状态
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
// 2. 配置端口模式,GPIO_Init
// 第一个参数是选择哪个GPIO,第二个是参数的结构体
// 是PC13口的LED,所以第一个参数写GPIOC
// 先定义一个结构体GPIO_InitStructure,有三个参数,
// 分别是GPIO模式、GPIO端口、GPIO速度
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC,&GPIO_InitStructure);
// 点灯,GPIO_SetBits将端口设置为高电平
GPIO_SetBits(GPIOC,GPIO_Pin_13);
// 点灯,GPIO_ResetBits将端口设置为低电平
// GPIO_ResetBits(GPIOC,GPIO_Pin_13);
1.9 STM32F103C8T6工程模板创建
STM32F10x固件库文件分析 | ||
启动文件 | startup_stm32f10x_md.s | 汇编编写的启动文件 |
外设相关 | stm32f10x.h | 外设寄存器定义;针对片上的外设 |
stm32f10x_xxx.c | 外设固件库源文件 | |
stm32f10x_xxx.h | 外设固件库头文件 | |
内核相关 | core_cm3.h | 内核寄存器定义;针对内核的外设 |
core_cm3.c | 控制内核外设的相关函数 | |
system_stm32f10x.c和system_stm32f10x.h | 用于系统初始化和配置系统时钟 | |
misc.c和misc.h | 与NVIC和SysTick相关的函数 | |
用户相关 | main.c | main函数 |
stm32f10x_conf.h | 软件库配置头文件 | |
stm32f10x_it.c和stm32f10x_it.h | 中断服务函数 |
启动文件 | 区别 |
---|---|
startup_stm32f10x_ld.s | ld: low_density 小容量,Flash容量在16-32K之间 |
startup_stm32f10x_md.s | md: medium_density 中容量,Flash容量在64-128K之间 |
startup_stm32f10x_hd.s | hd: high_density 大容量,Flash容量在256-512K之间 |
startup_stm32f10x_xl.s | xl: 超大容量,Flash容量在512-1024K之间 |
库函数工程模板中建立3个文件夹:
1. Start文件夹
2. Library文件夹
3. User文件夹
1.10 stm32启动流程
1.10.1 启动配置
微控制器(单片机)上电后,是如何寻找到并执行main函数的呢?—–启动文件(Bootloader)
很显然微控制器无法从硬件上定位main函数的入口地址,因为使用C语言作为开发语言后,变量/函数的地址便由编译器在编译时自行分配,这样一来main函数的入口地址在微控制器的内部存储空间中不再是绝对不变的。
每一种微控制器(处理器)都必须有启动文件,启动文件的作用便是负责执行微控制器从“复位”到“开始执行main函数”中间这段时间(称为启动过程)所必须进行的工作。
启动模式:
根据选定的启动模式,主闪存存储器、系统存储器或SRAM可以按照以下方式访问:
注意: 当从内置SRAM启动,在应用程序的初始化代码中,必须使用NVIC的异常表和偏移寄存器,重新映射向量表至SRAM中。
1.10.2 启动流程
Cortex-M3内核规定,向量表的起始地址必须存放栈顶指针MSP的地址,而第二个地址则必须存放复位中断入口向量地址,这样在Cortex-M3内核复位后,会自动从起始地址的下一个32位空间取出复位中断入口向量,跳转执行复位中断服务程序。对比ARM7/ARM9内核,Cortex-M3内核则是固定了中断向量表的位置而起始地址是可变化的。
- 上电复位,硬件设置SP、PC的值
__initial_sp
,存放的是栈顶指针MSP的地址。Reset_Handler
执行,- 跳转到
Reset_Handler
开始执行
SystemInit
函数,设置系统时钟__main
函数,完成某些初始化,调用main函数。作者:luckyme_