1.static用于函数前
将static关键字用于函数前,那么这个函数称为静态函数,该函数将只能在当前.c文件中使用,属于内部函数,在其他.c文件中无法调用该函数。如此可以使程序可读性、可移植性更强。
如下,新建了一个hal_led.c文件,在这个文件中,LED等外部设备的GPIO初始化函数仅hal_led.c这个文件中调用,不会在外部文件调用,所以在函数hal_ledConfig(void)前添加static使其仅在内部调用。在这个文件中,将所有要初始化的函数或变量将在函数hal_led_Init()中实现,如此一来,main函数中,代码将更加简洁明了,增强了代码的可读性。
#include "hal_led.h"
#include "stm32f10x.h"
static void hal_ledConfig(void);
void hal_led_Init(void) //所有初始化函数或变量
{
hal_ledConfig();
//可添加其他需要初始化的函数或者变量
}
static void hal_ledConfig(void) //GPIO初始化函数
{
GPIO_InitTypeDef GPIO_InitStructure;
//时钟使能
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA , ENABLE);
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB , ENABLE);
//配置GPIO口 PA1 LED
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出,输出电流大,驱动能力强
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_ResetBits(GPIOA,GPIO_Pin_1);
//PB0 BEEP
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; ;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_ResetBits(GPIOB,GPIO_Pin_0);
}
主函数如下:
#include "hal_led.h"
int main(void)
{
hal_led_Init();
while(1)
{
}
}
2.static用于变量前(此处主要说明局部变量)
static修饰局部变量时,该变量称为静态局部变量。在函数中声明变量时,static关键字指定的变量只初始化一次,在之后调用该函数中,该变量保持上一次的状态。
举例说明,如下函数:
//LED闪烁1s任务调度函数
void hal_ledProc(void)
{
static int i = 0; //计数值
i++;
if(i > 50) //500ms
{
i = 0;
led_control_turn(); //LED翻转函数
}
}
函数功能:实现LED每秒闪烁1次。
功能实现分析:这个函数在整个工程中,每隔10ms执行1次,那么要实现LED每秒闪烁1次,只需要设置一个计数值,记下这个函数运行的次数,当这个函数运行50次后,即计数值到50次时,让LED的状态翻转便实现了LED每秒翻转1次。
对于这个计数值有两种实现方式,一种是定义一个全局变量,初始化为0,每进入函数一次计数值加1,计数值满后将其清0;另一种是在函数中定义一个静态局部变量(static修饰),每进入函数一次计数值加1,计数值满计数值清0。
这两种方式有什么区别呢?
第一种方式虽然可以实现功能,但如果在一个大工程中,这样会使得代码冗长复杂、可读性差、可移植性差。
第二种方式将使得代码简约明了、可读性强、可移植性强。前面贴出来的代码就是第二种。
在上面代码中,i只在第一次进入该函数时初始化,之后再进入该函数,static int i = 0;该语句将不会再被执行,i的值将是上一次函数结束时的值。