单片机编程的几种新用法
2010-09-14 16:03:29| 分类: 默认分类 | 标签: |字号大中小 订阅
一、头文件包含巧妙用法
当一个头文件被多个C文件包含,且该头文件中定义了这些C文件的公共变量,则在编译的时候会出现重复定义,导致编译通不过,通常我们会采用如下两种做法来解决上述问题。
(为了让问题表述得更清楚,我们假设两个C文件C1,C2,C3,一个头文件H1,C1,C2,C3有两个公共变量V1和V2)
1、
2、
很显然,以上两种方法都要对V1和V2书写至少两次,一次定义,一次外部声明,且不是在同一文件下,这样不利于管理和修改,有没有一种方法可以让这些公用的变量放在一个文件里,且只要书写一次呢?
首先我们将要用到的公共变量全部书写到com.h文件中,每一个变量在定义前加一个符号EXT_,当该头文件被main.c函数包含时,定义EXT_为空,表示com.h中的变量在main.c中被定义,当被其它文件包含时,定义EXT_为extern,表示外部声明,如:
Com.h文件:
//避免重复定义
#ifdef
#else
#endif
//全局变量
EXT_ u8
Main.c
#define root
#include "com.h"
二、用 结构体 的方式来定义总线或外设地址
当一个整体包含不同类型的多个成员时,通常用结构体来定义结构体变量,这样内存会将这些变量按照递增的方式分配到相邻的地址(不对齐的地方会有填充),按“结构体名.成员名”的方式访问结构体内的成员,这是访问结构体变量的方式;但是还有一种指向结构体变量的指针,它可以将某个地址转换成该结构体类型的指针,比如寄存器的定义:
(以下是摘自 STM32固件函数库,关于GPIO的定义)
typedef struct
{
} GPIO_TypeDef;
#define GPIOA_BASE
#define GPIOA
这样在操作GPIOA的寄存器时只要这样写就可以了
读: X="GPIOA-">CRL;
或
当然,要达到上述目的也可以采用如下方式
#define GPIOA_ CRL
#define GPIOA_ CRH
#define GPIOA_ IDR
#define GPIOA_ ODR
#define GPIOA_ BSSR
#define GPIOA_ LCKR
很明显,第一种书写方式更加正规化,且当定义多个GPIO时,只要将其它GPIO的基地址强制转换为该结构类型的指针即可。
再来看看一个定义外部总线的例子
typedef struct
{
} CH375_TypeDef;
CH375-> CH375_DATA=data;
CH375-> CH375_CMD=cmd;
怎么样,是不是方便多了。重要的是代码的观赏和可读性提高了。
三、 用枚举数据类型来定义特定的状态
如:用宏定义:
#define Sucess
#define Failure
#define Busy
用枚举
typedef enum { Sucess = 0, Failure , Busy } FlagStatus;
四、用共用体类型定义共享内存空间
共用体类型定义的数据是将多个成员共享同一内存空间,该空间的大小为最大成员的大小,其用法与结构体完全相同,但值得注意的是不能同时引用多个成员,在某一时刻只能使用其中之一成员。
在程序中如果全局变量比较多,包含几个结构和数组,如果这些全部定义的话势必会占大量的内存,有可能还会导致单片机内存不够,如果能让几个不同时用到的数组和结构变量共享一段内存,则能省出很多的内存空间。
比如以下输入输出若不同时进行,则可以共享同一段内存空间
union {
unsigned char
unsigned char