您的位置:首页 > 其它

像写Windows程序那样写单片机程序之基础配置

2009-06-08 10:32 232 查看
作者:jiqiang
QQ:25757032
Email:jiqiang0123@gmail.com

为什么非得要“像Windows程序”那样,而不是Linux或是其他程序那样?原因很简单,因为本人不会~_~。其实,重要的不是像哪种平台下的程序,而是程序的结构方式、屏蔽底层硬件实现等与平台无关的东西。
本系列文章探讨的主题都是在Keil uVision3集成编译环境下完成的,针对的是51系列单片机。
下面就介绍一下在我的单片机程序里必须要包含的一个头文件----"const.h",完整内容如下:
#ifndef _CONST_H_
#define _CONST_H_
#include <intrins.h>

#define TRUE 1
#define FALSE 0

typedef unsigned char BYTE;
typedef unsigned int WORD;
typedef unsigned long DWORD;
typedef float FLOAT;
typedef char CHAR;
typedef unsigned char UCHAR;
typedef int INT;
typedef unsigned int UINT;
typedef unsigned long ULONG;
typedef UINT WPARAM;
typedef ULONG LPARAM;
typedef ULONG LRESULT;
typedef void VOID;
typedef const CONST;
typedef void *PVOID;
typedef bit BOOL;

#define MAKEWORD(lo, hi) ((WORD)(((BYTE)(lo)) | ((WORD)((BYTE)(hi))) << 8))
#define MAKEDWORD(lo, hi) ((DWORD)(((WORD)(lo)) | ((DWORD)((WORD)(hi))) << 16))
#define LOWORD(dw) ((WORD)(dw)
#define HIWORD(dw) ((WORD)(((DWORD)(dw) >> 16) & 0xFFFF))
#define LOBYTE(w) ((BYTE)(w))
#define HIBYTE(w) ((BYTE)(((WORD)(w) >> 8) & 0xFF))
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#define MIN(a, b) (((a) < (b)) ? (a) : (b))

#define SET_STATE_FLAG(state, mask) ((state) |= (mask))
#define RESET_STATE_FLAG(state, mask) ((state) &= ~(mask))
#define TEST_STATE_FLAG(state, mask) ((state) & (mask))

//偏移量从0开始
#define TEST_BIT(b, offset) (1 & ((b) >> (offset)))
#define SET_BIT(b, offset) ((b) |= (1 << (offset)))
#define RESET_BIT(b, offset) ((b) &= (~(1 << (offset))))

//将BCD码变为十进制,如将0x23变为23
//注意:高四位和低四位均不能大于9
#define BCD_TO_DECIMAL(bcd) ((BYTE)((((BYTE)(bcd)) >> 4) * 10 + (((BYTE)(bcd)) & 0x0f)))
#define DECIMAL_TO_BCD(decimal) ((BYTE)(((((BYTE)(decimal)) / 10) << 4) | ((BYTE)(decimal)) % 10))

#define NOP() _nop_()
#define BYTE_ROTATE_LEFT(b, n) _crol_(b, n)
#define BYTE_ROTATE_RIGHT(b, n) _cror_(b, n)
#define WORD_ROTATE_LEFT(w, n) _irol_(w, n)
#define WORD_ROTATE_RIGHT(w, n) _iror_(w, n)
#define DWORD_ROTATE_LEFT(dw, n) _lrol_(dw, n)
#define DWORD_ROTATE_RIGHT(dw, n) _lror_(dw, n)

#define ENABLE_ALL_INTERRUPTS() (EA = 1)
#define DISABLE_ALL_INTERRUPTS() (EA = 0)

#endif

其实,里面的大部分内容都是从VC的头文件里拷贝过来的没什么创新,而且从命名也比较好判断出实现的功能,也就不一一介绍了。下面说一下几个常用的:
1、LOBYTE( )和HIBYTE( )。从名字就可以看出,取一个字长的低字节和高字节。这两个宏在定时器的初值装载中经常要用到。在网上或书上几乎所有的程序都是这样:
TH0 = (65536- X) / 256;
TL0 = (65536 - X) % 256;
其实这样赋值是非常不直观的,高字节为什么要除以256?低字节为什么要对256取余?如果换成如下的写法是不是很明了呢?
TH0 = HIBYTE(65536- X);
TL0 = LOBYTE(65536 - X);
2、TEST_BIT( )、SET_BIT( )和RESET_BIT( )。单片机的资源比较紧张,经常要用到以“位”为单位。这三个宏就是为了方便位操作的。
3、BCD_TO_DECIMAL( )和DECIMAL_TO_BCD( )。用过ds1302的朋友都知道,从中度取的都是BCD格式的信息,经常需要与十进制之间进行转换。
当然,这个头文件只是起到一个抛砖引玉的作用,随时都加入需要的功能。这样做的好处是把经常用到的功能提炼出来,提高了代码的复用率。更重要的是,今后所有自己的库文件的编写都用到了此头文件中的内容。就像所有Windows程序都需要包含windows.h头文件一样。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐