static从英文上翻译是静态的意思,在C语言中static所起的作用也正是静态。对于局部变量而言,其作用域是局部的如某一子函数体,程序在每次执行时调用该子函数时,其声明的局部变量都会重新赋值。那如果我们想让程序在调用该子函数时,其声明的某个局部变量的值,保留上次该子函数被调用结束时的值,那么就需要在变量声明时前置static。可以这么理解,对于静态的局部变量,其占用的内存空间在程序执行时是一直都存在的(静态的本质)。当然即使是静态局部变量,其作用域仅限于该子函数。
讲到这里,大家应该对上一节的全局变量还有印象,全局变量的作用域自变量声明开始至代码段结束,而且全局变量的值本身就是保留上次程序执行结束后的值。那么如果在全局变量声明时加上static,这个时候我们说静态全局变量具有本地属性,即该全局变量只在所处的源代码文件中有效,而不能被其他源文件的函数调用。这里简单提下,在这一阶段我们的代码量很少,全局变量用不到static属性,因为一个源文件就可以了。当然在实际项目中情况就不同了,一个完整的工程文件会包含若干个头文件和源文件,比如函数的声明和变量的声明放在头文件中,若干个功能实现的代码拆分成相应的源文件等。
好了现在开始讲讲单片机控制8段数码管的显示,数码管实物如图所示(图片所示位4位数码管,市场上的位数都可定制)。不管几位的数码管连接在一起,其显示的原理是一样的,靠内部的发光二极管点亮相应的段数,就能显示不同的数字。如图所示,a~g和dp小数点位构成了数码管的8段显示,对于共阴极数码管而言,要使得某一发光二极管比如a点亮,那么就需要a端高电平才有效;而对于共阳极数码管而言则刚好相反,a端低电平时a发光二极管才能点亮。
本节我们采用共阳极数码管作为讲解的对象,首先得解决一个问题那就是要显示的数字和字母的编码,运用proteus仿真软件搭建原理图,其中a~g以及dp依次对应单片机P0口的0~7位。
若要显示“0”,那么a~f要点亮,而g和小数点dp要熄灭,也就是说a~f端口低电平而g、dp端口高电平即显示数字0,此时单片机P0口的值为二进制1100 0000(十六进制0xC0),从上图的仿真结果也验证了这一点。
明白了编码的原理,结合原理图我们就可以列出数码管显示数字0~9以及英文字母A~F,对应的P0口电平状态即编码了,结果如下:
到这里我们可以正式开始写代码了,实现间隔1s数码管循环显示数字0~F以及英文字母A~F。
#include //包含头文件
#define uint unsigned int //宏定义,C语言预处理,下一节再讲
#define uchar unsigned char
void delayxms(uint xms); //函数声明,告诉编译器函数的参数类型和返回值
code uchar LED_CODE[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
0x80,0x90,0x88,0x83,0xA7,0xA1,0x86,0x8E};//C语言数组,索引从0开始
//code关键词的作用,使得该数组不占用内存空间,而是直接分配到程序空间中
void delayxms(uint xms) //延时函数
{
uint i,j = 0;
for(i=xms;i>0;i--) //通过for循环嵌套,实现xms延时
for(j=110;j>0;j--);
}
void main()
{
uchar i = 0; //局部变量
while(1)
{
for(i = 0; i
{
P0 = LED_CODE; //P0口的电平状态通过数组赋值
delayxms(1000); //延时1s
}
}
}