单片机开发-随记
单片机程序为何有很多typedef
- 单片机操作寄存器时,对数据长度有明确要求。然而,cpu位数和编译器位数会导致变量长度不同,为了得到确切字长的变量类型,通常会使用typedef定义出定长变量类型。
c99中引入了stdint作为标准库头文件,linux下也有sys/type。可以使用标准库的指定字长类型,减少typedef定义
typedef unsigned int u16;
此外,也是方便移植。将程序从16位cpu(int长度为16bit)移植到32位cpu时,只需要直接改typedef定义可以让代码快速移植。
- 增强程序可读性,表面变量的硬件含义
typedef uint8_t GPIO_PIN; //明确表示“GPIO引脚编号”
typedef uint32_t SensorValue;//明确表示“传感器数值”
Doxygen注释规范
在STM32标准库以及我们自己编写的头文件中,可以看到一些比较特别的注释,类似
/**
* @brief 初始化控制LED的IO
* @param 无
* @retval 无
*/
这是一种名为“Doxygen”的注释规范,如果在工程文件中按照这种规范去注释,可以使用Doxygen软件自动根据注释生成帮助文档。 我们所说非常重要的库帮助文档《stm32f4xx_dsp_stdperiph_lib_um.chm》,就是由该软件根据库文件的注释生成的。 关于Doxygen注释规范本教程不作讲解,感兴趣的读者可自行搜索网络上的资料学习。
当编译时提示这样的错误时,是因为框出来的变量被重复定义了,我们要从定义的地方解决。
防止头文件重复包含
在STM32标准库的所有头文件以及我们自己编写的头文件中,可看到类似的宏定义:
#ifndef __LED_H
#define __LED_H
/*此处省略头文件的具体内容*/
#endif /* end of __LED_H */
它的功能是防止头文件被重复包含,避免引起编译错误。
在头文件的开头,使用“#ifndef”关键字,判断标号__LED_H
是否被定义,若没有被定义,则从“#ifndef”至“#endif”关键字之间的内容都有效, 也就是说,这个头文件若被其它文件“#include”,它就会被包含到其该文件中了,且头文件中紧接着使用“#define”关键字定义上面判断的标号__LED_H
。 当这个头文件被同一个文件第二次“#include”包含的时候,由于有了第一次包含中的#define __LED_H
定义,这时再判断#ifndef__LED_H
, 判断的结果就是假了,从“#ifndef”至“#endif”之间的内容都无效,从而防止了同一个头文件被包含多次,编译时就不会出现“redefine(重复定义)”的错误了。
一般来说,我们不会直接在C的源文件写两个“#include”来包含同一个头文件,但可能因为头文件内部的包含导致重复,这种代码主要是避免这样的问题。
至于为什么要用两个下划线来定义__LED_H
标号,其实这只是防止它与其它普通宏定义重复了,如我们用“GPIO_PIN_0”来代替这个判断标号, 就会因为stm32f4xx.h已经定义了GPIO_PIN_0,结果导致文件无效了从而一次都没被包含。
全局变量不要在.h里定义
如果全局变量在.h文件里定义,当这个头文件被多个文件include时,所有引用这个.h的.c中都会重复定义变量。
当只剩一个地方定义后,在其他文件中使用可以通过extern声明来使用这个变量
关于STM32 IAP升级之为什么APP执行要&0x2FFE0000这个数值的原因
https://zhuanlan.zhihu.com/p/105109753
程序在运行过程中,0x20000000是SRAM运行的起始地址(查产品使用说明里的地址映射) 如果SRAM空间是128KB,也就是0x20000000-0X2001FFFF这个范围;图片的MCU的SRAM是(16+8)KB的,所以规格书给的地址范围是0x20000000-0X20007FFF(足够代表32KB)。
JumpAddress = *(volatile uint32_t *)FLASH_APP_ADDR;
这句话的意思是取得APP程序的地址空间存放的数据,这个空间就是0x08060000
if ((JumpAddress & 0x2FFE0000) == 0x20000000)
0x2FFE0000是根据MCU实际的SRAM大小决定的。 当APP运行的程序栈顶指针落在SRAM区域时,也就是0x20000000到0X2001FFFF这个区间时候,这个时候即是有效的栈顶指针,由于开始的地址是0x20000000,而结束的地址是0X2001FFFF,我们只要判断它的高16位,即是确定这个地址范围在从0x2000开始。
stm32 在使用keil5仿真调试程序时,忘记关机看门狗
在调试程序的时候,拉高了供电使能管脚,理论上应该保持3.3V高电平的,但是使用示波器/万用表量的时候,发现有波动(保持高电平一段时间后,迅速变为低电平,然后又继续保持高电平),排查了管脚复用后问题任然存在。
最后发现,是调试的时候,程序使能了看门狗,4秒没有喂狗,所以4秒就复位一次,从而产生管脚波动的现象。
如何测引脚的高低电平
将万用表调到电压档,量程选稍大的如20V。
红表笔接要测量的引脚,黑表笔接地。
引脚是低电平,一般在0V左右