STM32-F407ZGT6

STM32-F407ZGT6
沐飞STM32-F407ZGT6
144引脚 1024K字节闪存储存器 LQFP封装 -40°C~85°C工作范围
开发板介绍
开发板介绍
image-20210404103005743
image-20210404103005743
STM32内核
ARM内核的32位MCU系列
–Cortex-M内核
–标准的ARM架构
uCortex-M4采用ARMv7-ME架构
image-20210404103355273
image-20210404103355273
Cortex-M4与M3对比
image-20210404103505452
image-20210404103505452
ARMv7架构定义了三大分工明确的系列:
“A”系列:面向尖端的基于虚拟内存的操作系统和用户应用
“R”系列:针对实时系统;
“M”系列:对微控制器。
学习方法
掌握调试工具:JTAG
image-20210404102642577
image-20210404102642577
多使用JTAG调试代码,深入理解代码执行流程。在基础不够扎实的时候,不要走马换花的看,要做到深入理解代码涵义。
库函数和寄存器对比学习
项目中大多数用库函数。但是学习,如果你只会看几个函数的话,你根本没有学懂,遇到问题很难自己解决,所以必要了解一下寄存器配置原理,加深理解。
尤其前面几个章节实验,最好了解寄存器配置,加深对STM32本质的理解。
STM32最小系统
供电
复位
时钟:外部晶振(2个)
Boot启动模式选择
下载电路(串口/JTAG/SWD)
后备电池
连接串口
image-20210404151322239
image-20210404151322239
RXD和TXD是连接usb_232 PA9和PA10用来烧录程序
串口1(PA1)才能作为串口下载,也可以用于串口通信
PA2和PA3 只能用来串口通信,不能下载
下载程序flyMcu使用
搜索串口,F4波特率最高设置为76800 其他按照下图配置
image-20210404152655145
image-20210404152655145
下载程序是用Jlink
配置:
enterDebug
enterDebug
Setting
Setting
select
select
下载程序
load
load
STM32启动模式
image-20210404153858964
image-20210404153858964
由下图控制
image-20210404153911198
image-20210404153911198
STM32GPIO
7组每组16 从GPIOA.0GPIOA.15 ~~GPIOG.0GPIOG.15
每组IO口有10个寄存器
每个IO口都可以作为中断输入
IO口
4种模式:输入浮空,输入上拉,输入下拉,模拟输入
4种输出模式:开漏输出,开漏复用功能,推挽式输出。推挽式复用功能
4种最大输出速度:2Mhz,25Mhz,50Mhz,100Mhz
1 | 一个端口模式寄存器(GPIOx_MODER) |
端口模式寄存器
image-20210405164406767
image-20210405164406767
端口输出类型寄存器
image-20210405164434228
image-20210405164434228
高16位未使用
端口输出速度寄存器
image-20210405164457134
image-20210405164457134
端口上拉/下拉寄存器
image-20210405164518948
image-20210405164518948
端口输入数据寄存器
image-20210405164546230
image-20210405164546230
端口输出数据寄存器
QQ图片20210405165937
QQ图片20210405165937
端口上输出0或1是有影响的
端口置位/复位寄存器
image-20210405164613372
image-20210405164613372
端口位写0的话不会对端口有影响
写1就会置为1
端口配置锁存寄存器(待写)
端口位复用功能寄存器(待写)
跑马灯
重要源文件:
misc.c
stm32f4xx_rcc.c 一定要加
stm32f4xx_gpio.c 用于串口
stm32f4xx_usart.c SYSTEM里的usart.c有用到
顶层头文件
stm32f4xx.h
使用的头文件
1 |
使用的函数
1 | 重要函数: |
led.c
1 | GPIO_InitTypeDef GPIO_InitStructre; //定义结构体 |
main.c
1 | delay_init(168); |
寄存器操作版本
1 | //|=与&= |
位操作版本
1 | PFout(9)=1; //到sys.h中查看 通过将寄存器的位映射为地址,通过操作地址达到操作位的作用 (读-改-写) |
蜂鸣器
位置:F8引脚
蜂鸣器电路,接在三极管的C端
蜂鸣器电路图
蜂鸣器电路图
三极管
三极管
按键输入
1 | RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);//对应时钟使能 |
时钟系统
时钟频率的计算
PLLclock计算(常用)
image-20210429201803486
image-20210429201803486
STM32F4开发指南-库函数版本_V1
STM32F4开发指南-库函数版本_V1
image-20210429203507847
image-20210429203507847
SystemInit函数解读
初始化之后的状态:
SYSCLK(系统时钟) =168MHz
AHB总线时钟(HCLK=SYSCLK) =168MHz
APB1总线时钟(PCLK1=SYSCLK/4) =42MHz
APB2总线时钟(PCLK2=SYSCLK/2) =84MHz
PLL主时钟 =168MHz
获取系统时钟函数
初始化之后可以通过变量SystemCoreClock获取系统变量。如果SYSCLK=168MHz,那么变量SystemCoreClock=168000000。
Systick定时器
24位倒时
睡眠时也能工作
4个Systick寄存器
1 | CTRL SysTick 控制和状态寄存器 LOAD(开关) |
SysTick 控制和状态寄存器- CTRL
image-20210429211531521
image-20210429211531521
1 | 对于STM32,外部时钟源是 HCLK(AHB总线时钟)的1/8 |
SysTick 重装载数值寄存器- LOAD
image-20210429211659749
image-20210429211659749
SysTick 当前值寄存器- VAL
image-20210429211712874
image-20210429211712874
固件库中的Systick相关函数:
1 | SysTick_CLKSourceConfig() //Systick时钟源选择 misc.c文件中 |
端口复用
概念:本来是GPIO,复用完就作为串口1的发送接收引脚
复用器一次只允许一个外设的复用功能(AF)连接到对应的IO口
每个IO引脚都有一个复用器,该复用器采用16路复用功能输入(AF0到AF15),可通过GPIOx_AFRL(针对引脚0-7)和GPIOx_AFRH(针对引脚8-15)寄存器对这些输入进行配置,每四位控制一路复用。
AFRL寄存器
image-20210503214607884
image-20210503214607884
对于ADC和DAC,在GPIOx_MODER寄存器中将所需I/O配置为模拟通道
端口复用配置过程
1.GPIO端口时钟使能
2.复用外设时钟使能
3.端口模式配置为复用功能。 GPIO_Init()函数
4.配置GPIOx_AFRL或者GPIOx_AFRH寄存器,将IO连接
到所需的AFx。
1 | RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //使能GPIOA时钟 ① |
完全重映射
1 | GPIO_PinRemapConfig(GPIO_FullRemap_TIM2, ENABLE); //完全重映射 |
禁用JTAG
1 | GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable , ENABLE); // 改变指定管脚的映射,JTAG-DP 禁用 + SW-DP 使能,禁用JTAG |
NVIC中断优先级管理
STM32F40xx/STM32F41xx的92个中断里面,包括10个内核中断和82个可屏蔽中断,具有16级可编程的中断优先级。
位置:STM32F4xx中文参考手册》P234 表45和46
中断管理方法
image-20210503233951039
image-20210503233951039
抢占优先级 & 响应优先级区别
1.高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的。
2.抢占优先级相同的中断,高响应优先级不可以打断低响应优先级的中断。
3.抢占优先级相同的中断,当两个中断同时发生的情况下,哪个响应优先级高,哪个先执行。
4.如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行;
中断优先级设置
初始化函数:
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);
分组函数:
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);
最好只设置一次
代码:
1 | NVIC_InitTypeDef NVIC_InitStructure; |
串口通信
STM32的串口通信接口
UART:通用异步收发器
USART:通用同步异步收发器
STM32串口异步通信需要定义的参数
① 起始位
② 数据位(8位或者9位)
③ 奇偶校验位(第9位)
④ 停止位(1,15,2位)
⑤ 波特率设置
image-20210503235553407
image-20210503235553407
1 | void My_USART1_Init(void) |
状态寄存器
FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG);
image-20210504000831841
image-20210504000831841
数据寄存器
void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);
uint16_t USART_ReceiveData(USART_TypeDef* USARTx);
image-20210504000938955
image-20210504000938955
void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);
image-20210504001007646
image-20210504001007646
波特率计算公式
image-20210504001138065
image-20210504001138065
串口配置一般步骤
① 串口时钟使能:RCC_APBxPeriphClockCmd();
GPIO时钟使能:RCC_AHB1PeriphClockCmd();
② 引脚复用映射:
GPIO_PinAFConfig();
③GPIO端口模式设置:GPIO_Init(); 模式设置为GPIO_Mode_AF
④串口参数初始化:USART_Init();
⑤开启中断并且初始化NVIC(如果需要开启中断才需要这个步骤)
NVIC_Init();
USART_ITConfig();
⑥使能串口:USART_Cmd();
⑦编写中断处理函数:USARTx_IRQHandler();
⑧串口数据收发:
void USART_SendData();//发送数据到串口,DR
uint16_t USART_ReceiveData();//接受数据,从DR读取接受到的数据
⑨串口传输状态获取:
FlagStatus USART_GetFlagStatus();
void USART_ClearITPendingBit();
Printf支持
1 | //加入以下代码,支持printf函数,而不需要选择use MicroLIB |
外部中断
头文件 exti.h
1 | GPIOx.0映射到EXTI0 |
IO口外部中断在中断向量表中只分配了7个中断向量,也就是只能使用7个中断服务函数
image-20210504001736923
image-20210504001736923
中断服务函数列表
用于写中断后的操作
1 | EXTI0_IRQHandler |
外部中断的一般配置步骤
①使能SYSCFG时钟:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
②初始化IO口为输入。
GPIO_Init();
③设置IO口与中断线的映射关系。
void SYSCFG_EXTILineConfig();
④初始化线上中断,设置触发条件等。
EXTI_Init();
⑤配置中断分组(NVIC),并使能中断。
NVIC_Init();
⑥编写中断服务函数。
EXTIx_IRQHandler();
⑦清除中断标志位
EXTI_ClearITPendingBit();
独立看门狗
功能:在启动正常运行的时候,系统不能复位。在系统跑飞(程序异常执行)的情况,系统复位,程序重新执行。
独立看门狗(IWDG)由专用的低速时钟(LSI)驱动,即使主时钟发生故障它仍有效。
键寄存器
预分频寄存器IWDG_PR:0~2位有效。具有写保护功能,要操作先取消写保护
重装载寄存器IWDG_RLR:0~11位有效。具有写保护功能,要操作先取消写保护
image-20210504002306393
image-20210504002306393
预分频寄存器
image-20210504002357377
image-20210504002357377
重载寄存器
image-20210504002432525
image-20210504002432525
状态寄存器
image-20210504002451419
image-20210504002451419
独立看门狗超时时间
image-20210504002506848
image-20210504002506848
1 | 溢出时间计算: |
时钟频率LSI=32K, 一个看门狗时钟周期就是最短超时时间。最长超时时间= (IWDG_RLR寄存器最大值)X看门狗时钟周期
IWDG独立看门狗操作库函数
1 | void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess);//取消写保护:0x5555使能 |
独立看门狗操作步骤
① 取消寄存器写保护:
IWDG_WriteAccessCmd();
② 设置独立看门狗的预分频系数,确定时钟:
IWDG_SetPrescaler();
③ 设置看门狗重装载值,确定溢出时间:
IWDG_SetReload();
④ 使能看门狗
IWDG_Enable();
⑤ 应用程序喂狗:
IWDG_ReloadCounter();
窗口看门狗
窗口看门狗由从APB1时钟分频后得到时钟驱动。通过可配置的时间窗口来检测应用程序非正常的过迟或过早操作。
独立看门狗限制喂狗时间在0-x内,x由相关寄存器决定。喂狗的时间不能过晚。
image-20210504002906239
image-20210504002906239
2种情况之一时产生看门狗复位
①当喂狗的时候如果计数器的值大于某一设定数值W[6:0]时,此设定数值在WWDG_CFR寄存器定义。
② 当计数器的数值从0x40减到0x3F时【T6位跳变到0】。
如果启动了看门狗并且允许中断,当递减计数器等于0x40时产生早期唤醒中断(EWI),它可以用于喂狗以避免WWDG复位
窗口看门狗超时时间
image-20210504003037163
image-20210504003037163
image-20210504003042213
image-20210504003042213
image-20210504003048243
image-20210504003048243
控制寄存器WWDG_CR
image-20210504003143608
image-20210504003143608
1 | void WWDG_Enable(uint8_t Counter);//启动并设置初始值 |
配置寄存器WWDG_CFR
image-20210504003222479
image-20210504003222479
1 | void WWDG_EnableIT(void);//使能提前唤醒中断 |
状态寄存器WWDG_SR
image-20210504003250942
image-20210504003250942
1 | FlagStatus WWDG_GetFlagStatus(void); |
窗口看门狗的一般配置步骤
① 使能看门狗时钟:
RCC_APB1PeriphClockCmd();
② 设置分频系数:
WWDG_SetPrescaler();
③ 设置上窗口值:
WWDG_SetWindowValue();
④ 开启提前唤醒中断并分组(可选):
WWDG_EnableIT();
NVIC_Init();
⑤ 使能看门狗:
WWDG_Enable();
⑥ 喂狗:
WWDG_SetCounter();
⑦编写中断服务函数
WWDG_IRQHandler();
wwdg.c
1 | void WWDG_Init(u8 tr,u8 wr,u32 fprer) |
main.c
1 | int main(void) |
通用定时器
STM32F40x系列总共最多有14个定时器
image-20210504211715441
image-20210504211715441
4 个独立通道(TIMx_CH1~4),这些通道可以用来作为:
① 输入捕获
② 输出比较
③ PWM 生成(边缘或中间对齐模式)
④ 单脉冲模式输出
可使用外部信号(TIMx_ETR)控制定时器和定时器互连(可以用 1 个定时器控制另外一个定时器)的同步电路。
如下事件发生时产生中断/DMA(6个独立的IRQ/DMA请求生成器):
①更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发)
②触发事件(计数器启动、停止、初始化或者由内部/外部触发计数)
③输入捕获
④输出比较
⑤支持针对定位的增量(正交)编码器和霍尔传感器电路
触发输入作为外部时钟或者按周期的电流管理
计数器模式
通用定时器可以向上计数、向下计数、向上向下双向计数模式
image-20210504212028234
image-20210504212028234
内部时钟选择
image-20210504212300402
image-20210504212300402
计数器当前值寄存器CNT
image-20210504212422395
image-20210504212422395
TIMx->CNT 获取当前值
预分频寄存器TIMx_PSC
image-20210504212439222
image-20210504212439222
自动重装载寄存器(TIMx_ARR)
image-20210504212454628
image-20210504212454628
控制寄存器1(TIMx_CR1)
image-20210504212506320
image-20210504212506320
DMA中断使能寄存器(TIMx_DIER)
image-20210504212523100
image-20210504212523100
image-20210504212625091
image-20210504212625091
image-20210504212551406
image-20210504212551406
image-20210504212634593
image-20210504212634593
image-20210504212646983
image-20210504212646983
高级定时器做PWM注意事项
要加这句代码
1 | TIM_CtrlPWMOutputs(TIM8,ENABLE); //MOE 主输出使能 |
OLED
1 | //OLED的显存 |
ESP8266
AP模式:可以将ESP8266作为热点,可以让其他的设备连接上它;
STA模式:可以连接上当前环境下的WIFI热点。、
HC-05蓝牙模块
灯的状态
模块自带了一个状态指示灯:STA。该灯有3种状态
此时STA慢闪(1秒亮1次),模块进入AT状态
模块配对成功,此时STA双闪(一次闪2下,2秒闪一次)。
进入AT模式的两种方式
①上电同时/上电之前将KEY设置为VCC,上电后,模块即进入AT指令状态。
② 模块上电后,通过将KEY接VCC,使模块进入AT状态。
方法1进入AT状态后,模块的波特率为:38400(8位数据位,1位停止位)。方法2进入AT状态后,模块波特率和通信波特率一致
指令结构
1 | AT+<CMD><=PARAM> 设置参数格式 |
其中CMD(指令)和PARAM(参数)都是可选的,不过切记在发送末尾添加回车符(\r\n)(串口调试助手勾选发送新行就不用添加回车符),否则模块不响应,比如我们要查看模块的版本:
1 | 串口发送:AT+VERSION?\r\n |
修改模块主从指令
1 | AT+ROLE=0或1,该指令来设置模块为从机或主机 |
设置记忆指令
AT+CMODE=1,该指令设置模块可以对任意地址的蓝牙模块进行配对,模块默认设置为该参数。
AT+CMODE=0,该指令设置模块为指定地址配对,如果先设置模块为任意地址,然后配对,接下去使用该指令,则模块会记忆最后一次配对的地址,下次上电会一直搜索该地址的模块,直到搜索到为止。
修改通信波特率指令
1 | AT+UART= <Param1>,<Param2>,<Param3> |
该指令用于设置串口波特率、停止位、校验位等。
Param1为波特率,可选范围为:4800、9600、19200、38400、
57600、115200、230400、460800、921600、1382400;
Param2为停止位选择,0表示1位停止位,1表示2位停止位;
Param3为校验位选择,0表示没有校验位(None),1表示奇校验
(Odd),2表示偶校验(Even)。
比如我们发送:AT+UART=9600,0,0,则是设置通信波特率为9600,1位停止位,没有校验位,这也是我们模块的默认设置。
修改密码指令
1 | AT+PSWD=<password> |
该指令用于设置模块的配对密码,password必须为4个字节长度。
修改蓝牙模块名字
1 | AT+NAME=<name> |
该指令用于设置模块的名字,name为你要设置的名字,必须为ASCII字符,且最长不能超过32个字符。模块默认的名字为ATK-HC05。比如发送:AT+NAME=GUANG ZHOU,即可设置模块名字为“GUANG ZHOU”。
Usmart调试组件
Usmart文件说明
usmart.c负责与外部互交等。
usmat_str.c主要负责命令和参数解析。
usmart_config.c主要由用户添加需要由usmart管理的函数。
usmart.h和usmart_str.h是两个头文件,其中usmart.h里面含有几个用户配置宏定义,可以用来配置usmart的功能及总参数长度(直接和SRAM占用挂钩)、是否使能定时器扫描、是否使用读写函数等。
添加USMART包到工程,以及设置头文件路径
添加需要调用的函数添加到usmart_config.c文件中
主函数调用usmart_dev.init函数初始化Usmart
通过助手发送命令,调用再usmart中注册过的函数
1 | delay_init(168); |
这段函数写在main函数上面
1 | void light_led(void) //外部实现 |
1 | extern void light_led(void); //启用外部定义,就是上面那个函数,不用再led头文件里声明,因为这个已经算是声明了,就差实现了 |
USMART系统命令
?: 获取帮助信息
help: 获取帮助信息
list: 可用的函数列表
id: 可用函数的ID列表
hex: 参数16进制显示,后跟空格+数字即执行进制转换
dec: 参数10进制显示,后跟空格+数字即执行进制转换
runtime 1,开启函数运行计时;0,关闭函数运行计时;
请按照程序编写格式输入函数名及参数并以回车键结束.
RTC时钟
1 | if(RTC_ReadBackupRegister(RTC_BKP_DR0)!=0x5050) |
硬件随机数
1 | u8 RNG_Init(void); //RNG初始化 |
ADC模数转换
IIC
24c02
SPI
W25Qxx
#stm32