举个例子吧,断码管用过吧?它的解法有两种:共阴极和共阳极。断码管有abcdefg七个端子接入,一般我们会按顺序abcdef对应单片机某一端口的从低位到高位接。但你想过没有,若是正好把高低位顺序完全接反了怎么办(不要说不可能,我可碰到过)?再加上又可以共阴极和共阳极两种选择。是否可以把这四种情况都统一到一起形成一个.h头文件供日后随意使用呢?
这其实应该是程序员的直觉,一种天生的惰性,把经常用到的东西一次性做好,供日后使用。
我是这么实现的,参见以下代码:[code=C/C++][/code]
#ifndef _LED_NUM_H_
#define _LED_NUM_H_
#include "const.h"
typedef enum tagLEDNUM
{
LED_0,
LED_1,
LED_2,
LED_3,
LED_4,
LED_5,
LED_6,
LED_7,
LED_8,
LED_9,
/* LED_A,
LED_B,
LED_C,
LED_D,
LED_E,
LED_F,*/
LED_MINUS,
LED_ALL_OFF,
LED_ALL_ON,
LED_TABLE_SIZE
}LEDNUM;
#if defined COMMON_CATHODE //共阴极
#ifdef COMMON_CODE
//"-"号
code BYTE g_LEDNumTable[LED_TABLE_SIZE] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x80, 0x00, 0xff}; //最后两个字节为关和开
#elif defined REVERSE_CODE //反序字节
code BYTE g_LEDNumTable[LED_TABLE_SIZE] = {0xfc, 0x60, 0xda, 0xf2, 0x66, 0xb6, 0xae, 0xe0, 0xfe, 0xf6, 0x01, 0x00, 0xff};
#else
#error must indicate COMMON_CODE or REVERSE_CODE identifier
#endif
#elif defined COMMON_ANTICATHODE //共阳极
#ifdef COMMON_CODE
//"-"号
code BYTE g_LEDNumTable[LED_TABLE_SIZE] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0x7f, 0xff, 0x00}; //最后两个字节为关和开
#elif defined REVERSE_CODE //反序字节
code BYTE g_LEDNumTable[LED_TABLE_SIZE] = {0x03, 0x9f, 0x25, 0x0d, 0x99, 0x49, 0x41, 0x1f, 0x01, 0x09, 0xfe, 0xff, 0x00};
#else
#error must indicate COMMON_CODE or REVERSE_CODE identifier
#endif
#else
#error must indicate COMMON_CATHODE or COMMON_ANTICATHODE identifier
#endif
#define GET_LED_CODE(num) (g_LEDNumTable[num])
#endif
这样,以后使用的时候定义一下 COMMON_CATHODE 或COMMON_ANTICATHODE,REVERSE_CODE或COMMON_CODE 标识符就行了,这四个标识符完成了那四种的可能组合。定义过之后,直接用GET_LED_CODE()这个宏就可以取得数字所对应的断码了。比如你想在P0口输出4,那么直接P0 = GET_LED_CODE(4)就可以了,就这么简单。
写成这样一个头文件有如下的好处:
1、达到了代码复用,只要用到段码管就可以直接用这个头文件了,不用每次都重写一遍
2、将运行期获得的参数转化到了编译期来完成,提高了运行速度,当然会占用一些rom
这个头文件里用到了一些可能不太多见的预编译宏,这可是c语言的一大特点,需要多熟悉一下,如果掌握了会大大提高功力。 |