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

 

作者: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头文件一样。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值