stm32常用的c语言函数
1.define宏定义:
(1)格式:
#define标识符字符串
(2)说明:
标识符:定义的宏名
字符串:可以是常数、表达式、格式串等
(3)举例:
#defineSYSCLK_FREQ_72MHz 72000000
定义标识符SYSCLK_FREQ_72MHz的值为72000000。在之后的程序中,SYSCLK_FREQ_72MHz就代表了72000000这个数
2.ifdef条件编译
(1)格式:
#ifdef标识符
程序段1
#else
程序段2
#endif
(2)说明:
若对标识符定义过,那么执行程序段1,否则执行程序段2。
在实际应用中我们可以省略else项,也可以对这个函数进行处理,比较常用的是:
#ifndef xxx
#definexxx
程序段
#endif
这个方式可以用在.h文件的编写中,避免重复定义。
(3)举例:
#ifndef __LED_H//如果未定义led.h
#define __LED_H//那么定义led.h
void LED_Init(void); //执行LED_Init函数(这里这个函数为空)
#endif //结束
3.extern变量声明
这里注意区别变量的声明和定义,这是两个概念,变量的声明可以有很多次,但变量的定义就只有一次
(1)格式:
externxxxxxx
(2)说明:
由于变量只能够被定义一次,那么,如果我在一个文件中定义了这个,然而我在另一个文件中也要用到这个变量,注意这里是单独用这个变量,而不是说我可以通过调用函数的方式来处理这个东西,就比如说定义的某个标识,我需要在许多地方对这个标识进行判断,此时就需要用到这个函数了。
当我们在程序中看到了这样的语句:
externintflag;
那么我们在这个工程的其他文件中一定会找到这样一句话:
intflag;
后面这句话就是对变量的定义,而前面这句话就是对变量的声明。
(3)举例:(此处理解不深刻,先放一个不完全手册上面的例子)
在main.c中定义一个一个全局变量id,id的初始化都是在main中进行的。
在main.c中存在:
u8 id;
main()
{
id=1;
printf("d%",id);//输出id的值(id=1)
test(); //调用test函数
printf("d%",id);//输出id被改变之后的值(由下文可知此时id=2)
}
可以看出我们调用了test,假设我们要在这个test里面使用id这个变量,那么:
在test.c中存在:
externu8id; //此处声明id这个变量已经在别处定义过了,在这里我要用到
void test(void)
{
id=2;
}
4.typedef类型别名
(1)格式:
typedef xxxxxx;
(2)说明:
typedef 用于为现有类型创建一个新的名字,或称为类型别名,用来简化变量的定义。 typedef 在 MDK用得最多的就是定义结构体的类型别名和枚举类型。这个函数非常常见,但我们编程的时候似乎用的比较少,stm自带的函数库倒是用来很多,在gotodefinition的时候经常会看到这样定义的东西。
(3)举例:
举一个定义枚举类型的例子,在GPIO端口初始化的时候遇到的函数
typedef enum
{
GPIO_Speed_10MHz = 1,
GPIO_Speed_2MHz,
GPIO_Speed_50MHz
}GPIOSpeed_TypeDef;
#define IS_GPIO_SPEED(SPEED) (((SPEED) == GPIO_Speed_10MHz) ||((SPEED) == GPIO_Speed_2MHz) ||
((SPEED) == GPIO_Speed_50MHz))
这里设置了端口速度的类型,在之后的调用中我们只需要直接说端口速度是GPIOSpeed_TypeDef类型就可以了,而不需要说它是一个包括三个成员的枚举类型的东西。
5.结构体(结构)
(1)格式:
结构体的声明格式1:
Struct 结构体名
{
成员列表;
}变量名列表;
格式2:
Struct结构体名;
结构体变量列表 ;
(2)说明:
第一种方式常在库函数里面见到,第二种方式在我的编程中常用
结构使得我们在任何时候,只需要修改结构体成员变量,往结构体中间加入新的成员变量,而不需要修改函数定义就可以达到修改入口参数同样的目的了。这样的好处是不用修改任何函数定义就可以达到增加变量的目的。
(3)举例:
举一个定义一个结构的例子,这是一个在GPIO端口初始化的时候遇到的函数
声明方式1:
typedef struct
{
uint16_tGPIO_Pin;
GPIOSpeed_TypeDef GPIO_Speed;
GPIOMode_TypeDefGPIO_Mode;
}GPIO_InitTypeDef;
//定义一个名为GPIO_InitTypeDef的结构,其中包括三个成员:GPIO_Pin,GPIO_Speed和GPIO_Mode,之后我们想要对这三个成员组成的结构体进行操作的时候就直接操作GPIO_InitTypeDef就可以了。
不声明结构成员:
GPIO_InitTypeDefGPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin= GPIO_Pin_8;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
//定义一个名为GPIO_InitStructure的结构,它的类型为GPIO_InitTypeDef,之后为其中的三个成员赋值。
(4)附加:
结构体的引用方式:
结构名.成员
结构名->结构成员
区别:关于.和->的用法,有这样一个规律:点.要求左边的这个结构必须为实体,箭头->要求左边的这个结构必须为指针。