从单片机基础到程序框架(全集 2019pdf版).pdf - 第347页
unsigned c har u8Sign; // 符号 0 为正数 1 为负数 unsigned l ong u32D ata; //数值 }; struct S tructSignD ata GtNum ber; //Gt 代表 全局的结构体 变量。 void H anShu(struct Struc tSignData *p tData) // pt 代表 局部的 结构体指针 { struct Struc tSignData t …

unsigned int Gu16NumberBuffer[5]; //后缀是 Buffer。16 位的全局变量数组。用在普通数组。
unsigned char Gu8NumberString[5]; //后缀是 String。8 位的全局变量数组。用在字符串。
//根据原理图得出的共阴数码管字模表
code unsigned char Cu8DigTable[]=//后缀是 Table。这里的 code 是代表 C51 的常量(类似 const)。
{
0x3f, //0 序号 0
0x06, //1 序号 1
0x5b, //2 序号 2
0x4f, //3 序号 3
0x66, //4 序号 4
0x6d, //5 序号 5
0x7d, //6 序号 6
0x07, //7 序号 7
0x7f, //8 序号 8
0x6f, //9 序号 9
0x00, //不显示 序号 10
};
void HanShu(unsigned char u8Data) //u8 就代表局部的 8 位变量
{
unsigned char u8NumberMessage[5]; //后缀是 Message。8 位的局部变量数组。用在信息。
}
【79.5 指针的命名规范和习惯。】
指针的前缀加“p”来区分。再往下细分,指针有全局和局部,有“静态”和“非静态”,有“8 位宽度”
和“16 位宽度”和“32 位宽度”,有变量指针和常量指针。比如:
unsigned char *pGu8NumberString; //pGu8 代表全局的 8 位变量指针
void HanShu(const unsigned char *pCu8Data) //pCu8 代表局部的 8 位常量指针
{
unsigned char *pu8NumberBuffer; //pu8 代表局部的 8 位变量指针
static unsigned int *pSu16NumberBuffer; //pSu16 代表局部的 16 位静态变量指针
static unsigned long *pSu32NumberBuffer; //pSu32 代表局部的 32 位静态变量指针
}
【79.6 结构体的命名规范和习惯。】
结构体的前缀加“t”来区分。再往下细分,指针有全局和局部,有“静态”和“非静态”,有结构体变
量和结构体指针。比如:
struct StructSignData //带符号的数
{

unsigned char u8Sign; //符号 0 为正数 1 为负数
unsigned long u32Data; //数值
};
struct StructSignData GtNumber; //Gt 代表全局的结构体变量。
void HanShu(struct StructSignData *ptData) //pt 代表局部的结构体指针
{
struct StructSignData tNumber; //t 代表局部的结构体变量。
static struct StructSignData StNumber; //St 代表局部的静态结构体变量。
}
【79.7 宏常量的命名规范和习惯。】
所谓“宏常量”往往是指用#define 语句定义的常量。宏常量的所有字符都用大写字母。比如:
#define DELAY_TIME 30 //宏常量所有字符都用大写字母。DELAY_TIME 代表延时的时间。
void HanShu(void)
{
delay(DELAY_TIME); //相当于 delay(30),这里的 delay 代表某个延时函数(这里没有具体写出来)
}
【79.8 首字符用大写字母以及下划线“_”的灵活运用。】
两个以上的英文单词连在一起命名时,每个单词的首字符用大写,其余用小写,这样可以把每个单词“断
句”开来,方便阅读。如果遇到两个英文单词连在一起不好“断句”的情况(比如某个英文单词全部是大写
字母的专用名词),只要在两个英文单词之间插入下划线“_”就可以清晰的“断句”了。比如:
unsigned long Gu32GetFileLength; //GetFileLength 寓意“获取某个文件的长度”。
unsigned char Gu8ESD_Flag; //ESD 是专业用名词,代表“静电释放”的意思。用下划线“_”断句。

第八十节: 单片机 IO 口驱动 LED。
【80.1 不再依赖第 11 节模板程序。】
前面大量的章节主要是讲 C 语言本身的基础知识,因此每次的练习例程都要依赖第 11 节的模板程序。
从本节开始,正式进入到单片机主题,如果没有特殊说明,以后的练习程序就不再需要依赖第 11 节模板程
序,可以脱离模板单飞了。
【80.2 寄存器。】
寄存器是跨越在软件与硬件之间的桥梁,单片机的 C 语言想控制单片机引脚输出 0V 或者 5V 的物理电压,
本质就是通过往寄存器里填数字,往哪个寄存器填数字,填什么样的数字,对应的引脚就输出什么样的电压。
至于“为什么往寄存器填数字就会在引脚上输出对应的电压”这个问题,对于我们“应用级”工程师来说是
一个黑匣子。我们写软件的最底层就是操作到“寄存器”这个层面,至于“寄存器与物理电压之间是如何关
联如何实现”的这个问题,其实是“芯片级”半导体工程师所研究的事,因为单片机本身其实就是一个成品,
我们从“芯片级”半导体工程师那里拿到这个成品,这个成品的说明书告诉了我们该成品的每个寄存器的作
用,我们只能在这个基础上去做更上层的应用。该说明书其实就是大家通常所说的芯片的 datasheet。
寄存器在单片机 C 语言层面,是一个全局变量,是一个具备特定名字的全局变量,是一个被系统征用的
全局变量。寄存器的名字就像古代皇帝的名字,所有普通老百姓的变量名字都要“避尊者讳”,不能跟寄存
器的名字重名,否则 C 编译器就编译不通过。
图 80.2.1 单片机的 32 个 IO 口引脚
本教程用的 STC89C52 单片机 IO 口寄存器有 4 个,分别是 P0,P1,P2,P3 这 4 个寄存器,每个寄存器都是
一个 8 位的全局变量,每一位代表控制一个单片机的 IO 口引脚,因此,该单片机一共有 32 个(4 乘以 8)
IO 口引脚,每个引脚都是可以单独控制的(俗称位操作)。往该位填入 0,对应的引脚就输出 0V 的物理电压。