0_说明
介绍STM32F103C8T6,引脚配置,引脚工作模式。与STM32CubeMX强相关。
1_GPIO 引脚
引脚配置
通常,电源+称为
VCC
,地称为GND
。但在STM32中,电源+ 称为Vdd
,地称为Vss
。
记忆:因为NMOS管的电流从漏极(Drain)到源极(Source)形成电势差,即我们给漏极加正电压,给源极加负电压。
- Vdd Voltage Drain-Drain
- Vss Voltage Source-Source
- 黄(黄绿)色引脚为电源及备用电池等默认引脚
- 灰色引脚为普通IO引脚,都是可编程的。
- 通用引脚分为
GPIOA
、GPIOB
、GPIOC
、GPIOD
四组 - 简写即数目:PA0……PA15、PB0……PB15、PC13……PC15、PD0和PD1
- 通用引脚分为
GPIO
General Purpose Input/Output
8种工作模式
输出模式案例
输入模式
浮空的引脚就像天线,会接收空间的电磁波,因此会得到随机的1、0
上拉电阻 - 当引脚悬空时,默认提供高
电压。
下拉电阻 - 当引脚悬空时,默认提供低
电压。
通用
程序直接控制引脚的输入与输出。
复用
使用其他模块来托管其输入与输出。此时该引脚可实现其他不同类型的功能。
复用功能重映射
将冲突的引脚移动到备用引脚上。如两个功能使用到了相同的引脚,可以将这些相同的引脚映射到备用引脚上。使得引脚不发生冲突。
IO最大输出速度
高低电压的切换是需要时间的,而不是理想状态的“瞬时”,因此波形呈现为梯形,有上升斜坡与下降斜坡。加快切换频率,中间的电压保持时间会越来越短。再加快,会发现上升沿和下降沿完全重合,此时不能有效地输出高低电压了。
STM32有三种输出速度。过快的上升沿、下降沿会导致芯片功耗增加
2_串口通信
单片机想要和其他设备进行通信,就必须借助各种各样的通信接口
UART
(Universal Asynchronous Receiver/Transmitter)通用异步收发器
收发方式
由Tx、Rx组成,Tx引脚用于向外发送,Rx引脚用于接收数据。
自然地,接收信号的设备使用Rx引脚与发送端的Tx引脚链接,接收端Tx引脚与发送端Rx引脚链接
数据帧
由三部分组成:起始位(1位)+ 数据位(8位或9位)+ 停止位(0.5、1、1.5、2位,常用1位)
- 1、数据开始传输前,串口处于空闲状态。数据线上是高电压
- 2、发送方将数据线拉低,就发送了一个起始位
- 3、数据位由所要传输的数据转换为八位二进制,逆向传播(如发送数据2,二进制为00000010,则发送01000000)
- 4、数据位后是停止位,即保持一段时间的高电压。
- 5、数据帧再次回到空闲状态。等待下一帧的发送。
数据位的最后一位可以拿来作为校验位。校验方法(Parity)为奇偶校验
- 奇校验Odd:要求有效数据和校验位中“1”的个数为奇数
- 偶校验Even:要求有效数据和校验位中“1”的个数为偶数
当检查1的个数与奇偶校验位相同,则数据正确,否则为错误数据。
波特率
串口传输速度,即每秒发送或接收的位数。
如9600波特率,即每秒发送或接收9600个数据位,每一位约0.1毫秒
115200波特率,即每秒发送或接收115200个数据位,每一位约8.7微秒
波特率越高,数据传输的速度越快,但要注意,收发双方都要设置相同的波特率。
常用数据位为8位无校验位或9位带校验位
USART
(Universal Synchronous/Asynchronous Receiver/Transmitter)通用同步/异步收发器(不常用)
收发方式
在异步收发模式的基础上,添加了一条CK线(时钟线),用于同步收发。
串口与电脑通信
电脑一般只有USB接口,此时需要USB转TTL的模块,它的作用是将串口转为USB接口。
串口的工作模式
- Asynchronous(异步模式)
- Synchronous(同步模式)
- Single-wire(Half-duplex)(单线模式)半双工
- Multiprocessor Communication(多处理器通信)
- LrDA (Local Ring-Independent Data Access)
- LIN (Local Interconnect Network)
- SmartCard (智能卡)
- SmartCard with Card Clock
Stm32CubeMX配置的接收引脚默认为浮空模式,但由于串口的数据接收引脚可能会意外断开,所以最好配置一个上拉电阻
UART API
1 | // 通过串口向外发送数据 |
3_I2C总线
单片机有三个串口,分别为USART1、USART2、USART3,且是一对一的。若要链接更多设备,需要用到I2C总线。
SCL
和SDA
都用开漏输出
,并需分别接一个上拉电阻,阻值一般为4.7k。
逻辑线与
与运算 &:一假为假,两真为真。
逻辑线与:SCL与SDA都为1,由于上拉电阻的存在,总线输出高电压1。若有任意引脚为0,则总线输出低电压(此时上拉电阻不起作用)。
数据传输
- 起始位:在SCL高电压时,向SDA发送下降沿,表示数据传输开始。
- 寻址:主机向从机发送地址(7位或10位),每个从机有各自的地址。
- 数据传输:I2C以字节为单位传输数据,每次可以传输多个字节。
- 停止位:在数据传输结束后,SCL时高电压时,向SDA发送上升沿,表示数据传输结束。
示例:
传输模式
波特率 = 每秒钟传输的位数。有多种模式
STM32F103C8T6 只支持Sm、Fm模式
名称 | 简写 | 英文 | 最大速度 |
---|---|---|---|
标准模式 | Sm | Standard Mode | 100kbps |
快速模式 | Fm | Fast Mode | 400kbps |
快速增强模式 | Fm+ | Fast Mode Plus | 1Mbps |
高速模式 | HSm | High Speed Mode | 3.4Mbps |
超快模式 | UFm | Ultra Fast Mode | 5Mbps |
快速模式下可以设置时钟信号的
占空比
。可以设置为2:1 和16:9两种,一般设置为2:1
I2C API
1 | // 向从机写数据 |
4_时钟系统
注意总线最高速度。可根据需求设置MCU的工作频率。
单片机内部结构类比电脑
时钟树:Clock Tree
数字电路可分为两类
- 组合逻辑电路:不含有记忆元件。它的输出之和当前输入有关。
- 时序逻辑电路:含有记忆元件。它的输出与当前、之前的输入有关。并且
有时钟信号才能工作
(CP——Clock Pulse)即时钟脉冲
时钟的快慢决定了电路运行的快慢
时钟分类
High Speed Clock(高速时钟)、Low Speed Clock(低速时钟)、External Clock(外部时钟)、Internal Clock(内部时钟)
- 高速内部时钟HSI
- 高速外部时钟HSE
- 低速内部时钟LSI
- 低速外部时钟LSE
内部时钟:精度低,成本低,内置在MCU中
外部时钟:精度高,成本高,外接在MCU外
锁相环
锁相环(Phase Locked Loop)是时钟系统设计中常用的一种技术。锁相环是一种时钟同步技术,通过将两个时钟源同步到同一个频率,从而实现时钟同步。锁相环的优点是简单、可靠,缺点是时钟同步 accuracy(精度)和时钟同步 delay(时钟延迟)都有可能。
即:对时钟信号做乘法(“超频”)
分频器
作用就是对时钟信号频率做除法(降频)
测试时钟频率代码
8MHz = 800万次/秒
1 | // 利用程序执行一百万次循环,约耗时1秒(一次循环约8个时钟周期) |
在STM32CubeMX中配置RCC
选择启用HSE、LSE:
- BYPASS Clock Source 旁路时钟源 。直接使用生成好的时钟信号提供给MCU
- Crystal/Ceramic Resonator 晶体/陶瓷振荡器。通过外接电路产生时钟信号
5_SPI总线
Serial Peripheral Interface(串行外设接口)。适用于高速、双向数据传输场景。(摄像头、Flash、SD卡等)
SPI总线由四条线组成:
- MOSI:(Master Out Slave Input) 主机输出从机输入。
主机发送数据给从机
主机的MOSI连接所有从机的MOSI - MISO:(Master In Slave Out) 主机输入从机输出。
从机发送数据给主机
主机的MISO连接所有从机的MISO - SCK:(Serial Clock),串行时钟线。
时钟线是SPI总线中唯一必须的线,用于控制数据传输的时序。
主机的SCK连接所有从机的SCK - NSS:(Negative Slave Select),负极性从机选择。
用于控制从机是否接收数据。即从机选择(低电压有效)。主机向对应的NSS发送低电压可以选中从机
主机的每个NSS引脚分别连接从机的NSS引脚
五个参数
波特率
SPI总线没有规定波特率的范围,一般取几兆到几十兆bps
SPI波特率选取的原则
- 选择允许的最大值
- 考虑设备所能承受的极限
- 考虑电路板所能承受的极限(面包板、杜邦线组成的电路板,最高选择10Mbps的波特率,再高会产生较严重的干扰)
比特位的传输顺序(MSB First/LSB First)
无符号8位整数,从bit0至bit7的权重分别为2^0至2^7。其中bit0为LSB,bit7为MSB。
- LSB:(Least Significant Bit) 最低有效位。
- MSB:(Most Significant Bit) 最高有效位。
所以有了两种传输方式:MSB First(先传最高有效位)和LSB First(先传最低有效位)
数据位长度(8位 / 16位)
- 8位一组,每组一个字节
- 16位一组,每组1个16位整数
时钟的极性
- 低级性:空闲状态为低电平,数据传输时为高电平。此时把所有的上升沿称为第一边沿,所有的下降沿称为第二边沿。
- 高级性:空闲状态为高电平,数据传输时为低电平。此时把所有的下降沿称为第一边沿,所有的上升沿称为第二边沿。
时钟的相位
- 第一边沿采集:(1st edge capture)在第一个边沿时,数据被采集。
- 第二边沿采集:(2nd edge capture)在第二个边沿时,数据被采集。
四种时钟模式
极性\相位 | 第一边沿采集0 | 第二边沿采集1 |
---|---|---|
低级性0 | 00(模式0) | 01(模式1) |
高级性1 | 10(模式2) | 11(模式3) |
模式0:低级性,第一边沿采集
模式1:低级性,第二边沿采集
模式2:高级性,第一边沿采集
模式3:高级性,第二边沿采集
按键控制LED亮灭代码
1 | // 按下并松开按键,控制LED的量、灭 |
STM32CubeMX中配置SPI
1、Connectivity -> 选择SPI1(2)
2、Model -> 选择Full Duplex Master(全双工主模式)。从机模式一般不用,也复杂
3、Hardware NSS Signal -> Disable(禁用)。硬件NSS一般用于多主机通信,一般用不到。
4、需选择一个GPIO引脚作为NSS引脚,并设置为推挽模式。在后续输出高低电压。最大输出速度为高速模式。默认为高电压。
SPI API
1 | // 发送数据 |
Flash模块
Flash是常见的数据持久化模块,类似于硬盘。
以W25Q64为例,容量
为64MBit,即8MByte。
其容量分为若干个块
(Block),每块64k。
每个块分为若干个扇区
(Sector),每扇区4k。扇区是擦除的最小单元。
每个扇区被分为若干页
(Page),每页256字节。页是数据写入的最小单元。
写入过程
写使能(解锁)-> 扇区擦除 -> 延迟100ms -> 写使能(解锁)-> 页编程 -> 延迟10ms
写使能、扇区擦除、页编程都需要发送响应的指令码(在发送的数据数组中的第一个元素)。具体需查看手册。
1 | // 读取例子 |
6_中断
常规程序被突发事件中断源
中断,然后去执行突发事件处理代码中断响应函数
,最后回到常规程序。
即“放下手头的工作处理突发事件,处理完成后继续做手头工作”。
又:单片机是“单线程”的。
中断优先级
以stm32f103为例,有bit3 – bit0共4位表示中断优先级,即0000 – 1111,换算为十进制,为0 – 15,共16个优先级。
数字越小表示优先级越高
bit3、bit2为pre-emption priority,抢占优先级,与中断嵌套
和中断排队
有关
bit1、bit0为sub priority,子优先级,与中断排队
有关
- 中断嵌套的发生条件:新中断的抢占优先级更高。若优先级不高,则不发生嵌套,而发生排队。
NVIC配置
NVIC:(Nested Vectored Interrupt Controller)嵌套向量中断控制器,负责管理单片机内部的中断。
图片解释:每个模块都可以产生多个中断(模块箭头),每个中断都有独立的开关(箭头开关)负责中断的使能和禁止(中断发生了也不去响应),每个中断都可以设置优先级(四个格子),仲裁电路管理排队、嵌套。经过仲裁后的中断调用其相应函数(通过Flash中断向量表找到函数)
中断 API
1 | // 串口使用中断方式接受一定数量的数据 |
7_定时器
TIM:(Timer)
时钟树提供时钟信号(晶振等),定时器执行和时间相关的操作。
一个定时器有四个通道(Channel),每个通道可以独立设置。
时基单元
- PSC: Prescaler,预分频,即时钟频率除以该值,得到定时器时钟频率。
- CNT: Counter,计数器,计数到该值时,产生中断。
- ARR: Auto Reload Register,自动重载寄存器
- RCR: Repetition Counter Register,重复计数器
时钟来源
- 来自RCC(时钟树)
- 来自从模式控制器的触发信号TRIG
- 来自外部参考信号ETRF
降频
时钟树的时钟频率通常过高,所以需要降频
时钟树中的APB分频器
连接到TIM时,中间有个倍频器
。倍频器在分频器等于1时为1,在分频器大于1时为2。这使得倍频器降频。这就是PSC的作用。
降频的倍数 = PSC + 1
PSC ∈ [0,65535]
eg: PSC = 3,则时钟频率为时钟树频率/4
ARR、CNT、RCR
CNT
对PSC输入的脉冲进行计数。可以递增,也可以递减。CNT ∈ [0,65535]ARR
自动重装寄存器设定定时的周期。ARR ∈ [0,65535]RCR
重复计数器设定定时的周期。RCR ∈ [0,65535],次数为RCR+1。即CNT计数溢出的次数。达到后触发update事件。高级定时器才有。
CNT的计数方式:
- 上计数 counting up:从零开始计数,达到ARR值后溢出归零。定时周期为ARR+1。
- 下计数 counting down:从ARR开始计数,到零后溢出回归ARR。定时周期为ARR+1。
- 中心对齐 center align:先上溢出,再下溢出。
eg:
stm32f1系列的四种定时器
- TIM1 and TIM8:高级定时器,支持定时、PWM、捕获、比较等。(Advanced Timer)
- TIM2 to TIM5:通用定时器,支持定时、PWM、捕获等。(General Timer)
- TIM9 to TIM14:通用定时器,支持定时、PWM等。(General Timer)
- Tim6 and TIM7:基本定时器。(Basic Timer)
寄存器预加载
PSC
ARR
RCR
具有寄存器预加载机制。(缓冲机制)。为了安全,防止动态改变ARR时CNT“跑飞”至最大值。PSC、RCR强制开启预加载,无法关闭。ARR默认关闭,需手动开启。
- 活动寄存器(Active Register)
- 影子寄存器(Shadow Register)
向寄存器写值,值会先进入影子寄存器,当触发update事件后,再写入活动寄存器。
输出比较
PWM信号(Pulse Width Modulation脉冲宽度调制信号)
- 占空比: 占空比 = 输出信号的持续时间/定时周期 * 100%
- 周期恒定,占空比可调。用占空比调节信号的大小。
CCR:(Capture/Compare Register)捕获/比较寄存器,用于设定输出信号的持续时间。CCR ∈ [0,65535]
时基单元决定周期,CCR决定占空比。
CCR输出模式
输入捕获
定时器有四个通道,可作为输入,也可以作为输出。做输入时,把外部信号输入进来,然后使用定时器对这个信号的时间参数进行测量,这种功能就叫输入捕获
做输出时,使用定时器向外输出精确定时的方波信号,这种功能叫输出比较
输入捕获就是捕捉信号变化的时间点,并把它保存下来。利用这个就可以对输入信号的时间参数进行测量。
从模式控制器
作为从机 | 作为主机 |
---|---|
(被控制) | (控制别人) |
Slave Mode disable 从模式禁止 | Reset 复位 |
Encoder Mode 1 编码器模式1 | Enable 使能 |
Encoder Mode 2 编码器模式2 | Update 更新 |
Encoder Mode 3 编码器模式3 | Compare Pulse 输出比较脉冲 |
Reset Mode 复位模式 | Compare OC1Ref 输出比较参考信号1 |
Gated Mode 门模式 | Compare OC2Ref 输出比较参考信号2 |
Trigger Mode 触发模式 | Compare OC3Ref 输出比较参考信号3 |
External Clock Mode1 外部时钟模式1 | Compare OC4Ref 输出比较参考信号4 |
相关中断
- define TIM1_BRK_IRQChannel ((u8)0x18) 刹车功能
- define TIM1_UP_IRQChannel ((u8)0x19) 定时溢出中断,时间到了就触发。
- define TIM1_TRG_COM_IRQChannel ((u8)0x1A) 定时器触发中断
- define TIM1_CC_IRQChannel ((u8)0x1B) 定时器捕获比较中断,设置CCR寄存器值可以触发。
相关API
1 | // 以中断方式启动时基单元 |
8_ADC
Analog to Digital Converter (模拟信号到数字信号的转换)
模拟信号 | 数字信号 |
---|---|
时间和幅度都连续 | 时间和幅度都离散 |
自然界的信号 | 计算机的信号 |
12位逐次逼近型ADC
SAR (Successive Approximation Register) 逐次逼近寄存器
12位
- 12位指的是采样深度(使用多少位二进制数来表示一个采样点)
- 如0-3.3v电压,使用4位ADC采样,即0000-1111,表示把0-3.3v电压分成$2^4-1$份,每份对应0.22v。
- ADC的采样深度越深,转换的结果越精细。采样深度是权衡ADC性能的重要指标之一
逐次逼近型
其结构类似天平,每一次比较进行寄存器调整,直到采样结束。
四位逐次逼近型ADC示例
- 输入2.21v模拟信号
- 采样保持电路闭合–电容充电–采样保持电路断开–此后由于电容储能,保证后续输入电压不会改变。
- 向结果寄存器最高位 $b_1$(代表1.76v)写1,
- 此时电压发生器输出的电压就是1.76v,比2.21v小,
- 所以继续向低一位的寄存器$b_2$(代表0.88v)写1,
- 此时电压发生器输出的电压就是1.76 + 0.88 > 2.21 ,所以将其改为0,向低一位寄存器$b_3$(代表0.44v)写1,。
- 以此类推,逐步逼近。直到采样结束。
ADC的基本原理
- 对于stm32f103c8t6来说,ADC输入有12个,其中p0-p9为模拟输入引脚,还有一个内置温度计,一个参考电压。
- 12个ADC各有一个开关,开关控制ADC的采样通道。
- 常规序列、注入序列:对12个ADC进行顺序或注入采样。
ADC采样时间和转换时间
采样时间:放重物。转换时间:调整砝码
完成一次转换的总时间 = 采样时间 + 转换时间
采样时间、转换时间都需要表示成ADC时钟周期的倍数
$$时钟周期(Cycles) = \frac {1}{ADC时钟频率} $$
- eg: ADC时钟频率为14MHz,则$时钟周期Cycles = \frac{1}{14}us$
- eg:
- $转换时间 = 0.9us = 12.5 * \frac{1}{14}us = 12.5cycle$
- $采样时间 = 0.1us = 1.5 * \frac{1}{14}us = 1.5cycle$
转换时间
(采样深度 + 0.5 )个ADC时钟周期
采样时间
即采样开关闭合的时间,即采样电容充电的时间。
- 事实:采样精度本身就是有限的
- 电容充电只能随时间增加而无限接近输入的采样电压。所以出现了采样效率与采样精度的抉择。
- 只需保证采样误差远小于ADC的最大精度即可结束采样。
- $采样误差 < \frac 1 4 *ADC分辨率 $
- 例:对应stm32f103c8t6,采样深度12位,则$分辨率 = \frac {(3.3-0)} {(2^{12}-1)} \approx 0.8mV $
- 量程: 0-3.3v,分辨率:0.8mV,则$采样误差 < \frac 1 4 *0.8mV = 0.2mV $
最优采样时间:
- 模拟输入信号的内阻与采样电容是串联关系,所以根据欧姆定律,内阻越大,充电电流越小,充电速度越小,采样时间越长。
- 理论上,采样时间只于信号源内阻有关。
- $$ T_{最优采样时间} = (R_{信号源内阻} + R_{采样电路的电阻}) * C_{采样电容} * ln(2^{采样深度+2})$$
- 对于stm32f103c8t6来说,$R_{采样电路电阻} = 1kΩ,C_{采样电容} = 8pF , 采样深度 = 12 $
- 最终带入 $$T_{最优采样时间} = (R_{信号源内阻} + 1000) * 77.6 * 10^{-12} $$
表示为周期的形式: $采样时间*采样频率 $
对于stm32f103c8t6来说,只有8个周期档位可以选择。实际开发中,选择相近的周期选择即可
API
1 | // 启动常规序列 |