Skip to content

Latest commit

 

History

History
384 lines (338 loc) · 217 KB

File metadata and controls

384 lines (338 loc) · 217 KB

单片机


1. 入门

1.1 用 STM32CubeMX 和 Clion 配置工程

Clion 创建工程

  1. 顶栏 File, New, Project, 左侧选STM32CubeMX, 设置工程目录和工程的名称, Create
    例如:
    Location: E:\Projects\MyProject
    
  2. 左栏双击 工程名.ioc, 右侧 Open with STM32CubeMX

STM32CubeMX 基础配置

在配置好Project Manager之前都不要点保存

  1. 上栏 Piniout & Configuration, 左栏RCC(时钟设置), 左栏右侧栏High Speed Clock 改为 Crystal Resonator (晶振)
  2. 左栏 System Core, SYS栏 (这里决定代码如何烧录) , 左栏右侧栏Debug改为Serial Wire
  3. 上栏 Clock Configuration 时钟配置示例
    • 左侧的输入频率应与硬件一致, 要照着原理图填, 不能填错, 例如这里是8MHz, 则 HSE 的 Input frequency也应填8M 硬件晶振
    • Pll Source Mux 选中 HSE
    • System Clock Mux 选中 PLLCLK
    • (主频) HCLK 下面例如 168 MHz max, 可直接配到最高主频, 框内填168, 回车让其自动计算
  4. 上栏 Project Manager
    • 左栏Project
      • 在ToolChain/IDE 处选择STM32CubeIDE
      • Ptoject Name 一定要和在Clion中建立的一致!!!
        例如:
        Project Name:              MyProject
        Project Location:          E:\Projects
        Toolchain Folder Location: E:\Projects\MyProject\
        
    • 左栏Code Generator, 勾选 Generate peripheral initialization as a pair of '.c/.h' files per peripheral
      • Src 文件夹储存 .c 文件
      • Inc 文件夹储存 .h 文件
  5. 顶栏 Generate Code, Overwrite

Clion 基础配置

  1. 回来后会出现 Board Config Files 弹窗, 随便选一个
    Clion面板配置弹窗
  2. 点击顶栏此处, Edit Configurations OpenDebugConfigurations
  3. 更改为对应烧录器的配置文件, 例如使用DAP-Link
    DAPLink配置文件

1.2 写一个闪灯程序

STM32CubeMX 配置 LED

  1. 看原理图, 例如看到LED2对应芯片上对应PC5管脚
  2. 上栏 Piniout & Configuration, 右下角搜索框搜索PC5
  3. 左键对应的引脚, 设置为GPIO_Output
    • (GPIO_Input 为读取引脚当前是高电平/低电平)
    • (GPIO_Output 为设置引脚当前是高电平/低电平)
    • (GPIO_Analog 为模拟信号)
  4. 左栏 System Core, GPIO栏, 左栏右侧栏选中PC5, 下方User Label, 可改为LED2
  5. 顶栏 Generate Code

Clion 写闪灯程序

  1. 在 main.c 的 while(1) 内输入
    HAL_GPIO_TogglePin(LED2_GPIO_Port, LED2_Pin); // LED2_xxx 已在 main.h 中定义
    HAL_Delay(500); // 阻塞500毫秒
  2. 顶栏 点 顶栏运行键 (构建并烧录)

1.3 STM32CubeMX的其他配置

  • 左栏 System Core, Analog栏
    • ADC模数转换器, (例如用在激光测距, 激光测距输入模拟信号, 需要转换为数字信号进行处理)
    • Timers 计时器
    • Connectivity 消息的传递转发, (例如串口、CAN)
    • Multimedia (例如DCMI接显示器或相机。不常用, 因为相机一般不会用STM32处理)
    • Middleware 中间层, (FREERTOS可以嵌入一个操作系统, USB_DEVICE例如用单片机开发一个键盘鼠标等)


2. 基础知识

  • 单片机, MCU, Microcontroller Unit
  • 开发板, Discovery,包含单片机
  • 单片机都是死循环, 不可退出
  • 总线: 连CPU和其他部件 (优势: 一条线上可挂多个设备, 节约连线) , 例如总线举例, 任一时刻只有一个发送数据, CPU是管理者
  • 三态门举例 三态门举例
  • 8位机、32机位机等, 数字为总线宽度, 代表CPU的ALU (逻辑运算单元) 能做8bit或32bit数据的加法和逻辑运算
  • FPU (浮点运算单元) 可做乘法
  • 位数宽度: 地址总线 <= 数据总线
  • 某一管脚同一时刻只能Input/Output择一, 数字信号/模拟信号择一
  • 开漏输出可通过的电流很大只能出低电平, 推挽输出高低电平都可
  • STM32处理器为降低功耗, 各模块需分别独立开启时钟, 需使用到某个外设模块时, 要先设对应的时钟
  • STM32单片机最多有7个16位并行I/O端口:PA~PG
  • 运行板子前建议先按复位键RST
  • 作为指令的关键变量定义时在前面加__IO以免被编译器优化掉
  • VCC是VDD是Power是高电平。例如发光二极管p极接VCC, N极接单片机控制的IO口, 当写入低电平时pn结正偏, 二极管导通发光
    • 例如, 一块上有三个LED数字灯, 一个数字的7个灯管为A~G, 小数点为P, 这块板子的IO口有ABCDEFGP123, 比如让2和D接低电平是让2号灯的D部位亮起
  • Program Counter(pc指针)完全由硬件控制, 指明当前运行哪个代码
  • C程序代码给计算机执行要经过编译、链接(link, 为每个函数分配入口地址)
  • main函数地址唯一且固定, 否则CPU不知从何开始
  • HAL函数是底层写好的
  • 函数定义前加__weak使程序内可出现其他同名函数, 运行的是编译后空间占用最大的函数
  • 定义后未使用的变量可以写UNUSED(a);防止出现warning
  • 色环电阻的数字:如470=47x10^0Ω, 472=47x10^2Ω
  • 场效应管可当作开关, 根据不同的型号, 在高电平或低电平时导通
  • PWM: 脉冲宽度调制, 占空比=(脉冲宽度W/周期T), 方波的占空比是1:1(50%), 占空比不同可用于做呼吸灯和控制电机转速
  • 串口通信以字节为单位;DMA、以太网等高速通信以数据包为单位
  • 查芯片型号:

2.1 单片机部件

  • Register (寄存器) : 放临时数据
  • Flash: 放程序
  • RAM: 内存
    • SRAM:静态内存, 不断电就一直在
    • DRAM:动态内存, 定时刷新, 读取速度远低于前者, 容量大
  • Instructrion Decode (指令解码器) : 把数变为控制信号 (操作数) (如加法后续再取两个数作为数据)
  • AMBA上总线
    • AHB(Advanced High performance Bus)作为系统总线
    • APB(Advanced Peripheral Bus)作为外设总线
      • APB1 用于低速外设
      • APB2 用于高速外设

2.2 单片机结构

  • 哈佛结构: 指令集中放置, 不会和数据混取, 更安全
  • 冯·诺曼结构 (普林斯顿) : 数据和控制放到一起 冯诺依曼普林斯顿

2.3 芯片命名含义(例如STM32F407ZGT6)

  • STM32: 产品系列, 基于ARM的32位控制器
  • F:产品类型, 通用类型
  • 407:产品子系列, 103增强型
  • Z:引脚数目 (T=36, C=48, R=64, V=100, Z=144)
  • G:山村存储器容量 (4=16KB, 6=32KB, 8=64KB, B=128KB, C=256KB, D=384KB, E=512KB, G=1024KB)
  • T:封装 (H=BGA, T=LQFP, U=VFQFPN, Y=WLCSP64)
  • 6:温度范围 (6=-40℃85℃, 7=-40℃105℃)

2.4 其他部位命名含义

  • P开头:外部管脚
  • VSS(接地)、VDD(电源)应分别接在一起
  • VBAT:接电池, 外部电源点开可保存一部分数据
  • NRST:N代表negative, 低电平复位
  • BOOT:模式选择
  • SYS:下载口
  • RCC:时钟(外部晶振很稳定, RC振荡器误差大)
  • GPIO:通用
  • ADC:模数转换(电压模拟信号转为数字信号, 例如声音采样)
  • TIM:定时器
  • UART: 通用串口收发设备
  • IIC:低速总线
  • SPI:高速总线

2.5 工程目录组成

  • .ioc 工程文件
  • core 源代码(可改)
  • drivers 底层源代码

2.6 读外设的方法

  • POLL 轮询(主动)
  • Interrupt 中断(被动)(关于中断的使用方法, 以前计算机以CPU为核心, 现在以储存器为核心, DMA不经过CPU直接内存存取效率高)

2.7 时钟频率

  • 普通8/16位单片机:只有1个系统的时钟频率
  • 基于ARM Cortex内核的MCU:具有多个时钟频率, 分别供给内核和不同的外设模块使用

2.8 CubeMX软件杂项

  • Clock Configuration 栏中HCLK是CPU工作频率
  • CSS数据选择器
  • 工程文件存在MDK-ARM
  • 为每个外设生成一个.c/.h文件以增加可读性:Project Manager栏, Code Generator, Generate pe...
  • 软件自己写的.c放进Core/Src; .h放进Core/Inc

2.9 Keil_v5软件杂项

HAL Init(); //初始化所有系统时钟和其他底层最基本的初始化
SystemClock_Config(); //初始化系统时钟
/*Initialize all configured peripherals*/ //初始化外设
while(1) {} //死循环
HAL_GPIO_ReadPin(...); //读引脚
HAL_GPIO_WritePin(...); //写引脚
HAL_GPIO_TogglePin(...); //写引脚的翻转电平
HAL_Delay(500); //阻塞500毫秒
  • 编译:左上角Batch Build
  • 左栏 gpio.c 分支内 stm32flxx.hal_flash.h内有厂家写好的驱动函数库
  • 一些函数如HAL_GPIO_ReadPin可以右键, Go To Definition可看参数说明
  • 插好板子后按左上角load(F8)
  • 例如 stm32flxx_it.c 中 HAL_GPIO_EXIT_IRQHandler(BTN0_Pin);所在处是中断服务程序入口
// e.g.按键按下灯灭松开灯亮
// (main函数外)
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
   if(GPIO_PIN_SET == HAL_GPIO_ReadPin(BTN0_GPIO_Port, BTN0_Pin))
   {
      HAL_GPIO_WritePin(LED0_GPIO_Port, LED0_Pin, GPIO_PIN_SET); //高电平
   }
   else if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(BTN0_GPIO_Port, BTN0_Pin))
   {
      HAL_GPIO_WritePin(LED0_GPIO_Port, LED0_Pin, GPIO_PIN_RESET); //低电平
   }
}


3. 时钟

3.1 APB1 peripheral clocks 和 Timer clocks:

  • APB1 Peripheral Clocks (APB1外设时钟) :
    • APB1 Peripheral Clocks 是系统总线上的一个时钟域, 它提供了对一系列外设 (如串口、SPI、I2C等) 的时钟信号。
    • 这个时钟域的频率通常由系统时钟源 (一般是HSI、HSE、PLL等) 分频得到, 因此它的频率不同于主时钟 (SYSCLK) 。
    • 这个时钟域可以通过设置RCC (Reset and Clock Control) 寄存器来调整其频率分频比例, 以满足外设的时钟要求。
  • Timer Clocks (定时器时钟) :
    • Timer Clocks 是专门为定时器模块 (如TIM1、TIM2、TIM3等) 提供的时钟信号。
    • 定时器时钟通常直接来自于APB1 Peripheral Clocks, 但在一些情况下, 也可以来自APB2 Peripheral Clocks。
    • 定时器时钟的频率可以通过分频器来配置, 以满足具体的定时器应用需求。这使得您可以根据应用的需要调整定时器的工作频率。

3.2 STM32时钟系统

  • 类型:
    • HSI(High Speed Internal)
    • HSE(High Speed External)
    • LSI(Low Speed Internal)
    • LSE(Low Speed External)
    • PLL(Phase Locked Loop)(锁相环倍频输出, 先乘背书产生极高的倍率再分频)
  • 选择:
    • 内部:无需精确的场景
    • 高速:CPU
    • 低速:RTC
    • HSI、HSE、PLL可用来驱动系统时钟
    • LSI、LSE二级时钟源

3.3 定时器

  • 定时器中断在初始化后是默认关闭的, 用之前要打开, 例如HAL_TIM_Base_Start_IT(&htim2);

3.4 分频

  • 上栏Pinout, 左栏Timers, TIM2, Parameter Settings:
    • Prescaler(PSC) 预分频, 最大为35999
    • Counter Period(CND) 计数器, 再次分频
  • e.g. Clock Configuration输入时钟为72MHz (这个数值是时钟配置界面最右侧的数值而非HCLK, 例如407的TIM1接在APB2上, 就需要看APB2 Timer Clocks的数值, TIM2接在APB1上, 就需要看APB1 Timer Clocks的数值), Prescaler 35999(模值为原数值+1,即36000), Counter Period 999(模值1000)
    最终频率 = 72MHz*(1/36000)*(1/1000) = 2Hz
    中断函数以一秒2次的速度调用, 即每0.5秒调一次
  • Parameter Settings栏中 CH Polarity: 空闲时是高还是低


4. Cmakelists

4.1 构建类型

构建类型用来指定编译器的优化级别和调试信息的生成。不同的构建类型会影响程序的性能和可调试性。

相比debug模式, release模式的不同点在于:

  • 开启更高级别的优化, 使得程序运行更快, 但也会增加编译时间。
  • 去掉调试信息, 使得程序占用更少的空间, 但也会导致无法使用调试器进行断点和变量查看。
  • 关闭断言, 使得程序更稳定, 但也会忽略一些潜在的错误。

一般来说, release模式适合发布给用户使用, 而debug模式适合开发和测试阶段。

set(CMAKE_BUILD_TYPE "Release")


5. 中断

中断模型

  • 某硬件发生了一个事件, 中断发生后就进入用户写的中断服务程序, 之后退出
  • 中断服务程序应小并且尽可能快, 如设置标志位然后就退出, 可在main函数里设置检测到这个标志位然后慢慢处理
  • callback是中断的回调函数, 自带的CLEAR清理中断防止中断一直存在
  • 中断可分为边缘型(例如在电压上升沿或下降沿产生中断)或电平型(例如在电压低电平时产生中断)
  • 一般速度高频率快的中断优先级高(左栏System Core, NVIC, Priority数越小)


6. 通信

6.1 串口

  • 串口(serial port、串行通信接口、COM接口) 是指一种接口的类型, 它可以用于串行通信, 即数据以比特为单位按顺序传输
  • 优势是节约管脚资源、减少线的使用(大量用在工业中), 劣势是速率低(USB口和CPU速率都高于串口)
  • 串口可以指任何使用串行数据传输的接口, 接口协议包括 UART、SPI、I2C 等
  • 通信标准如 RS-232、RS-485 等
  • 异步通信就像快递放门口; 同步通信就像快递面对面交付
  • 在EIA-RS-232C标准下, 逻辑1为-15~-3V电压, 逻辑0为3~15V电压
  • TTL串口逻辑1为Vcc, 逻辑0为0V, 无法与计算机项链, 只能用在单片机和芯片间
  • TTL转RS-232:MAX232芯片给5V用, MAX3232芯片给3V用

6.1 UART/USART

  • 通用同步异步收发器(Universal Synchronous Asynchronous Receiver/Transmitter: USART),通用异步收发器(UART)
  • UART是一种通用串行数据总线, 用于异步通信(发送的数据不含参考时钟)。该总线双向通信, 可以实现全双工传输和接收。在嵌入式设计中, UART用来与PC进行通信, 包括与监控调试器和其器件
  • 引脚:
    • TXD 发送端
    • RXD 接收端
    • GND 公共地
  • 异步通信:
    • 常用波特率 115200 等,波特率需双方一致,否则例如接收到一串等长的高低高低不知道该读成010101还是001100110011
    • 要设起始位(节约了线路但浪费了带宽,长度为 1/波特率 (也就是1bit))和停止位(1、1.5、2bit),例如一组全0的数据,起始位为0停止位为1, 则可以用1+8+1(0000000001),其中8是word length
    • 传输数据方式:
      • 轮询
      • IT(中断):发送端发完置标志位,再发下一个(占CPU)
      • DMA:CPU不知情,DMA把收到的趁CPU空闲放进CPU的内存中
    • 避免出现每包10bit传输时最后一包小于10bit无法接收:设idle中断(例如延迟只有1byte的时间长度)
    • 数据发送时存在一个数组里(buffer)
    • 奇偶校验位:加上这一位后1的个数应该是奇数或偶数
  • 为了使用printf函数,需将fputc替换为写串口,例如:
    #include <stdio.h>
    UART_HandleTypeDef *g_user_uart = &huart1; // 由CubeMX生成
    int fputc(int ch, FILE *p) // 一次发送一个char
    {
        // 参数为: 串口指针,发送的数据内容,一次发1字节,timeout 10ms
        // HAL_UART_Transmit是轮询,查询数据发送状态,8bit数据和停止位全发完才返回(阻塞式调用)
        HAL_UART_Transmit(g_user_uart, (uint8_t *)&ch, 1, 10);
        return ch; // 返回发送的字符
    }
    // 例如工程名叫stop_beep,想用printf,在Keil里左栏Project stop_beep,stop_beep文件夹右键,option,勾选Use MicroLIB

6.2 CAN

  • 闭环总线网络(ISO11898)高速、短距离, 它的总线最大长度为 40m, 通信速度最高为 1Mbps, 总线的两端各要求有一个120 欧的电阻。
  • 差分信号, 可以抑制共模干扰

6.4 SPI

  • SPI是串行外设接口 (Serial Peripheral Interface)的缩写, 是Motorola公司推出的串行接口技术, 是一种高速、全双工同步的通信总线。它以主从方式工作, 这种模式通常有一个主设备和一个或多个从设备, 信号线包括SDI (串行数据输入 Serial Digital IN)、 SDO (串行数据输出 Serial Digital OUT)、 SCLK (时钟)、 CS(片选)
  • 引脚:
    • SCK 同步时钟
    • MISO 主机输入 从机输出
    • MOSI 主机输出 从机输入

6.5 IIC

  • 多用于芯片间的通信
  • 引脚:
    • SCL 同步时钟
    • SDA 数据输入/输出端

6.3 RS232 RS485

  • 串口是物理接口,它属于硬件;而TTL、RS-232、RS-485是指的不同的串行通讯标准
  • TTL也称三极管逻辑,由于在早期的半导体都是双极型晶体管工艺的,所以就用这个名字来称呼我们常用的那个串口
  • RS232是一种比较老的标准,点对点传输,传输距离比较短,数据传输速率也比较低(<19.2Kbps)。一般在电脑、调试仪器、交换机等设备中使用,是异步串口协议
  • EIA-RS-232:
    • 平接型为了延长线,交叉型为了通信(如两个计算机之间)
    • 发送针有电压,接收针没有
    • 全双工
  • RS485是一种高级的标准,它支持多点和远距离传输,它是一种半双工的协议,可以实现在同一总线上传输多个设备的数据,同时具有抗干扰能力。RS485使用差分信号传输,数据传输速率高,可达10Mbps,并且可扩展到1200m以上的距离


7. Power

7.1 LDO

  • LDO 是一种线性稳压器, 使用在其饱和区域内运行的晶体管或场效应管(FET), 从应用的输入电压中减去超额的电压, 产生经过调节的输出电压。所谓压降电压, 是指稳压器将输出电压维持在其额定值上下 100mV 之内所需的输入电压与输出电压差额的最小值。(常见的LDO芯片7805 , 1117)
  • 低压降(LDO)线性稳压器的成本低, 噪音低, 静态电流小, 这些是它的突出优点。它需要的外接元件也很少, 通常只需要一两个旁路电容
  • 适用于低压差的降压(压差在某个比较低的范围内), 应用例如5v降至3.3v

7.2 DCDC

  • DC-DC的意思是直流变(到)直流(不同直流电源值的转换), 只要符合这个定义都可以叫DC-DC转换器, 包括LDO。但是一般的说法是把直流变(到)直流由开关方式实现的器件叫DC-DC
  • 应用例如24v降至5v


8. USB

  • USB分为host(电脑通常是)和device(只能作为外围设备如U盘鼠标),host和device只能相互接
  • 类型(Class for FS IP)(让主机的驱动识别你)
    • Audio Device Class 音频
    • Communication Device Class 通信(虚拟串口,COM口)(需又额外驱动支持,如link009(适用于STM32的USB口))
    • Download Firmware Update Device Class(DFU)下载固件
    • Human Interface Device Class 人机交互(HID)(如键盘鼠标)
    • Mass Storage Device Class 大容量存储(如U盘)