基础知识说明

1. 上拉输入

  • 悬空 / 无外接:引脚 = 高电平(平时高)
  • 外接 GND(接地、开关按下):引脚 = 低电平(按下低)
  • 口诀:默认高,接地变低

2. 下拉输入

  • 悬空 / 无外接:引脚 = 低电平(平时低)
  • 外接 VCC(接电源、开关按下):引脚 = 高电平(按下高)
  • 口诀:默认低,接电变高

选择原则:模式和外部模块保持默认状态一致,若外部模块默认输出低电平,就选择输入低电平(下拉输入),若外部模块默认输出高电平,就选择输入高电平(上拉输入) 。       

三极管示意图:

左边是基极,带箭头的是发射极,剩下的是发射极

一.STM32所需用到的函数解析:

对于LED闪烁所需要用到的库函数:

可指定GPIOA,GPIOB,调用这个函数后,所指定的GPIO外设就会被复位。

可将指定的端口设置为高电平

可将指定的端口设置为低电平

根据第三个参数的值来设置指定的端口(Bit_RESET是低电平,Bit_SET是高电平)

二.STM32与51外设的逻辑语关系:

2.1LED

LED正极接面包板正极,负极接GPI/O口时输入低电平亮,反之,输入高电平亮,蜂鸣器是低电平发出响声,高电平不发声,且LED初始化模式和频率设置如下

2.2按键

但对于按键是相同的当按键按下时,函数的返回值均为0,初始化模式和频率设置如下

(按键Speed的取值与实际使用无关)

例:if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1)==0)

2.3光敏电阻

光敏电阻的特性:

  • 有光照时:光敏电阻阻值很小(比如几百欧~几千欧)
  • 被遮挡 / 黑暗时:光敏电阻阻值很大(几兆欧甚至更高)

对于光敏电阻,当选择上拉输入时:

  • 被遮挡(光敏电阻阻值大) → 内部上拉主导 → 引脚高电平 → 返回 1
  • 有光照(光敏电阻阻值小) → 光敏电阻拉低主导 → 引脚低电平 → 返回 0

上图符号表示或门,可以有多个输入,但是只能有一个输出,执行的是或的逻辑,在输出端只要有一个是高电平1,就输出的是高电平1,只有全部输入低电平0,才会输出0

上图符号是与门,可以有多个输入,但是只能有一个输出,执行的是与的逻辑,在输出端只要有一个是低电平0,就输出的是低电平0,只有全部输入高电平1,才会输出1

上图符号是非门,只能有一个输入和一个输出,执行的是非的逻辑,在输出端只要有一个是低电平0,就输出的是高电平1,只要有一个是高电平1,就输出的是低电平0,

上图是数据选择器,有多个输入,一个输出     

三.GPIO 

简介:单片机的引脚,用来读外部信号控制外部设备

GPIO模式: 

LED是浮空

四.EXTI(外部中断)

4.1EXTI简介

简介:STM32 引脚触发中断,外部电平 / 边沿变化触发程序跳转

AFIO的用处:

  • AFIO 的核心作用:AFIO 主要用于引脚复用功能的选择和重定义,是 STM32 中配置 GPIO 引脚特殊功能的关键模块。
  • STM32 中 AFIO 的两大核心任务
    • 复用功能引脚重映射:调整外设默认引脚映射关系,解决引脚资源冲突,优化硬件设计。
    • 中断引脚选择:确定外部中断线与具体 GPIO 引脚的对应关系,配置外部中断输入源。

4.2步骤:

  1. 开启GPIO和AFIO的时钟                                                                                                       
  2. GPIO初始化                                                                                                                             
  3. AFIO选择中断引脚                                                                                                                                                  
  4.  EXIT初始化                                                                                                                             
  5. NVIC中断分组                                                                                                                           
  6. NVIC配置                                                                                                                                      //若是PX5到PX9,则通道为 EXTI9_5_IRQHandler                                                                    //若是PX10到PX15,则通道为 EXTI15_10_IRQHandler                                                            //NVIC_IRQ通道可在stm32f10x.h文件的297行之后找到

五.TIM定时器 

工作图:

5.1TIM定时中断

5.1.1关于定时器的函数

时钟源选择:

时基单元:

中断输出控制:

运行控制:(来决定定时器运行和静止)

写预分频值的函数:

改变计数器的计数模式:

选择是否有预装:

给自动重装器写一个值:

配置时基单元时可通过以下公式定时:

此为定时1s时所配置的函数:

因为预分频器和计数器都有一个数的偏差,所以要减个1(实际分频数=预分频数+1)

  • ARR 控制 波形长短(周期 / 频率)        下图就是设置ARR值的函数
  • PSC决定定时器的计数频率           

清除标志位:

5.1.2步骤:

  1. 开启TIM时钟                                                                                                   
  2. 配置时钟源                                                                                              
  3.  时基单元初始化                                                                                                    对于计数:当计时器数到ARR的值加一(100)就会清零重新开始计算                                                     (ARR+1)*(PSC+1)/72000000就是每增加一所需要的时间                                        TIM_Prescaler:决定了 “计数的速度”,数值越大,数得越慢。                                              TIM_Period:决定了 “数多少个数才溢出”,数值越大,溢出越慢。
  4. 中断输出配置                                                                                                                             硬件只会自动置 1,不会自动清 0!必须软件手动清零(通过TIM_ClearFlag函数来实现)。
  5. NVIC分组和配置(和EXTI一样)
  6. TIM使能                                                                                                                                   

5.2TIM输出比较

5.2.1OC(Output Capture)输出比较

简介:输出比较可以通过比较 CNT 与 CCR 寄存器值的关系,来对输出电平进行置 1、置 0 或翻转的操作,用于输出一定频率和占空比的 PWM 波形。

5.2.2PWM (Pulse Width Modulation) 脉冲宽度调制

PWM的频率越快,它等效模拟的信号就平稳 

占空比决定了PWM等效出来的模拟电压的大小 

若占空比是以0.1%的速率来变化的,即10%->10.1%->10.2%->10.3%,则分辨率为0.1%

  • PWM 频率Freq = CK_PSC / (PSC + 1) / (ARR + 1)
  • PWM 占空比Duty = CCR / (ARR + 1)
  • PWM 分辨率 Reso = 1 / (ARR + 1)

PWM的输出比较模式:

  • 蓝色斜线:代表定时器的计数器 CNT 的值随时间变化的过程。它从 0 开始,一直向上计数,直到达到最大值后自动清零,重新开始计数,形成锯齿状的上升波形。
  • 红色水平线:代表捕获 / 比较寄存器 CCR 的值,这里数值是 30。当 CNT 计数值小于这个值时,输出 PWM 为有效电平;大于等于时则变为无效电平,它决定了 PWM 的占空比。
  • 黄色水平线:代表自动重装载寄存器 ARR 的值,这里数值是 99。当 CNT 计数到这个值时,就会自动清零并重新计数,它决定了 PWM 的周期(频率)。

参数计算:

PWM占空比:Duty=CCR/(ARR+1)

  • ARR 控制 波形长短(周期 / 频率)        下图就是设置ARR值的函数
  • CCR 控制 高电平长短(占空比)           CCR=300->300 个时钟高电平

5.2.3步骤:

  1. 开启时钟               
  2. 配置时钟源(TIM)和初始化(GPIO) GPIO初始化不能使用推挽输出(Mode_Out_PP),只能使用复用推挽输出(Mode_AF_PP)
  3. 实基单元初始化(与上文TIM相同)
  4. 输出比较初始化不同通道对应的引脚不同如下图
  5. TIM使能
  6. 外部封装一个函数,来设置CCR的值

 5.2.4各个通道对应的引脚

5.2.5舵机

舵机的内部图:

工作原理:PWM信号输入到控制板,给控制板一个指定的目标角度,电位器就会检测目标当前角度,如果大于目标角度就会反转,反之就会正转

输入 PWM 信号要求:周期为 20ms,高电平宽度为 0.5ms~2.5ms

周期20ms:从一个上升沿到下一个上升沿的时间为20ms。

舵机分为两种:旋转角度180和360

旋转角度180:输入不同信号脉冲宽度旋转角度不同

旋转角度360:输入不同信号脉冲宽度旋转方向和速度不同

电机驱动板的硬件电路:

5.2.6函数解读

用来配置输出比较模块的,一个函数对应一个输出单元

给输出比较结构体赋一个默认值

用来配置强制输出模式

单独更改CCR寄存器的值,可用来更改占空比

仅高级定时器使用,在使用高级定时器输出 PWM 时,需要调用这个函数,使能主输出,否则 PWM 将不能正常输出。

 

用来给结构体赋初始值,当从通用计时器更换为高级定时器时,需要配置的成员变多,如果没有配置,就会导致高级定时器输出PWM时会出现问题,所以我们可以先给所有成员先赋一个初始值,然后修改部分结构体成员的方式来处理问题。 

对于普通/开漏推挽输出,引脚的控制权是来自于输出数据寄存器的(GPIO_Mode_Out_PP)

若想让定时器来控制引脚,则需要使用复用开漏/推挽输出的模式,输出控制权将转移给片上外设

(GPIO_Mode_AF_PP),PWM波形才能通过引脚输出

5.2.7重映射

定义:将片上外设(如串口、定时器)的默认 I/O 引脚,切换到芯片上其他备用引脚。(例:

将作用于PA0的功能转移到PA15上)

引脚重映射配置函数

步骤:
  1. 开启时钟(必须开启AFIO)

  2. 引脚重映射配置

 第一行是选择了部分重映射方式一(参考手册上有详细的说明)

对于引脚PA15:上电后默认复用为了调试端口JTDI,若想让其作为普通的GPIO端口,则需解除调试端口

5.3TIM输入捕获

5.3.1IC(Input Capture)输入捕获

简介:输入捕获模式下,当通道输入引脚出现指定电平跳变时,当前 CNT 的值将被锁存到 CCR 中,可用于测量 PWM 波形的频率、占空比、脉冲间隔、电平持续时间等参数。

四个输入捕获和输出比较通道,共用4个CCR寄存器,以及四个通道的引脚(CH1-CH4)也是共用的,所以两者只能使用一个,不能同时使用        

5.3.2频率测量

  • 测频法:在闸门时间 T 内,对上升沿计次,得到 N,则频率 fx​=N/T
  • 测周法:两个上升沿内,以标准频率fc​计次,得到 N,则频率 fx​=fc​/N
  • 中界频率:测频法与测周法误差相等的频率点 fm​=fc​/T​(令测频法和测周法的N相等,然后将fx解出来)

fc从哪里来?

  • 硬件来源

    • 系统时钟(如 HSE 晶振 72MHz)
    • 定时器时钟(经过分频后的频率,比如 1MHz)
    • 外部高精度晶振(比如 8MHz)
  • 软件配置

    • 比如定时器配置为:
      • 时钟源:72MHz
      • 预分频 PSC=71 → 分频系数 72
      • 计数时钟:fc = 72MHz / 72 = 1MHz
    • 这个 1MHz 就是你在测周法里用的 fc

高频适合测频法,低频适合测周法

当待测频率小于中界频率时为低频,高于中界频率时为高频

5.3.3主从触发模式

主模式:可将定时器内部的信号映射到TRGO引脚,用于触发别的外设

即:主动发时钟、主动发起通信,说了算

从模式:接收其他外设或者自身外设的信号,用于控制自身定时器的运行

即:被动等时钟、被动响应,听指挥

选择从模式:

触发源选择:选择从模式的触发信号源

选择从模式输入的触发源

选择主模式输出的触发源

5.3.4输入捕获和PWMI基本结构

输入捕获:

先转运CNT到CCR中,再触发从模式使CNT清零

PWMI:

对左上角的图进行分析:

  • 在触发上升沿时,CCR1先赋值CNT,然后令CNT=0,在高电平时间内CNT一直++
  • 在触发下降沿时,给CCR2赋值CNT,这时CNT是在高电平期间的值,然后在低电平时间内CNT也一直++
  • 在触发下一个上升沿时,给CCR1赋值CNT,这时的CNT是一个周期的总值
  • 则CCR1/CCR2=占空比

5.3.5步骤:

IC配置步骤:

  1. 开启时钟
  2. 配置GPIO,时钟源
  3. 时基单元初始化
  4. 输入捕获初始化
  5. 选择触发源和从模式
  6. TIM使能
  7. 封装函数,获得输入捕获的频率

同时要配置PWM

分析:

  • tim2的psc,arr只负责控制输出的频率,而tim3的psc负责测周法中的fc,arr负责不让计数器溢出
  • 必须将PWM波配置完全(占空比,频率,分辨率),否则无法测量

例子分析:当输入信号为100HZ时


先明确你的定时器配置

  • TIM3 时钟:72MHz
  • PSC 预分频:72-1 = 71
  • 计数频率 = 72MHz / (71+1) = 1MHz
  • 意思:计数器每 1μs 加 1

100Hz 信号的周期是多少?

频率 f = 100Hz 周期 T = 1 /f = 0.01 秒 = 10,000 微秒(μs)


计数器会计多少个数?

因为 1μs 计 1 个数 10000μs 就会计 10000 个数

则输入捕获测量的频率值为1MHz/10000

5.3.6各个通道对应的引脚

5.3.7输入捕获和输出比较之间的差别

输入捕获 输出比较
引脚 输入端口 输出端口
执行流程 接收到输入信号,执行CNT锁存到CCR的动作 根据CCR和CNT的大小关系来执行输出动作

  • 每个通用定时器和高级定时器都有4个输入捕获通道(在输入捕获中,高级定时器和通用定时器没有区别,基本定时器没有输入捕获功能)

函数方面上的差别:

输入捕获下:CCR是只读的,要用GetCapture

输出比较下:CCR是只写的,要用SetCompare

5.4编码器接口(Encoder Interface )

  • 编码器接口可接收增量(正交)编码器的信号,根据编码器旋转产生的正交信号脉冲,自动控制 CNT 自增或自减,从而指示编码器的位置、旋转方向和旋转速度
  • 每个高级定时器和通用定时器都拥有 1 个编码器接口
  • 两个输入引脚借用了输入捕获的通道 1 和通道 2

5.4.1正交编码器

正转:超前90°

反转:滞后90°

                                                                                A相                                              B相

分析:

在TI1和TI2上计数的情况下:若A相上升沿,则相对信号的电平是指B相的电平高低,此时B相高电平,就为向下计数

5.4.2编码器接口基本结构

过程:

  • 输入捕获的前两个通道通过GPIO口接入编码器的A、B相
  • 通过滤波器和边沿检测极性选择产生TI1FP1、TI2FP2通向编码器接口
  • 编码器接口再通过预分频器控制CNT的时钟,同时还根据编码器的旋转方向控制CNT的计数方向

5.4.3步骤:

  1. 开启时钟
  2. 配置GPIO(因为编码器接口就是一个带方向控制的外部时钟,所以不需要配置内部时钟)
  3. 时基单元配置
  4. 输入捕获初始化 因为只需配置滤波器和极性边沿选择,所以分频选择和选择是否直流的结构体参数可以去掉
  5. 编码器接口配置 因为此处可以进行极性边沿选择,所以上处进行初始化时可省略,且此处配置会覆盖上面函数的参数;这里的上升沿不代表上升沿有效,因为旋转编码器上升沿和下降沿始终都是有效的,而是代表TI1和TI2是否反相,选择Rising通道不反相,选择Falling通道反相 
  • 反相:通道的输入信号直接送入定时器,不做电平翻转
  • 不反向:通道的输入信号先被取反,再送入定时器
配置 含义 效果
Rising, Rising 两个通道都不反相 编码器正转时计数器向上计数
Falling, Rising CH1 反相,CH2 不反相 计数方向整体反转
Rising, Falling CH1 不反相,CH2 反相 计数方向整体反转
Falling, Falling 两个通道都反相 相位关系不变,方向和默认一致

六.ADC(模拟-数字转换器)

6.1ADC简介

简介:将模拟电压转换为数字变量,可将ADC看成一个电压表,将引脚的电压值测出,放在一个变量里

  • ADC:将模拟电压转换为数字变量,是模拟电路到数字电路的桥梁。
  • DAC:将数字变量转换为模拟电压,是模拟电路到数字电路的桥梁。
  • 12 位(位数越高,量化结果就越精细,对应分辨率越高)逐次逼近型 (ADC的工作模式)ADC,AD转化开始到产生结果的时间为1us(1MHz,此为stm32中,ADC最快转换频率)
  • 输入电压范围:0~3.3V,转换结果范围:0~4095(输入电压和转换结果为一 一对应关系)

6.2逐次逼近型ADC

STM32的通道有18个

ADC逐次比较:给DAC一个数据使其生成一个对应的电压(已知),然后与通道输入的一个未知电压进行比较,若DAC的电压比未知电压大,就通过二分法使DAC电压变小,不断重复就得到了未知的电压

6.3ADC的基本结构

分析:

  • 输入通道有18个:16个GPIO口和2个内部通道;
  • AD转换器里的规则组最多选择16个通道,注入组最多选择4个通道;
  • 转换的结果存放在数据寄存器中,其中规则组有1个寄存器,注入组有四个;
  • 触发控制可分为软件触发和硬件触发,硬件触发主要来自于定时器和外部中断的引脚,RCC是推动ADC逐次比较的时钟;
  • 模拟看门狗用于监测转换结果的范围,若超出设定阈值,就通过中断输出控制向NVIC申请中断
  • EOF是结束信号

规则组的四种转换模式:

  • 单次转换,非扫描模式                                  只有序列1的通道转换有效
  • 多次转换,非扫描模式
  • 单次转换,扫描模式             将前7个序列的通道都转换,将数据结果放在数据寄存器里,并用DMA将数据挪走(防止数据被覆盖)
  • 多次转换,扫描模式

总结:

  • 单次 + 非扫描:单通道、转一次就停(只有第一个通道)
  • 单次 + 扫描:多通道序列跑一遍就停
  • 连续 + 非扫描:单通道高速连续采样(只有第一个通道)
  • 连续 + 扫描:多通道循环采样,高速数据采集

数据对齐:

  • 数据右对齐(一般使用)
  • 数据左对齐(不想要高分辨率时使用)

AD转换时间:

  • AD 转换的步骤:采样,保持,量化,编码
  • STM32 ADC 的总转换时间为: TCONV = 采样时间 + 12.5 个 ADC 周期(量化,编码所需时间)
  • 例如:当 ADCCLK=14MHz(最大频率),采样时间为 1.5 个 ADC 周期 :TCONV  = 1.5 + 12.5 = 14 个 ADC 周期 = 1μs

校准:

  • ADC 有一个内置自校准模式。校准可大幅减小因内部电容器组的变化而造成的准精度误差。校准期间,在每个电容器上都会计算出一个误差修正码 (数字值),这个码用于消除在随后的转换中每个电容器上产生的误差
  • 建议在每次上电后执行一次校准
  • 启动校准前, ADC 必须处于关电状态超过至少两个 ADC 时钟周期

硬件电路:

  • 点位器产生可调电压的电路

中间的滑动端可输出一个0~3.3V的可调电压,向上滑电压增大,向下电压减小

  • 传感器输出电压的电路

传出端感器阻值变小,下拉作用变强,输出电压下降,

传出端感器阻值变大,下拉作用变弱,输出电压上升,

  • 电压转换电路

通过串联分压来实现测量VIN电压

6.4步骤

  1. 开启RCC时钟
  2. 配置GPIO口 AIN模式下,GPIO口是无效的,目的是为了防止GPIO口的输入输出对模拟电压造成干扰,AIN模式是ADC的专属模式
  3. 选择规则组的输入通道
  4. 规则组通道配置
  5. ADC初始化
  6. ADC使能
  7. ADC校准
  8. 封装一个用于得到转换值的函数

以上是选择单次转换,非扫描模式的操作步骤

若选择多次转换,非扫描模式,则如图所示:

大参数稳定,小参数更快

给SWSTART置1,开始转换

返回SWSTART的状态,由于SWSTART在开始转换后立刻就清零了,所以此函数返回值与转换是否结束无关

七.DMA直接存储器存取

7.1DMA简介

简介:不用CPU参与,DMA 自己在内存 ↔ 外设之间和内存 ↔ 内存高速搬数据

  • 12个独立可配置的通道:DMA1(7个通道),DMA2(5个通道)
  • 每个通道都支持软件触发和特定的硬件触发

7.2存储器映像

  • 在stm32中变量是存储在SRAM里面的,用const修饰的常量是存储在Flash里面的
  • 访问ADC1的DR寄存器方式:ADC1->DR
ROM 只读存储器(程序闪存)
  • 断电数据保留
  • 只读为主,可擦写
  • 存放:烧录固件、常量
  • STM32:片内 Flash
RAM 随机存取存储器(运行内存)
  • 断电数据丢失
  • 读写速度快
  • 存放:程序运行变量、栈、堆
  • STM32:片内 SRAM

7.3DMA基本结构

分析:DMA的数据转运可以是存储器(一般指Flash和SRAM)到外设,也可是外设到存储器,也可是Flash到SRAM,但不能是SRAM到Flash(Flash只读)

当是存储器到存储器时,外设的参数应该写Flash的

数据宽度:可选择字节(Byte)、半字(HalfWord)、字(Word)

地址自增:外设寄存器不需要自增,存储器需要自增

自动重装器:转运完成后是否恢复到未转运前传输计数器的数字         

传输计数器:自减计数器,用于设定需要转运几次

M2M:用于选择软件触发(用于存储器到存储器)或硬件触发(方式:ADC、串口、定时器),但软件触发不能和自动重装器一起用,软件触发的目的是为了使传输计数器清零,而自动重装器是防止其清零

DMA转运条件:

  • DMA必须使能
  • 传输计数器必须大于0,若其等于0,且没有自动重装器,这时就要给DMA_Cmd失能,再给传输计数器一个大于0的数,然后使能开启
  • 触发源必须有触发信号

当传输数据和被传输数据的传输宽度不同时:

  • 大数据传到小数据时,高位会被舍弃
  • 小数据传到大数据时,高位会补0

7.4步骤

  1. 开启时钟注:DMA的时钟在AHBP总线上
  2. DMA初始化 其中AddrB,AddrA,Size均为自定义变量
  3. DMA使能
  4. 封装一个DMA转运函数

当DMA和ADC一起使用时

  1. 开启时钟
  2. 设置ADC的时钟
  3. GPIO初始化
  4. ADC规则组通道配置和ADC初始化
  5. DMA初始化
  6. DMA和ADC使能
  7. ADC校准
  8. ADC触发
  • 以上为ADC连续扫描模式的配置方法
  • 强制转换 (uint32_t) 就是把 “指针类型的地址” 转换成 “32 位整数”
  • 选择DMA_PeripheralDataSize_HalfWord(低16位数据)是因为低16位数据是规则组的数据,高16位数据是ADC2的(stm32中没有ADC2)
  • AD_Value为自定义数组

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐