【嵌入式八股11】STM32

一、STM32 启动流程

  1. 启动区域选择:STM32 依据 boot 引脚的设置来确定启动区域,具体如下:

引脚状态 启动方式 描述

|-----|----------|------------------------------------------------------------------------------------------|
| x 0 | 片内 Flash | 从代码区启动,支持 ICP 下载方式(如 SWD、JTAG 烧录),这是最常用的启动方式,代码存储在片内 Flash 中,稳定可靠。 |
| 0 1 | 系统存储器 | 通过内置 ROM 启动,采用 ISP 下载(出厂预置代码,常见的如使用 UART 烧录)。此方式一般用于出厂时的程序烧录或者在没有 SWD、JTAG 接口的情况下进行程序更新。 |
| 1 1 | SRAM | 从 RAM 启动,但数据在掉电后会丢失。这种启动方式常用于一些调试场景,方便快速测试代码,不过由于数据易失性,不适用于正式的产品运行。 |

  1. 运行 bootloader :当确定启动区域后,处理器开始运行 bootloader,主要包括以下几个步骤:

    • 初始化寄存器:处理器会将各个寄存器的值初始化为默认值,为后续的程序运行做好准备。
    • 硬件设置 SP、PC,进入复位中断函数 Rest_Hander()
      • 从 0x0800 0000 读取数据赋值给栈指针 SP(MSP),并设置为栈顶指针 0x2000 0000 + RAM_Size。这一步确定了栈的起始位置,为函数调用等操作提供了空间。
      • 从 0x0800 0004 读取数据赋值给 PC(指向 Reset_Handler 中断服务函数)。通过以下代码实现:

    LDR R0, = SystemInit
    BLX R0

  • **设置系统时钟,进入 SystemInit()**:

  • 设置 RCC 寄存器各位,配置系统的时钟源、分频系数等,以确保系统能够稳定运行在合适的时钟频率下。

  • 设置中断向量表偏移地址,根据启动区域的不同,使用以下代码进行设置:

    #ifdef VECT_TAB_SRAM
    SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. /
    #else
    SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /
    Vector Table Relocation in Internal FLASH. */
    #endif

  • **软件设置 SP,__main 入栈(系统初始化函数)**:通过以下代码将 __main 函数入栈,进一步进行系统的初始化操作:

    LDR R0,=__main
    BX R0

  • **加载 data、bss 段并初始化_main 栈区**:由于哈弗体系结构决定了数据与代码分开存储,所以需要将 Flash 中的数据拷贝进入 SRAM,完成数据段和 bss 段的初始化。

  1. 跳转到 main():完成上述一系列初始化操作后,程序跳转到 main() 函数,开始执行用户编写的应用程序代码。

二、OTA(Over-The-Air)的情况

在 FLASH 中添加引导程序后,引导程序与 APP 程序将各自对应一个中断向量表。假设引导程序占用 N + M Byte 的 FLASH 空间。

  1. 上电启动流程:上电后,单片机从复位中断向量表处获取地址,并跳转执行复位中断服务函数,执行完毕后执行主函数。随后执行 Bootloader 中程序跳转的相关代码跳转至 APP,即地址 0x08000004 + N + M 处。进入主函数的步骤与 Bootloader 函数一致。

  2. 中断处理流程:当运行在主函数时,若有中断请求被响应,此时 PC 指针本应当指向位于地址 0x08000004 处的中断向量表,但由于程序预先通过"SCB->VTOR = 0x08000000 | ADDR_OFF;"这一语句,使得中断向量表偏移 ADDR_OFF(N + M)地址,因此 PC 指针会跳转到 0x08000004 + N + M 处所存放的中断向量表处,随后执行本应执行的中断服务函数,在跳出函数后再进入主函数运行。 以下是实现程序跳转至 APP 的示例代码:

    void iapLoadApp(uint32_t appxAddr)
    {
    iapfun jumptoapp;
    // 检查 appxaddr 处存放的数据(栈顶地址 0x2000****)是不是在 RAM 的地址范围内
    if( 0x20000000 == ( ((vu32)appxAddr) & 0x2FFE0000) )
    {
    // 拷贝 APP 程序的复位中断函数地址,用户代码区第二个字为程序开始地址(复位地址)(强制跳转到函数地址处执行,函数指针的方式)
    jumptoapp = (iapfun)(vu32)(appxAddr + 4);
    // 初始化 APP 堆栈指针(用户代码区的第一个字用于存放栈顶地址),重新分配 RAM
    MSR_MSP((vu32)appxAddr);
    // 执行 APP 的复位中断函数,跳转到 APP
    jumptoapp();
    }
    }

三、中断相关知识

  1. 中断的过程
    • 中断初始化
      • 设置中断源,使某个外设具备产生中断的能力,例如配置 GPIO 引脚为外部中断模式。
      • 设置中断控制器,对某个外设的中断通道进行使能或屏蔽操作,同时设置中断优先级,以确定多个中断同时发生时的处理顺序。
      • 使能 CPU 中断总开关,允许 CPU 响应中断请求。
    • CPU 运行与中断响应:CPU 在运行正常程序的过程中,每执行完一条指令(指令的执行包含多个时钟周期,如取指、译码、执行等)都会检查是否有异常或中断产生。当产生中断(如用户按下按键)时,中断信号先经过中断控制器,然后传递给 CPU。
    • 中断处理步骤
      • 保存现场:将 PC、LR、MSP、通用寄存器、FPU 等相关寄存器的值压栈,保存当前程序的运行状态,以便中断处理完成后能够恢复继续执行。
      • 分辨异常/中断,调用对应的异常/中断处理函数:根据中断源的类型,找到对应的中断向量表中的地址,跳转到相应的中断处理函数进行处理。
      • 恢复现场:中断处理完成后,将之前压栈的寄存器值出栈,恢复 PC 的值,使程序继续执行原来的任务。
    • 中断优先级处理:在执行高优先级中断时,如果低优先级中断到来,低优先级中断不会被丢失,而是会等待高优先级中断处理完毕后再进行处理。
    • 中断向量表:当中断发生时,PC 设置为一个特定地址,这些地址按优先级排列就构成了异常向量表,它存储了各个中断处理函数的入口地址。
  2. 中断的定义与分类
    • 定义:中断是指正在执行某事件时,被另一个事件打断,从而造成任务切换的过程。
    • 分类:分为内核异常和外部中断。内核异常通常由 CPU 内部的一些错误或特殊情况引起,如复位、硬件故障等;外部中断则由外部设备(如按键、传感器等)产生的信号触发。
  3. 嵌套向量中断控制器 NVIC:NVIC 用于处理多个优先级中断到来后的处理顺序。当多个中断同时发生时,NVIC 根据预先设置的中断优先级,先处理优先级高的中断,处理完后再处理优先级低的中断。

四、STM32 定时器

  1. 定时器分类
    • 系统滴答定时器 SysTick:并非外设,而是 CM3 内核的一部分,主要用于产生系统时钟节拍,为操作系统提供基本的时间管理功能。
    • 看门狗定时器 WatchDog:包括 IWDG 独立看门狗和 WWDG 窗口看门狗。IWDG 采用独立时钟,主要用于监视硬件错误,当在规定时间内没有喂狗操作时,会触发系统复位;WWDG 采用系统时钟,用于监视软件错误,必须在规定时间窗口内刷新,否则也会触发系统复位,并且在进入 WWDG 中断时,可以保存复位前的数据,防止跑飞后跳过某些代码段。
    • 基本定时器 TIM6、TIM7:具有预分频和重装载寄存器功能,可用于简单的定时任务,如定时触发 ADC 转换等。
    • 通用定时器 TIM2、TIM3、TIM4、TIM5:除了基本定时器的功能外,还支持输出比较、输入捕获、PWM 输出、单脉冲等功能,应用较为广泛,如电机控制、PWM 调光等场景。
    • 高级定时器 TIM1、TIM8:在通用定时器的基础上,增加了死区控制功能,常用于需要控制功率器件(如 MOSFET)的场合,以避免上下桥臂同时导通造成短路。
  2. 基本定时与 PWM 原理
    • 基本定时:通过设置预分频寄存器和重装载寄存器的值,来确定定时器的定时周期。预分频器用于对定时器的时钟进行分频,重装载寄存器则存储定时器的计数值。
    • PWM:除了预分频和重装载寄存器外,还需要设置比较寄存器。比较寄存器的值决定了 PWM 波形的占空比,通过改变比较寄存器的值,可以实现对 PWM 波形的调整。

五、STM32 ADC

  1. 基本特性:STM32F1 的 ADC 精度为 12 位,每个 ADC 最多有 16 个外部通道。各通道的 A/D 转换可以单次、连续扫描或间断执行,ADC 转换的结果(6 - 12 位)可以左对齐或右对齐储存在 16 位数据寄存器中。ADC 的输入时钟不得超过 14MHz,其时钟频率由 PCLK2 分频产生。
  2. 数据处理与通道特性:一个 ADC 的不同通道读取的值在共用的 DR 寄存器中,因此在进行下一个通道采集前需要将数据取走,否则数据会丢失。此外,ADC 还具有注入通道,它可以在规则通道转换时,强行插入转换,用于处理一些优先级较高的模拟信号采集。
  3. 参考电压与采集精度:参考电压一般为 3.3V,采集精度与位数相关,计算公式为最大测量电压 / 2^采样位数,例如 3.3V / 2^12,采样方式采用逐次逼近法。

六、STM32 DMA

  1. DMA 作用:当外部设备(如硬盘、显卡、网络适配器等)需要与主存储器进行数据交换时,传统方式需要通过中央处理器(CPU)作为中介来完成数据传输操作。但在大量数据传输的情况下,这种方式会使 CPU 过多地参与数据传输,降低整体性能。而 DMA 可以在 CPU 不介入的情况下,将数据在外设与内存中进行传递,从而提高系统的运行效率。
  2. CPU 搬运数据与 DMA 传输对比
    • CPU 搬运数据顺序
      • 外设设置状态寄存器置位。
      • CPU 读取外设数据寄存器到 CPU 通用寄存器。
      • CPU 将通用寄存器数据写入内存。
    • DMA 传输优势:DMA 可以独立完成数据传输,不需要 CPU 频繁参与,节约了 CPU 的资源。
  3. DMA 配置
    • 配置 DMA 控制器:设置 DMA 通道、数据传输方向(外设到存储器或存储器到外设)、传输模式(单次传输、循环传输等)、数据宽度、传输计数等参数。
    • 分配内存:如果是外设到存储器的数据传输,需要分配一块足够大小的缓冲区。
    • 配置 DMA 通道:将外设和 DMA 通道连接起来,通常需要配置外设的 DMA 请求触发方式和 DMA 通道的优先级等参数。
    • 触发 DMA 传输:启动数据的传输,DMA 控制器将自动执行数据的传输,而不需要 CPU 的干预。
  4. DMA 工作模式
    • 循环模式:单轮传输结束后,重置传输计数器,重置传输地址为初始值,再次开始新一轮循环,适用于需要不断重复传输相同数据的场景。
    • 双缓冲区:一个缓冲区传输完成中断触发后,缓存地址乒乓交换,同时触发回调函数,常用于处理连续的数据传输,提高数据处理的效率。
  5. 实际应用:在实际应用中,需要分析性能瓶颈是数据频率还是数据量过大。如果是数据频率问题,可以采用双 DMA BUF 的方式来提高数据的处理速度;如果是数据量过大,则可以使用单个大 DMA BUF 来一次性传输更多的数据。

七、STM32 看门狗

  1. IWDG 独立看门狗:采用独立时钟,不受系统时钟的影响,主要用于监视硬件错误。在正常运行时,程序需要定期进行喂狗操作(即向看门狗计数器写入特定值),如果在规定时间内没有喂狗,看门狗计数器会溢出,从而触发系统复位,保证系统在硬件出现异常时能够恢复正常运行。
  2. WWDG 窗口看门狗:采用系统时钟,用于监视软件错误。它要求程序必须在规定的时间窗口内进行刷新操作,否则会触发系统复位。窗口看门狗的优势在于可以防止程序跑飞后跳过某些关键代码段,并且在进入 WWDG 中断时,可以保存复位前的数据,以便后续分析问题。

八、IO 口类型

分类 电平特性 用途 备注

|------|------------------------------------------------------|-----------------------------------------------------|---------------------------------|
| 上拉输入 | 常态为高电平(通过上拉电阻连接 VCC) | 主要用于 IO 读取操作,当外部设备没有连接时,IO 口保持高电平状态 | 在一些按键输入电路中常用,按键按下时拉低电平,松开时恢复高电平 |
| 下拉输入 | 常态为低电平(通过下拉电阻连接 GND) | 同样用于 IO 读取操作,当外部设备没有连接时,IO 口保持低电平状态 | |
| 推挽输出 | 可以输出高电平和低电平,且都有较强的驱动能力,IO 输出 0 时接 GND,IO 输出 1 时接 VCC | 一般用于 IO 输出操作,如控制 LED 灯的亮灭、驱动小型继电器等 | 驱动负载能力强,能够直接驱动一些简单的外部设备 |
| 开漏输出 | 只能输出低电平,高电平没有驱动能力,需要外部上拉电阻才能真正输出高电平 | 常用于实现线与功能,如在 IIC 总线中,只要有一个设备给低电平,那么总线都会被拉低,从而实现线与逻辑 | 在一些需要多个设备共享总线的场景中非常有用 |

九、STM32 主频、Flash、SRAM 大小

类型 主频 Flash 容量 RAM 容量 内核

|---------------|------|--------|-------|-----|
| STM32F407IGH6 | 168M | 1024KB | 192KB | M4 |
| STM32L151RET6 | 32M | 512KB | 80KB | M3 |
| STM32F103C8T6 | 72M | 64KB | 20KB | M3 |
| HC32L130E8PA | 48M | 64KB | 8KB | M0+ |

十、ADC 采样原理

ADC(Analog-to-Digital Converter)采样原理采用逐次逼近法,这一过程和用天平称物重非常相似。具体来说,天平称重物时,从最重的砝码开始试放,与被称物体进行比较,若物体重于砝码,则该砝码保留,否则移去。然后再加上第二个次重砝码,同样根据物体与砝码重量的比较结果决定第二个砝码的去留,如此一直加到最小一个砝码为止。最后将所有留下的砝码重量相加,就得到了物体的重量。

仿照这一思路,逐次比较型 A/D 转换器将输入模拟信号与不同的参考电压作多次比较,使转换所得的数字量在数值上逐次逼近输入模拟量对应值。通过不断地比较和调整,最终得到与输入模拟信号相对应的数字量输出。

相关推荐
define菜鸟#4 小时前
51单片机实验五:A/D和D/A转换
单片机·嵌入式硬件
良许Linux4 小时前
如何系统地入门学习stm32?
stm32·单片机·学习
KaiGer6665 小时前
AUTOSAR图解==>AUTOSAR_SWS_EFXLibrary
单片机·汽车·嵌入式·autosar
li158172604146 小时前
FEMDRW032G-88A19江波龙 工规级/工业宽温级/车规级 eMMC 应用领域 车载系统、工控设备、智能终端等
嵌入式硬件·车载系统·云计算
the sun347 小时前
STM32各个外设和CortexM3内核的关系
stm32·单片机·嵌入式硬件
电子艾号哲7 小时前
STM32单片机入门学习——第42节: [12-2] BKP备份寄存器&RTC实时时钟
stm32·单片机·学习
云山工作室7 小时前
基于单片机的热释电红外报警器(论文+源码)
单片机·嵌入式硬件
A-花开堪折8 小时前
Qemu-STM32(十五):STM32F103加入Flash控制器
stm32·单片机·嵌入式硬件