1.Typedef
typedef用于为现有类型创建一个新的名字,或称为类型别名,用来简化变量的定义。typedef在MDK用得最多的就是定义结构体的类型别名和枚举类型了。
如:typedef struct
{
u16 seq_num;
u16 len;
u8 dev_id[GPRS_PRO_DEVICE_ID];
u16 command_id;
u8 *pro_data;
}gprs_pro_cmd_t;
然后我们就可以直接使用gprs_pro_cmd_t定义一个结构体变量。
2.结构体
① 一般形式:Struct 结构体名 { 成员列表; }变量名列表;
② 这样是声明后直接定义,也可以先声明,后定义;
如:
Struct 结构体名字 { 成员列表; };
例如:struct U_TYPE usart1,usart2;
注意:结构体指针成员变量引用方法是通过“->”符号实现;
运用:在我们定义函数的形参时,形参数量较多的情况下,一旦修改就会很麻烦。因此将形参使用结构体进行统一定义,进行组合。
typedef struct{
uint32_t USART_BaudRate;
uint16_t USART_WordLength;
uint16_t USART_StopBits;
uint16_t USART_Parity;
uint16_t USART_Mode;
uint16_t USART_HardwareFlowControl;}USART_InitTypeDef;
于是,我们在初始化串口的时候入口参数就可以是USART_InitTypeDef类型的变量或者指针变量了,MDK中是这样做的:
void USART_Init(USART_TypeDef*USART_InitTypeDef*USART_InitStruct);
这样,任何时候,我们只需要修改结构体成员变量,往结构体中间加入新的成员变量,而不需要修改函数定义就可以达到修改入口参数同样的目的了。
3.宏定义
宏定义是一种预处理命令,便于代码可读性
在C语言的宏定义中,偶尔会碰到#和##符号的使用,如下
#ifndef MKSTR
#define MKSTR(x) #x
#endif
#define CAR_SECTION __attribute__((used,section("car")))
#define CAR(__name,__owner,__price)
static car car##__name CAR_SECTION = {
.name= MKSTR(__name),
.owner = MKSTR(__owner),
.price = __price,
}
#endif
1、#:表示将宏定义中的参数转换成字符串
例如上面的MKSTR(__name),展开后是#__name, 是将宏参数转换成字符串。这样就可以赋值给.name这个成员变量了。
2、##:表示连接,即将前后书写的字符连接起来。
例如上面的car##__name, 当宏参数宏参数__name为 Elec时,展开的该部分就是 carElec.
##就像个粘合剂,将前后两部分粘合起来。但是“##”不能随意粘合任意字符,必须是合法的C语言标示符。
4.条件编译
条件编译是一种宏定义,故有#,它的目的就是防止函数二次定义
最常用的方式就是
#ifndefine //如果未定义此函数
#define //则定义它
续行符
语法:“”
表示续行符的下一行与续行符所在的代码是连接起来
应用续行符的时候要注意,在“”后面不能有任何字符(包括注释、空格),只能直接回车
实际应用场景:
1、固件库里面有一个很重要的头文件,叫stm32f10x.h,这个头文件实现了外设寄存器的映射,相当于51单片机中的reg51.h
2、这个头文件会被很多文件包含调用,那就意味着stm32f10x.h的头文件会被多次包含,文件里面的那些寄存器结构体声明就会出现重复声明的错误
3、那为了防止头文件被重复包含时出现函数或者变量重复定义的情况,我们可以通过条件编译来解决
#ifndef __STM32F10X_H
#define __STM32F10X_H
// stm32f10x.h 头文件的真正内容
#endif /* __STM32F10X_H */
比如,stm32f10x.h被stm32f10x_gpio.h和stm32f10x_usart.h这两个固件库的头文件包含了,那么首次编译的时候就会判断是否定义了__STM32F10X_H,那第一次肯定是没有定义的,那紧接着就定义__STM32F10X_H,
当编译到第二个头文件也包含了stm32f10x.h时,因为__STM32F10X_H 已经被定义过,stm32f10x.h的内容就不会再编译一次。
因此,不管是固件库头文件还是我们自己用户编写头文件的时候,为了养成好的习惯,都必须在头文件上加上条件编译。
上一篇:STM32学习第三课:STM32 c语言学习基础3(内存操作、指针、结构指针)
下一篇:STM32学习第一课:STM32 编程的C语言基础
推荐阅读最新更新时间:2024-11-05 23:06
设计资源 培训 开发板 精华推荐
- 使用 Analog Devices 的 LTC1771ES8 的参考设计
- USB二口主机应用MIC2026A-2YM双通道配电开关典型应用
- 使用 ON Semiconductor 的 LA5620 的参考设计
- 使用 Infineon Technologies AG 的 IRU3073 的参考设计
- 使用 LT3710 的推挽式转换器
- LDK120C18R 1.8V低压降稳压器典型应用固定电路
- AD7983、16 位、1.33MSPS PulSAR ADC 的典型应用
- LMV358DR2G 运算放大器电压基准的典型应用电路
- opendoor-fingerprint
- LT1634BIS8-1.25 超准确 ±4.096V 输出电压基准的典型应用