新建项目时选择core和device
core:
device: 包含启动文件,system和startup
仿真时钟
32位计算机:1字=32位=4字节,64位计算机:1字=64位=8字节
手动移植freertos时,需要配置时钟
Cortex M7内核引入了cache机制
M7内核的MCU时钟频率已经高达400MHz+,一般外存的工作速度远没CPU工作速度快,如果要保证内存访问的正常,要不就CPU降频访问,要不就引入缓存机制
CortexM0 M3 M4 M7内核都是基于ARMv7架构
M7内核支持6级流水线
M3 M4 M7主要体现在指令集、浮点运算、数字信号处理、是否有缓存cache、TCM、性能的差异、功耗
M3: 72
M4: 168/180
M7:480
STM32解释
ST:意法半导体
M:微电子
32:总线宽度
STM32最小系统
开发流程
芯片选型–原理图绘制–pcb绘制–打板
volatile理解
宏定义编程减少变量存储
F3 F4 F7 H7 GPIO异同
推挽输出和开漏输出
开漏输出可以实现线与,一个设备低电平,总线被占用
TTL肖特基触发器:将正弦波编程方波
模拟输入是不经过TTL肖特基触发器的
MCU对功耗是有要求的
控制外设的使能与否,就是控制外设的时钟,来达到根据需求使能外设
AHB系统总线接入总线矩阵连接Cotex-M3内核
AHB桥接出两个总线APB1和APB2用来挂载不同外设
清零操作和赋值操作
使能外设步骤
- 查找开发手册总线章节,确定外设是挂载在哪个总线上
- 查找RCC寄存器,使能对应外设时钟
F3 和 F4系列区别
将GPIO配置单独抽离,F3分为高低位配置,端口配置低寄存器和高寄存器
PP:推挽
OP:开漏输出
寄存器简称
CR:控制寄存器
ODR:数据输出寄存器
IDR:数据输入寄存器
stm32的寄存器组织形式:基地址+偏移
寄存器编程和库函数编程对比
HAL库所在层次
HAL库软件包组织形式
stm32官方固件包
边定义边使用,支持C99模式
修改cubemx安装包路径
BSP 板级支持
函数宏定义
stm32的启动过程
M3 M4 M7采用的都是哈弗结构
编写的代码最后都会被编译成芯片可以识别的指令集
编译工具链编译成芯片可以识别的指令
芯片上电后会触发复位异常
触发后程序会去0x00000000地址的地方,指向中断向量表,复位异常会对应一个入口位置。跳转到中断向量表特定偏移位置,获取里面的内容执行
复位异常指向的是程序入口位置
启动配置
选择不同组合的boot引脚,决定我们哪一块实际的物理内存地址被映射到0地址
针对不同的启动方式,我们可以将中断向量表放在FLASH里、系统存储器里、和SRAM里
任意一款stm32单片机都有一个.s文件,这个文件就是启动文件,为什么不是.c文件,因为系统刚启动时没有C语言运行环境
做了四个工作:
1、初始化堆栈指针
2、设置PC指针,PC-8个地址就是当前程序运行的地址
3、设置中断向量表
4、配置系统时钟
5、调用C库函数__main初始化堆栈的工作,最终会跳转到我们自己编写的main
THUMB :THUMB指令集名字
DCD:为目标分配一块以字对齐的内存
CPU会从0x00000000地址获取到堆栈顶地址
可以重新定义Reset_Handler
__main在微库里实现
RCC 复位与时钟外设
RCC在stm32中算一个外设,控制着复位和时钟
stm32有三种复位方式:系统复位、电源复位和后备域复位
备份域在主电源掉电后,外部纽扣电池供电
VDD表示主电源,VBAT备用电源
时钟
F4系列,系统时钟是可以输出到固定引脚上
F3 F4 F7时钟差异都在外设时钟上,外设可以配置得更加灵活
stm32中断
中断和异常继承于cotex 内核
可编程的优先级同意NVIC 嵌套向量中断控制器
EXTI 扩展中断和事件控制器
脉冲发生器一般用来唤醒MCU
H7 多了使用外设来唤醒mcu芯片
不勾选只能下载一次
中断和事件的区别
中断可以产生NVIC
事件走下面产生脉冲发生器
外部事件的变化可以触发ADC的转换
systick系统定时器
满载情况下,systick每0.233016s产生一次中断
SysTick_Config由cortex内核官方支持包提供
没有配置好中断优先级的话,阻塞函数禁止在中断处理函数中使用
HAL库
HAL库主要包含:外设的初始化和外设的使用
Instance实例化xx_HandleTypeDef 用来指示某一个具体的外设
Init成员:初始化外设的一些参数,如波特率,停止位等等
Hdma:外设对应的dma通道
LOCK:防止资源竞争,有些操作时不可重入的,例如主函数中正在对外设进行初始化,忽然来了一个中断又对外设进行初始化,这个锁就可以将外设保护起来,保证外设可以正常运行
STATUS:表示句柄结构体的状态也关联到外设的具体状态
外设初始化:HAL_xx_Init
HAL_xx_Init函数会去调用HAL_xx_MspInit函数,需要我们用户自己实现
外设的使用
DEBUG
- 使用仿真器连接开发板 SWD/JTAG
函数跳转信息需要在魔法棒里进行配置
当程序下载和debug的时候出现问题,下载器的速率可以适当降低
trace相关的可以在软件帮助手册中找到
开启debug调试和添加断点
步入:进入函数内部执行
步过:跳过函数执行
步出:跳出函数,回到调用的地方
指定行跳转
小黄箭头:回到当前程序停止的位置
断点只能放在小黑块里,小黑块里才有实际语句的执行
其他调试窗口:
命令窗口,一般不怎么使用
反汇编窗口:
符号窗口,变量函数所在位置
寄存器窗口
调用栈窗口,观察函数所处的关系
watch窗口,观察变量,一种直接拖,一种右键添加
默认是变量的地址,放程序运行后会显示值,是可以直接修改的
局部变量需要打断点才能监控,全局变量可以实时监控
memory窗口
虚拟串口,需要特殊的仿真器才能支持
逻辑分析仪和事件分析仪窗口都需要特定的仿真器来支持
重要重要重要窗口
E:中断是否使能 P:中断挂起标志位 A:中断是否被激活
外设分为:内核外设和stm32片上外设
要看到实时变化,把周期更新选择上
UART
F1 3 7和H7不同点
H7有两个时钟域,将寄存器读写和数据发送和接受分开,同时还多了fifo
填充fifo,DMA搬运一次,减轻填充一个字节就搬运一次
HAL_Init都做了什么
1.必须在main函数中首先被调用
2.配置systick,并生成每1ms的中断,刚开始systick由HSI配置后面就会改变HSE
3.设置中断优先级组为4,全部为抢占优先级
4.HAL_Msp_Init 全局硬件初始化函数
注意:如果使用中断的话,要在中断.c文件中将中断服务函数的句柄定义好,不然的话会跑进默认的句柄中
要使用串口中断的话,需要在初始化中将串口中断使能
这里使能的是接收非空中断
串口中断
串口rx有数据就会产生中断,这里每来一个字节数据就将它发送出去,可以实现不定长数据接受与发送
getchar()本质是启动一次字符获取