0%

【MCU】MCU开发知识点记录与总结

内核相关部分

Cortex-M内核异常与中断

Cortex-M内核主要包括如下几种异常:

Reset:上电时复位或者热复位时调用,其被视为一种特殊形式的异常,永久启用、固定优先级-3

NMI:不可屏蔽中断,永久启用、固定优先级-2,不能被Reset以外的任何异常抢占,其可配置为软件触发或者外设信号触发,通常配置来用于处理严重的异常情况。当然,本人并没用过此异常

  • NMI的应用场景由用户配置,如看门狗、

HardFault:优先级-1

  • 在Cortex-M0内核中,只支持对齐访问,如果所编译的变量类型为非字节对齐(如int变量地址不能被4整除),可能会产生运行错误

MemManage:由于内存保护相关故障触发的异常,可配置触发方式/源,如非对齐内存访问、除零异常等

  • 例:如果指针变量并非为四字节对齐,同时内核使能了非对齐内存方法异常,那么当程序访问该指针变量时,会触发MemManage异常。当然,在GCC编译中也有相应的编译选项–-munaligned-access,为非字节对齐变量生成特定的程序指令
  • 如下代码所示,表示配置使能Cortex-M4内核的USGFAULT, BUSFAULT, MEMFAULT异常,启用DIV 0和未对齐异常内存访问
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #define OS_NVIC_SHCSR                       0xE000ED24
    #define OS_NVIC_CCR 0xE000ED14
    #define USGFAULT (1 << 18)
    #define BUSFAULT (1 << 17)
    #define MEMFAULT (1 << 16)
    #define DIV0FAULT (1 << 4)
    #define UNALIGNFAULT (1 << 3)

    *(volatile UINT32 *)OS_NVIC_SHCSR |= (USGFAULT | BUSFAULT | MEMFAULT);
    *(volatile UINT32 *)OS_NVIC_CCR |= (DIV0FAULT | UNALIGNFAULT);

BusFault:内存总线所检测的错误

UsageFault:与指令执行相关的故障异常,包括:未定义指令、指令执行状态无效、异常返回错误
如果在实际的函数指针强制转换调用中,传入参数与实际函数入参不一致,可能会导致未定义的行为错误

SVCall:由SVC指令触发的异常,操作系统环境中,程序可使用SVC指令主动挂起异常,访问内核和设备驱动

PendSV:实时操作系统可通过主动触发PendSV异常进行上下文切换

SysTick:系统滴答定时器归零时触发的异常,通常用作系统节拍

Interrupt(IRQ):中断

全局开关中断操作

1
2
3
4
5
6
7
8
9
10
11
__disable_irq();    // 将 PRIMASK 寄存器的值设置为 1,禁止所有中断
__enable_irq(); // 将 PRIMASK 寄存器的值设置为 0,开启所有中断
__set_PRIMASK(1); // PRIMASK 值为 1 ,所有可屏蔽中断的优先级为 1,表示所有可屏蔽中断均不能被中断处理程序处理,只能由 NMI 处理程序处理
__set_PRIMASK(0);

// 在 Cortex-M 架构中,FAULTMASK 寄存器控制所有异常的优先级
__set_FAULTMASK(1); // FAULTMASK 寄存器的值为 1 时,所有异常的优先级为 1,表示所有异常均不能被中断处理程序处理,只能由 NMI 处理程序处理
__set_FAULTMASK(0);

CPSID F //关异常,FAULTMASK=1
CPSIE F //开异常,FAULTMASK=0

MCU获取CPU使用率原理

  • 理论来说,裸机程序不能获取CPU使用率
  • 在RTOS下,可以通过计时器来测量CPU在空闲任务的运行时间,计算其占整体运行时间的比率即可得到CPU使用率
    • CPU使用率 = (CPU总运行时间 - CPU空闲时间) / CPU总运行时间
    • 通过使用计时器,可以计算上电运行以后的 CPU总使用率,也可以计算 一个时间周期内 CPU的使用率

系统相关部分

芯片时钟频率选择

选择芯片时钟频率,可以综合考虑芯片的性能需求、功耗需求、发热需求等

  • 性能:如果运行任务复杂,如包括图形处理、视频处理、复杂数运算等,须选择高频率
  • 功耗:如果产品对耗电有要求,可以考虑选用较低同时能够满足使用的频率,需要结合硬件综合评估
  • 发热:高频率会增加芯片的发热量,产品设计空间密闭狭小情况下,需要考虑芯片可能过热工作
  • 工艺:芯片制造工艺不够精湛,在高时钟频率下工作,可能会不稳定。 (当然,本人没遇到过相关情况)

外设接口相关部分

GPIO的输出速度

  • 根据外部设备要求进行配置
    • 常规的控制LED灯、按键等,采用2MHz即可
    • GPIO模拟SPI、I2C等总线,可以配置为10MHz
    • 控制DDR、USB等超高速接口,配置50MHZ
  • GPIO的输出速度越高,其驱动电路的功耗就越高

内部与外部晶振

  • 内部晶振精度较外部晶振低
  • 一般情况下,使用内部晶振足以满足常用需求,包括spi、iic、uart的外设通信
  • 如果要求时钟精度高,或应用于精密仪器等场景,或用到高速外设如usb、sdio的高精度时钟要求场景,考虑用外部晶振
    • SDIO 接口要求时钟信号的精度为 2% 或以下
      • 存储卡、扩展卡、无线模块
      • 高速图像传感器、高速存储卡
    • USB 接口要求时钟信号的精度为 5% 或以下
      • 鼠标、键盘、打印机、网络摄像头、耳机
      • 高速摄像头、高速打印机、高品质音频设备

外设接口的通信频率

MCU常用外设的通信速率范围

接口类型 通信频率 精度
SDIO 25 MHz~50 MHz 2% 以下
USB 12 MHz~480 MHz 5% 以下
I2C 100 kHz~400 kHz 1% 以下
SPI 1 MHz~20 MHz 1% 以下
UART 1200 bps~921600 bps 1% 以下

UART外设

  • UART(通用异步收发传输器)是一种设备、通信的基础,规定了数据的格式和帧结构;RS232和RS485是基于UART的电气接口标准,其规定了电气特性和物理特性
  • TTL电平的通信速率:MCU的UART外设理论最高速率取决于其外设的时钟源
    • 可通过芯片手册查看时钟树,获取外设的时钟频率
  • RS232为点对点通信,其标准传输速率须在20Kbps下,抗干扰能力差,传输最大距离不超过15m
  • RS485的理论最高传输速率为10Mbps,可一对多通信,理论最大传输距离1500米(9600bps)
  • 测试较高波特率场景要求时,可以通过示波器抓取uart外设波形,计算其误差是否满足,或者通过逻辑分析仪在收发两端分别测试验证

以下转述参考文章: UART波特率对时钟精度的要求有多高?

分频误差:波特率是根据系统时钟分频产生的,而系统时钟和波特率可能不是整数倍的关系,所以分频时也会产生误差。但是,当系统时钟较高,或者波特率较低时,这个误差影响很小。

时钟误差:波特率的主要误差还是取决于系统时钟的误差。串口通讯对时钟误差的要求有多高呢?
每一个字节都有一个起始位做同步,所以误差只会在一个字节内累计。在最后一个位采样时,误差最大,允许极限误差为0.5位。
按照每个字节10位计算,最大允许误差为±0.5/10=±0.05,即±5%。
考虑到串口通讯涉及收发两端,两端都可能存在误差,所以,每端的误差最好控制在±2.5%以内。当数据位、校验位等较多时,要求的时钟误差就更高一些。
考虑到上面所说的分频误差,一般来说,当时钟误差小于±2%时,串口通信是比较可靠的。

UART通信协议

  • 空闲状态
  • 起始位
  • 数据位
  • 奇偶检验位
  • 停止位

空闲位和空闲中断

空闲位:在UART通信中两个字节或者两个帧之间的 一位高电平,用于表示线路的空闲状态;当接收端检测到线路从”1”跳转到”0”(起始位)时,可以知道下一字节开始传输

  • 当一次发送多个字节时,每字节间会有个空闲位(可配置?看实际设计),用于区分字节

空闲中断:在接收到数据之后,如果在一个字节的时间内没有再接收到数据,就会产生空闲中断

  • 其一般用于接收不定长数据,用于标识一个数据包/一帧数据

SPI外设

SPI 的 MOSI、MISO引脚在空闲状态下为低电平,SCK空闲电平可以指定

QSPI

IIS接口

IIS(Inter-IC Sound),又称集成电路内置音频总线,是飞利浦在1986年定义的数字音频传输标准,与IIC并无相关性。

相对其它协议,IIS接口协议相对简单,没有地址和片选机制。在总线上,只能同时存在一个主设备和发射设备:提供时钟的为主设备,主设备可以是发射设备、接收设备或者协调两者的其它控制设备皆可。

主要应用于处理器与音频编解码器之间的音频数据传输

IIS协议定义了三根信号线:时钟信号SCK、数据信号SD、左右声道选择信号WS

  • SCK/BCLK 位时钟:等于通道数 * 位宽 * 采样率
  • SDIN/DIN 数据线:串行数据,以二进制补码形式在数据线上传输,在WS变化后的第一个SCK脉冲先传输最高位
  • WS/LRCLK 声道选择信号:用于区分左右声道的数据,0表示左声道,1表示右声道。也叫帧时钟,等于声音的采样频率
  • MCLK 主时钟(可选):提供主时钟频率给接收端,确保采样率的准确性。 在高质量音频输出、使用外部音频解码器、多通道音频传输时,主时钟是必须的。

标准IIS模式

其它部分

bin文件合并大小

假如一个bin文件大小为6KB,烧录地址为0x8000000,另一个bin文件大小为60KB,烧录地址为0x8002800(偏移10KB),那么此两bin文件合并大小为70KB,而非66KB

为什么一个内存地址对应一个字节

一个内存地址,通常对应一个内存单元,在大部分计算机系统中,一个内存单元通常是一个字节,因为字节是计算机处理数据的基本单位。即一个地址表示的是一个8-bit大小的空间。

在某些特定硬件或者设计中,一个地址可能会对应不同的数据单位,STM32有特定设计把一片内存映射成位带,一个地址对应 1 位。或者在某些系统设计中,一个地址对应的是16-bit大小空间。

大端/小端存储

多字节数据存储的字节顺序问题:

  • 大端存储(Big-endian)是指数据的高位字节存储在低地址,低位字节存储在高地址。
  • 小端存储(Little-endian)是指数据的低位字节存储在低地址,高位字节存储在高地址。

例,32bit的16进制数 0x12345678 在内存中的存放方式:

大端内存地址 0x1000 0x1001 0x1002 0x1003
大端存放内容 0x12 0x34 0x56 0x78

小端内存地址 0x1000 0x1001 0x1002 0x1003
小端存放内容 0x78 0x56 0x34 0x12

参考站点