- 顶栏 File, New, Project, 左侧选STM32CubeMX, 设置工程目录和工程的名称, Create
例如: Location: E:\Projects\MyProject - 左栏双击 工程名.ioc, 右侧 Open with STM32CubeMX
在配置好Project Manager之前都不要点保存
- 上栏 Piniout & Configuration, 左栏RCC(时钟设置), 左栏右侧栏High Speed Clock 改为 Crystal Resonator (晶振)
- 左栏 System Core, SYS栏 (这里决定代码如何烧录) , 左栏右侧栏Debug改为Serial Wire
- 上栏 Clock Configuration
- 上栏 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 文件
- 左栏Project
- 顶栏 Generate Code, Overwrite
- 看原理图, 例如看到LED2对应芯片上对应PC5管脚
- 上栏 Piniout & Configuration, 右下角搜索框搜索PC5
- 左键对应的引脚, 设置为GPIO_Output
- (GPIO_Input 为读取引脚当前是高电平/低电平)
- (GPIO_Output 为设置引脚当前是高电平/低电平)
- (GPIO_Analog 为模拟信号)
- 左栏 System Core, GPIO栏, 左栏右侧栏选中PC5, 下方User Label, 可改为LED2
- 顶栏 Generate Code
- 在 main.c 的 while(1) 内输入
HAL_GPIO_TogglePin(LED2_GPIO_Port, LED2_Pin); // LED2_xxx 已在 main.h 中定义 HAL_Delay(500); // 阻塞500毫秒
- 顶栏 点
(构建并烧录)
- 左栏 System Core, Analog栏
- ADC模数转换器, (例如用在激光测距, 激光测距输入模拟信号, 需要转换为数字信号进行处理)
- Timers 计时器
- Connectivity 消息的传递转发, (例如串口、CAN)
- Multimedia (例如DCMI接显示器或相机。不常用, 因为相机一般不会用STM32处理)
- Middleware 中间层, (FREERTOS可以嵌入一个操作系统, USB_DEVICE例如用单片机开发一个键盘鼠标等)
- 单片机, 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、以太网等高速通信以数据包为单位
- 查芯片型号:
- www.alldatasheet.com
- bing搜索TJA1050 datasheet
- 手机app半导小芯
- Register (寄存器) : 放临时数据
- Flash: 放程序
- RAM: 内存
- SRAM:静态内存, 不断电就一直在
- DRAM:动态内存, 定时刷新, 读取速度远低于前者, 容量大
- Instructrion Decode (指令解码器) : 把数变为控制信号 (操作数) (如加法后续再取两个数作为数据)
- AMBA上总线
- AHB(Advanced High performance Bus)作为系统总线
- APB(Advanced Peripheral Bus)作为外设总线
- APB1 用于低速外设
- APB2 用于高速外设
- 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℃)
- P开头:外部管脚
- VSS(接地)、VDD(电源)应分别接在一起
- VBAT:接电池, 外部电源点开可保存一部分数据
- NRST:N代表negative, 低电平复位
- BOOT:模式选择
- SYS:下载口
- RCC:时钟(外部晶振很稳定, RC振荡器误差大)
- GPIO:通用
- ADC:模数转换(电压模拟信号转为数字信号, 例如声音采样)
- TIM:定时器
- UART: 通用串口收发设备
- IIC:低速总线
- SPI:高速总线
- .ioc 工程文件
- core 源代码(可改)
- drivers 底层源代码
- POLL 轮询(主动)
- Interrupt 中断(被动)(关于中断的使用方法, 以前计算机以CPU为核心, 现在以储存器为核心, DMA不经过CPU直接内存存取效率高)
- 普通8/16位单片机:只有1个系统的时钟频率
- 基于ARM Cortex内核的MCU:具有多个时钟频率, 分别供给内核和不同的外设模块使用
- Clock Configuration 栏中HCLK是CPU工作频率
- CSS数据选择器
- 工程文件存在MDK-ARM
- 为每个外设生成一个.c/.h文件以增加可读性:Project Manager栏, Code Generator, Generate pe...
- 软件自己写的.c放进Core/Src; .h放进Core/Inc
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); //低电平
}
}- 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。
- 定时器时钟的频率可以通过分频器来配置, 以满足具体的定时器应用需求。这使得您可以根据应用的需要调整定时器的工作频率。
- 类型:
- 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二级时钟源
- 定时器中断在初始化后是默认关闭的, 用之前要打开, 例如
HAL_TIM_Base_Start_IT(&htim2);
- 上栏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: 空闲时是高还是低
构建类型用来指定编译器的优化级别和调试信息的生成。不同的构建类型会影响程序的性能和可调试性。
相比debug模式, release模式的不同点在于:
- 开启更高级别的优化, 使得程序运行更快, 但也会增加编译时间。
- 去掉调试信息, 使得程序占用更少的空间, 但也会导致无法使用调试器进行断点和变量查看。
- 关闭断言, 使得程序更稳定, 但也会忽略一些潜在的错误。
一般来说, release模式适合发布给用户使用, 而debug模式适合开发和测试阶段。
set(CMAKE_BUILD_TYPE "Release")
- 某硬件发生了一个事件, 中断发生后就进入用户写的中断服务程序, 之后退出
- 中断服务程序应小并且尽可能快, 如设置标志位然后就退出, 可在main函数里设置检测到这个标志位然后慢慢处理
- callback是中断的回调函数, 自带的CLEAR清理中断防止中断一直存在
- 中断可分为边缘型(例如在电压上升沿或下降沿产生中断)或电平型(例如在电压低电平时产生中断)
- 一般速度高频率快的中断优先级高(左栏System Core, NVIC, Priority数越小)
- 串口(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用
- 通用同步异步收发器(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
- 闭环总线网络(ISO11898)高速、短距离, 它的总线最大长度为 40m, 通信速度最高为 1Mbps, 总线的两端各要求有一个120 欧的电阻。
- 差分信号, 可以抑制共模干扰
- SPI是串行外设接口 (Serial Peripheral Interface)的缩写, 是Motorola公司推出的串行接口技术, 是一种高速、全双工、同步的通信总线。它以主从方式工作, 这种模式通常有一个主设备和一个或多个从设备, 信号线包括SDI (串行数据输入 Serial Digital IN)、 SDO (串行数据输出 Serial Digital OUT)、 SCLK (时钟)、 CS(片选)
- 引脚:
- SCK 同步时钟
- MISO 主机输入 从机输出
- MOSI 主机输出 从机输入
- 多用于芯片间的通信
- 引脚:
- SCL 同步时钟
- SDA 数据输入/输出端
- 串口是物理接口,它属于硬件;而TTL、RS-232、RS-485是指的不同的串行通讯标准
- TTL也称三极管逻辑,由于在早期的半导体都是双极型晶体管工艺的,所以就用这个名字来称呼我们常用的那个串口
- RS232是一种比较老的标准,点对点传输,传输距离比较短,数据传输速率也比较低(<19.2Kbps)。一般在电脑、调试仪器、交换机等设备中使用,是异步串口协议
- EIA-RS-232:
- 平接型为了延长线,交叉型为了通信(如两个计算机之间)
- 发送针有电压,接收针没有
- 全双工
- RS485是一种高级的标准,它支持多点和远距离传输,它是一种半双工的协议,可以实现在同一总线上传输多个设备的数据,同时具有抗干扰能力。RS485使用差分信号传输,数据传输速率高,可达10Mbps,并且可扩展到1200m以上的距离
- LDO 是一种线性稳压器, 使用在其饱和区域内运行的晶体管或场效应管(FET), 从应用的输入电压中减去超额的电压, 产生经过调节的输出电压。所谓压降电压, 是指稳压器将输出电压维持在其额定值上下 100mV 之内所需的输入电压与输出电压差额的最小值。(常见的LDO芯片7805 , 1117)
- 低压降(LDO)线性稳压器的成本低, 噪音低, 静态电流小, 这些是它的突出优点。它需要的外接元件也很少, 通常只需要一两个旁路电容
- 适用于低压差的降压(压差在某个比较低的范围内), 应用例如5v降至3.3v
- DC-DC的意思是直流变(到)直流(不同直流电源值的转换), 只要符合这个定义都可以叫DC-DC转换器, 包括LDO。但是一般的说法是把直流变(到)直流由开关方式实现的器件叫DC-DC
- 应用例如24v降至5v
- 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盘)