stm32
时间:2023-01-25 14:30:01
启动文件的功能
启动文件由汇编编写,是系统上电复位后的第一个程序。
- 堆栈指针的初始化
SP=_initial_sp - 初始化程序计数器指针
PC=Reset_Handler - 设置堆和栈的大小
- 设置中断向量表的入口地址,初始化中断向量表
- 配置外部
SRAM数据存储 - 配置系统时钟
- 调用
C库函数_main初始化用户栈,最终调用main函数转到C世界
来自p45、p108
GPIO工作模式
- 输入模式(
上拉/下拉/浮空) - 输出模式(
推挽/开漏、上拉/下拉) - 复用功能(
推挽/开漏、上拉/下拉) - 模拟输入输出
来自p42-43
STM32的GPIO有哪些配置模式?工作场景?
| 模式名称 | 性质 | 场景 |
|---|---|---|
| 浮空输入 | 数字输入 | 外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输入/外部按键输USART RX引脚 |
| 上拉输入 | 数字输入 | 需要IO内部上拉电阻输入时,器件的外部中断(IRQ)引脚触发的中断条件是下降沿触发/低电平触发,因此在无信号输入时始终保持高电平。如果有事件触发中断IRQ它可以输出一个低电平,然后(下降沿/低电平)。例如,单片无线收发器芯片NRF24L01的IRQ引脚的工作模式是上拉输入模式 |
| 下拉输入 | 数字输入 | 需要IO输入内部下拉电阻时,设备外部中断(IRQ)引脚触发中断条件为上升沿触发/高电平触发时,可选择下拉输入模式 |
| 模拟输入 | 模拟输入 | ADC模拟输入/低功耗省电 |
| 开漏输出 | 数字输出 | IIC/SMBus |
| 推挽输出 | 数字输出 | 普通的GPIO用于驱动LED、数字管等电子元件或输出控制信号 |
| 复用开漏输出 | 数字输出 | 常见片内外设(I2C/SMBus等等) |
| 复用推挽输出 | 数字输出 | 常见片内外设(USART TX引脚/SPI/PWM输出等等) |
来自# STM32 GPIO的8种工作模式与应用场合 和 中文手册 和 p40
堆栈和堆(启动文件)
- 栈的作用是局部变量、函数调用、函数形参等费用,栈的大小不得超过内部
SRAM大小_initial_sp紧挨着SPACE陈述(用于分配一定大小的内存空间,单位为字节),表示栈的结尾地址,即栈顶地址。栈,由高到低生长。 - 堆主要用于动态内存的分配,如
malloc()函数申请的内存在堆中,从低到高生长。
来自p109-110
简述SPI和IIC的区别
IIC |
SPI |
|---|---|
半双工,2根线SCL SDA |
全双工,4根线SCK CS MOSI MISO |
通过多主机总线SDA从设备上锁定地址信息 |
只有一个主设备通过CS从设备中确定片选 |
总线传输速度100Kbps-4Mbps |
达30Mbps以上 |
高电平时SDA下降沿标志传输开始,上升沿标志传输结束 |
CS开始拉低标志传输,CS拉高标志传输结束 |
| 读写顺序相对固定统一,设备驱动编写方便 | 不同从设备datasheet为了实现读写,比较复杂 |
CPOL/CPHA及通信模式
SPI一般有4通信模式的主要区别在于总线的空闲时间SCK时钟状态和数据采样时间。
时钟极性CPOL是指SPI当通信设备处于空闲状态时,SCK电平信号(即信号线)SPI通信开始前,NSS高电平时线SCK的状态)。CPOL=0时,SCK空闲时低电平,CPOL=1时,SCK在空闲时间为高电平。
时钟相位CPHA指数据采样的时刻,当CPHA=0时,MOSI或MISO数据线上的信号将在SCK采样了时钟线的奇数边缘。
CPOL及CPHA不同的状态,SPI分为4模式。主机和从机需要在同一模式下工作才能正常通信。实际上,更多的是模式0”和“模式3”
| SPI模式 | CPOL | CPHA | 空闲时SCK时钟 | 采样时刻 |
|---|---|---|---|---|
| 0 | 0 | 0 | 低电平 | 奇数边沿 |
| 1 | 0 | 1 | 低电平 | 偶数边沿 |
| 2 | 1 | 0 | 高电平 | 奇数边沿 |
| 3 | 1 | 1 | 高电平 | 偶数边沿 |
来自p237-238
IIC挂机设备的个数
由IIC地址决定,8位地址,减去1位广播地址,是7位地址,2^7=128,但是地址0x00不用,那就是127个地址, 所以理论上可以挂127个从器件。
但是IIC协议没有规定总线上device最大数目,但是规定了总线电容不能超过400pF。
管脚都是有输入电容的,PCB上也会有寄生电容,所以会有一个限制。实际设计中经验值大概是不超过8个器件。
总线之所以规定电容大小是因为,IIC的OD要求外部有电阻上拉,电阻和总线电容产生了一个RC延时效应,电容越大信号的边沿就越缓,有可能带来信号质量风险。
传输速度越快,信号的窗口就越小,上升沿下降沿时间要求更短更陡峭,所以RC乘积必须更小。
来自# IIC总线最多可以挂多少个设备 和 p205 -206
时钟源与时钟和总线对应外设
在STM32中,可以用内部时钟,也可以用外部时钟,在要求进度高的应用场合最好用外部晶体震荡器,内部时钟存在一定的精度误差。
准确的来说有4个时钟源可以选分别是HSI、LSI、HSE、LSE(即内部高速,内部低速,外部高速,外部低速),高速时钟主要用于系统内核和总线上的外设时钟。低速时钟主要用于独立看门狗IWDG、实时时钟RTC。
HSI是高速内部时钟,RC振荡器,频率为8MHz,上电后默认的系统时时钟 SYSCLK = 8MHz,Flash编程时钟
HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为4MHz~16MHz
LSI是低速内部时钟,RC振荡器,频率为40kHz,可用于独立看门狗IWDG、实时时钟RTC
LSE是低速外部时钟,接频率为32.768kHz的石英晶体
PLL为锁相环倍频输出,其时钟输入源可选择为HSI/2、HSE或者HSE/2。倍频可选择为2~16倍,但是其输出频率最大不得超过72MHz。通过倍频之后作为系统时钟的时钟源( 有很多人说是5个时钟源,这种说法有点问题,学习之后就会发现PLL并不是自己产生的时钟源,而是通过其他三个时钟源倍频得到的时钟)。

从左到右可以简单理解为 各个时钟源 -> 系统时钟来源的设置 -> 各个外设时钟的设置
系统时钟SYSCLK3种时钟源
HSI振荡器时钟
HSE振荡器时钟
PLLCLK时钟
PLL锁相环倍频(输入和输出)
PLL的输入(3种)
PLLi = HSI /2
PLLi = HSE /2
PLLi = HSE
PLL的输出(15种)
PLLout = PLLi Xn (n = 2…16)
F4系列总线对应外设
APB2总线:高级定时器timer1、timer8,通用定时器timer9、timer10、timer11,UTART1、USART6
APB1总线:通用定时器timer2、timer5,通用定时器timer12、timer14,基本定时器timer6、timer7、UTART2~UTART5
F4系列的系统时钟频率最高能到168M
来自# 图文并茂详解STM32时钟配置 和 p117-123
串口定义
STM32F4系统控制器有4个USART和4个UART,其中USART1和USART6的时钟来源于APB2总线时钟,最大频率为90MHz,其它6个时钟来源于APB1总线时钟,其最大频率为45MHz。
来自p161
串口调试为什么收到一直乱码?
- 首先检查上下两机位是否一致:波特率、数据位、停止位、奇偶校验等等
- 其次检查线缆:线缆长度是否过长,引入串扰,阻抗是否匹配,信号畸变是否在可控范围内
- 地电位:因为串口调试一般只需要三线
RX、TX、GND,地电位也非常重要,务必使你调试用的电脑地和你要调试的电路地电位基本一致(最好共地)。
- 电平:如果你使用的
TTL串口,那么还需要考虑是不是5V和3.3V的差异导致上述情况。
抢占优先级与子优先级
假设STM32配置了3个中断向量
-
当STM32响应中断时,中断A能打断中断B的中断服务函数吗?
-
中断C能打断中断A吗?
-
如果中断A和中断C中断同时到达,响应哪个中断?
中断向量
抢占优先级
子优先级
A
2
0
B
3
0
C
2
1
-
A可以打断B
-
C不能打断A
-
响应中断A
原因略
三种定时器
TIM1和TIM8定时器的功能包括【高级】
16位向上、向下、向上/下自动装载计数器
16位可编程(可以实时修改)预分频器,计数器时钟频率的分频系数为1~65535之间的任意数值
- 多达
4个独立通道: 输入捕获、输出比较、PWM生成(边缘或中间对齐模式)、单脉冲模式输出
- 死区时间可编程的互补输出
- 使用外部信号控制定时器和定时器互联的同步电路
- 允许在指定数目的计数器周期之后更新定时器寄存器的重复计数器
- 刹车输入信号可以将定时器输出信号置于复位状态或者一个已知状态
- 如下事件发生时产生中断/
DMA: 更新(计数器向上溢出/向下溢出)、计数器初始化(通过软件或者内部/外部触发) 、触发事件(计数器启动、停止、初始化或者由内部/外部触发计数) 、输入捕获、输出比较、刹车信号输入
- 支持针对定位的增量(正交)编码器和霍尔传感器电路
- 触发输入作为外部时钟或者按周期的电流管理
TIMx主要功能通用TIMx (TIM2、TIM3、TIM4和TIM5)定时器功能包括【通用】
16位向上、向下、向上/向下自动装载计数器
16位可编程(可以实时修改)预分频器,计数器时钟频率的分频系数为1~65536之间的任意数值
4个独立通道: 输入捕获、输出比较、PWM生成(边缘或中间对齐模式)、单脉冲模式输出
- 使用外部信号控制定时器和定时器互连的同步电路
- 如下事件发生时产生中断/
DMA:更新(计数器向上溢出/向下溢出)、计数器初始化(通过软件或者内部/外部触发)、触发事件(计数器启动、停止、初始化或者由内部/外部触发计数)、输入捕获 、输出比较
- 支持针对定位的增量(正交)编码器和霍尔传感器电路
- 触发输入作为外部时钟或者按周期的电流管理
TIM6和TIM7定时器的主要功能包括【简单
16位自动重装载累加计数器
16位可编程(可实时修改)预分频器,用于对输入的时钟按系数为1~65536之间的任意数值分频
- 触发
DAC的同步电路 注:此项是TIM6/7独有功能
- 在更新事件(计数器溢出)时产生中断/
DMA请求
EXTI 外部中断/事件控制器
EXTI 外部中断/事件控制器管理了控制器的23个中断/事件线,EXTI可分为两部分功能:一是产生中断,另一个是产生事件。
来自p136
SysTick
SysTick 系统定时器是CM4内核中的一个外设,内嵌在NVIC中。系统定时器是一个24位的向下递减的计数器,计数器每计数一次的时间为1/SYSCLK,一般我们设置系统时钟SYSCLK等于180MHz。
来自参考手册
RCC通过AHB时钟(HCLK)8分频后作为Cortex系统定时器(SysTick)的外部时钟。
通过对SysTick控制与状态寄存器的设置,可选择上述时钟或Cortex(HCLK)时钟作为SysTick时钟。
也就是说SysTick时钟源可以来自两个地方:
AHB时钟8分频
HCLK(内核)时钟
通过SysTick控制与状态寄存器的设置进行选择时钟源。
来自p145 和 STM32的SysTick时钟源来自哪里?
波特率计算
B a u d = f P L C K 8 × ( 2 − O V E R 8 ) × U S A R T D I V Baud=\frac{f_{PLCK}}{8{\times}(2-OVER8){\times}USARTDIV} Baud=8×(2−OVER8)×USARTDIVfPLCK
时钟控制逻辑计算
SCL线的时钟信号,由IIC接口根据时钟控制寄存器(CCR)控制,控制参数主要为时钟频率。配置IIC的CCR寄存器可修改通信速率相关的参数
- 可选择
IIC通信的“标准/快速”模式,这两个模式分别对应100kbps/400kbps的通信速率。
- 在快速模式下可选择
SCL时钟的占空比 T l o w T h i g h \frac{T_{low}}{T_{high}} ThighTlow,可选2或16/9模式。
CCR寄存器中还有一个12位的配置因子CCR,它与IIC外设的输入时钟源共同作用,产生SCL时钟。STM32的IIC外设都挂载在APB1总线上,使用APB1的时钟源PCLK1。
SCL信号线的输出时钟公式如下
标准模式
T h i g h = C C R × T P C L K 1 T_{high}=CCR{\times}T_{PCLK1} Thigh=CCR×TPCLK1
T l o w = C C R × T P C L K 1 T_{low}=CCR{\times}T_{PCLK1} Tlow=CCR×TPCLK1
快速模式 T l o w T h i g h = 2 \frac{T_{low}}{T_{high}}=2 ThighTlow=2
T h i g h = C C R × T P C L K 1 T_{high}=CCR{\times}T_{PCLK1} Thigh=CCR×TPCLK1
T l o w = 2 × C C R × T P C L K 1 T_{low}=2{\times}CCR{\times}T_{PCLK1} Tlow=2×CCR×TPCLK1
快速模式 T l o w T h i g h = 16 / 9 \frac{T_{low}}{T_{high}}=16/9 ThighTlow=16/9
T h i g h = 9 × C C R × T P C L K 1 T_{high}=9{\times}CCR{\times}T_{PCLK1} Thigh=9×CCR×TPCLK1
T l o w = 16 × C C R × T P C L K 1 T_{low}=16{\times}CCR{\times}T_{PCLK1} Tlow=16×CCR×TPCLK1
例如,PCLK1=45MHz,想要配置400kbps的速率
PCLK时钟周期: T P C L K 1 = 1 45000000 T_{PCLK1}=\frac{1}{45000000} TPCLK1=450000001
目标SCL时钟周期: T S C L = 1 400000 T_{SCL}=\frac{1}{400000} TSCL=4000001
SCL时钟周期内的高电平时间: T H I G H = 1 3 T S C L T_{HIGH}=\frac{1}{3}T_{SCL} THIGH=31TSCL
SCL时钟周期内的低电平时间: T L O W = 2 3 T S C L T_{LOW}=\frac{2}{3}T_{SCL} TLOW=32TSCL
CCR的值: C C R = T H I G H T P C L K 1 = 37.5 CCR=\frac{T_{HIGH}}{T_{PCLK1}}=37.5 CCR=TP

