STM32F407基础总结系列(一)

一、前言

突然间想记录一下这些简单实用的东西,因为我发现曾经拥有的、奇妙的抑或是一些引以为豪、熟练的不能再熟练的东西终将会变成脑海中一种自我良好的感觉,当要提取出来用到的时候才发现你依旧是那个小白白,依旧要重新来过。技术时代,时间宝贵,方向远比努力重要,只有更优秀才能更优秀。
本章记录的都是一些超级简单,很基础却也是很有用的东西,旨在帮助那些和我一样曾经迷茫、陷入其中的人,当然有大佬批评指教一下最好。
刚开始记录因此东西杂乱无章,没关系,好的文章是要经过不断地不断地修改才能出来的。记录的东西不详尽没有固定时间,没关系,烂开头好过一动不动(其实是懒)。记录的东西很低级,没关系,都是从新手入门过来然后在来回之间反复横跳(哼,瞧不起谁)。

二、STM32F407部分基础小知识(待整理)

1 外设设置相关

1.1 GPIO使用

单片机入门第一步用寄存器点灯,点灯操作的寄存器代码如下:
以PF6低电平为例

	/*开启 GPIOF 时钟,使用外设时都要先开启它的时钟*/
	RCC_AHB1ENR |= (1<<5);		
	/*PF6 MODER6 = 01b 输出模式*/
	GPIOF_MODER |= (1<<2*6);	
	/*PF6 OTYPER6 = 0b 推挽模式*/
	GPIOF_OTYPER |= (0<<1*6);
	/*PF6 OSPEEDR6 = 11b 速率100MHz*/
	GPIOF_OSPEEDR |= (3<<2*6);
	/*PF6 PUPDR6 = 01b 上拉模式*/
	GPIOF_PUPDR |= (1<<2*6);	
	/*PF6 BSRR寄存器的 BR6置1,使引脚输出低电平*/
	GPIOF_BSRR |= (1<<16<<6);

过程就是 开外设时钟->配置模式寄存器(输入还是输出)->输出类型寄存器(若配置输出模式化此项需要)->输出速度寄存器(一般没要求就开最大)->上下拉寄存器(一般上拉为高电平,下拉为低电平)->置位复位寄存器(可直接操作引脚为高低电平)

1.2 定时器PWM波

配置流程

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;//TIM时钟配置结构体
TIM_OCInitTypeDef TIM_OCInitStructure;//TIM PWM配置结构体
GPIO_InitTypeDef GPIO_InitStructure; //GPIO配置结构体
// 开启定时器相关的GPIO 外设时钟*/
RCC_AHB1PeriphClockCmd (RCC_AHB1Periph_GPIOA,ENABLE);//GPIO时钟
RCC_APB1PeriphClockCmd (RCC_APB1Periph_TIM3,ENABLE);//TIM3定时器时钟
 /* 指定引脚复用功能*/
 GPIO_PinAFConfig(GPIOA,GPIO_PinSource6,GPIO_AF_TIM3);//功能复用,注意这里GPIO_PinSource6和GPIO_Pin_6不能混淆。这个函数和GPIO_Init()先后无所谓。
 /* 定时器功能引脚初始化*/
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;//GPIO_PuPd_NOPULL;//上拉下拉无所谓 都可以
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
 GPIO_Init(GPIOA, &GPIO_InitStructure);
/* ================== 时基结构体初始化=================== */
 // 累计TIM_Period+1 个计数后产生一个更新或者中断
 // 当定时器从0 计数到1023,即为1024 次,为一个定时周期
 TIM_TimeBaseStructure.TIM_Period = 1024-1;
 // 高级控制定时器时钟源TIMxCLK = HCLK=42MHz
 // 设定定时器频率为=TIMxCLK/(TIM_Prescaler+1)=100KHz
 TIM_TimeBaseStructure.TIM_Prescaler = 420-1;
 // 时钟分频,在计算死区时间的时候会用到
 TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
 // 计数方式
 TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
 // 重复计数器,这里没使用
 TIM_TimeBaseStructure.TIM_RepetitionCounter=0;
 // 初始化定时器TIMx, x[1,8]
 TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

 /* ================== 输出结构体初始化=================== */
 // 配置为PWM 模式1,先输出高电平,达到比较值的时候再改变电平
 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
 // 主输出使能
 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
 // 配置比较值
 TIM_OCInitStructure.TIM_Pulse = 0;
 // 主输出高电平有效
 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
 // 通道初始化	
TIM_OC1Init(TIM3, &TIM_OCInitStructure);
 // 使能通道重装载
 TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);
// 使能定时器
 TIM_Cmd(TIM3, ENABLE);
// 主动输出使能
// TIM_CtrlPWMOutputs(TIM3, ENABLE);

总体流程是 开GPIO、TIM时钟->配置GPIO参数(注意是否功能复用)->配置TIM定时器参数(主要是分频与计数-也就是输入时钟与计数周期)->TIM定时器PWM波配置(包括占空比、模式、高低电平及通道)->功能开启

1.3 外部晶振参数修改

不同板子可能晶振不同,需要修改的地方如下:

先修改stm32f4xx.h文件中的HSE_VALUE(外部高速时钟)
在这里插入图片描述
再修改system_stm32f4xx.c中的PLL_M(锁相环分频系数)
在这里插入图片描述
不改程序也能运行,点灯可以,但定时时序肯定是错乱的,比如定时1s可能快也可能慢。

2 语言及使用环境相关

2.1 C/C++

工程中添加头文件 出现了c/c++混编 需要修改编译文件方式
有时候会出现这种问题,很奇怪,明明添加了头文件并且按F12也能跳转到相应的函数中去,它就是报错跟你对着干,这种问题考虑一下可能要调用的头文件的问价类型设置问题(c/c++混编导致)
在这里插入图片描述
比如main.c文件类型设定为c++源文件,main中调用了bsp_led.h,bsp_led.h对应的源文件为bsp_led.c,其类型为c源文件,编译后就会造成上述错误。(都改为c++源文件类型就好了,后续免不了使用c++模块化思想)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.2 F407的启动文件

有时候我们会遇到移植了不同F4芯片的工程,启动文件不一样,这时候就会尴尬要不要更换启动文件。实测不用更换,只需要修改魔术棒中的宏定义即可
在这里插入图片描述
在这里插入图片描述
问题不大,修改魔术棒选项中C/C++里的Define就好了,如下使用了429的启动文件,使用的时候定义407的宏定义就好了
在这里插入图片描述

3 测试验证相关

3.1 PWM配置IO引脚

配置PWM波IO引脚设置上拉或下拉或者不拉没啥影响,波形照样输出 (可能波形初次电平不一样吧)

3.2 通用IO引脚

实测引脚复用后,使用引脚置位复位函数无效//GPIO_SetBits()|GPIO_ResetBits(),功能复用相当于一个开关只能单项操作。
在这里插入图片描述
看一些教程上说GPIO上下拉模式设置上拉或下拉默认电平不一样,实测这一段代码执行后IO引脚仍处于没有电平的状态(非0v,非3.3v),最好有需求的话后边手动设置一个置位或复位就好啦
在这里插入图片描述

4 故障排查相关

4.1 可靠调试技巧

一些重要的调试技巧,确保硬件电路是没问题的,我曾经调试一个程序花了几个小时,从顶层逻辑排查到底层IO配置,最终发现是核心板外部电路有问题。准备多块板子对比验证也可。
当问题很久没有排查出来时最好把所有的可能问题列出记录下来一个一个尝试,思路要清晰一点,由大到小,由简到难,
通信端口可以放两个LED用于指示通信,一些工业级的通信模块都是带双向收发指示灯的,这个很棒,出现问题可以看指示灯从而将问题快速定位在外部还是内部。

三、小结尾

前边说的很虚,其实就是最近帮朋友看一个定时器输出PWM的基础问题,我找了半天没给人家解决,不仅啪啪打脸而且引发了一系列调试问题把我陷进去了【泪流满面】,最终我发现我连一个灯都点不起来,沮丧的亚批(可以想象一下一个单片机程序员半夜坐在那里在台灯的照射下对着电脑发呆)。星光不问赶路人,好在最后发现了问题(嘿嘿)。
要多开源记录一些东西帮自己的同时也是帮别人。

四、参考文献

猜你喜欢

转载自blog.csdn.net/weixin_43058521/article/details/119481542