基于51单片机的头文件—自己编写
- 格式:docx
- 大小:15.65 KB
- 文档页数:1
51单片机C语言头文件及其使用2007-05-29 16:33很多初学单片机者往往对C51的头文件感到很神秘,而为什么要那样写,甚至有的初学者喜欢问,P1口的P为什么要大写,不大写行不行呢?其实这样的问题,看过本文后,就会明白。
其实这个是在头文件中用sfr定义的,现在定义好了的是这样的sfr P1 = 0x90;,也就是说,到底大写,还是小写,就是在这里面决定的。
这就说明,如果你要用小写,就得在头文件中改为小写。
其实它都是为了编程序方便才这样写的,在程序编译时,就会变成相应的地址(如P1就变成了0x90)。
还有一点就是,现在有很多改进型的单片机,它们有很多新增的特殊功能寄存器在标准的reg51.h或reg52.h中没有定义,这就需要自己加进头文件(相关厂家已经把它们定义好了),当然也可以直接在程序中定义。
下面是一个标准的C51头文件:(此文件一般在C:\KEIL\C51\INC下,INC文件夹根目录里有不少头文件,并且里面还有很多以公司分类的文件夹,里面也都是相关产品的头文件。
如果我们要使用自己写的头文件,使用的时候只需把对应头文件拷贝到INC文件夹里就可以了。
)/* BYTE Registers */sfr P0 = 0x80;sfr P1 = 0x90;sfr P2 = 0xA0;sfr P3 = 0xB0;sfr PSW = 0xD0;sfr ACC = 0xE0;sfr B = 0xF0;sfr SP = 0x81;sfr DPL = 0x82;sfr DPH = 0x83;sfr PCON = 0x87;sfr TCON = 0x88;sfr TMOD = 0x89;sfr TL0 = 0x8A;sfr TL1 = 0x8B;sfr TH0 = 0x8C;sfr TH1 = 0x8D;sfr IE = 0xA8;sfr IP = 0xB8;sfr SCON = 0x98;sfr SBUF = 0x99;/* 8052 Extensions */sfr T2CON = 0xC8;sfr RCAP2L = 0xCA;sfr RCAP2H = 0xCB;sfr TL2 = 0xCC;/* BIT Registers */ /* PSW */sbit CY = PSW^7;sbit AC = PSW^6;sbit F0 = PSW^5;sbit RS1 = PSW^4;sbit RS0 = PSW^3;sbit OV = PSW^2;sbit P = PSW^0; //8052 only/* TCON */sbit TF1 = TCON^7;sbit TR1 = TCON^6;sbit TF0 = TCON^5;sbit TR0 = TCON^4;sbit IE1 = TCON^3;sbit IT1 = TCON^2;sbit IE0 = TCON^1;sbit IT0 = TCON^0;/* IE */sbit EA = IE^7;sbit ET2 = IE^5; //8052 onlysbit ES = IE^4;sbit ET1 = IE^3;sbit EX1 = IE^2;sbit ET0 = IE^1;sbit EX0 = IE^0;/* IP */sbit PT2 = IP^5;sbit PS = IP^4;sbit PT1 = IP^3;sbit PX1 = IP^2;sbit PT0 = IP^1;sbit PX0 = IP^0;/* P3 */sbit RD = P3^7;sbit WR = P3^6;sbit T1 = P3^5;sbit INT1 = P3^3;sbit INT0 = P3^2;sbit TXD = P3^1;sbit RXD = P3^0;/* SCON */sbit SM0 = SCON^7;sbit SM1 = SCON^6;sbit SM2 = SCON^5;sbit REN = SCON^4;sbit TB8 = SCON^3;sbit RB8 = SCON^2;sbit TI = SCON^1;sbit RI = SCON^0;/* P1 */sbit T2EX = P1^1; // 8052 onlysbit T2 = P1^0; // 8052 only/* T2CON */sbit TF2 = T2CON^7;sbit EXF2 = T2CON^6;sbit RCLK = T2CON^5;sbit TCLK = T2CON^4;sbit EXEN2 = T2CON^3;sbit TR2 = T2CON^2;sbit C_T2 = T2CON^1;sbit CP_RL2 = T2CON^0;还有一点就是,现在有很多改进型的单片机,它们有很多新增的特殊功能寄存器在标准的reg51.h或reg52.h中没有定义,这就需要自己加进头文件(相关厂家已经把它们定义好了),当然也可以直接在程序中定义。
/*预处理命令*/#include<reg52.h> //包含单片机寄存器的头文件#include<intrins.h> //包含_nop_()函数定义的头文件#define uchar unsigned char#define uint unsigned int#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};sbit IRIN=P3^2; //红外接收器数据线sbit LCD_RS = P0^7;sbit LCD_RW = P0^6;sbit LCD_EN = P0^5;uchar begin[]={"My car!"};uchar cdis1[]={"jiansu!"};uchar cdis2[]={"qianjin!"};uchar cdis3[]={"jiasu!"};uchar cdis4[]={"zuozhuang!"};uchar cdis5[]={"STOP!"};uchar cdis6[]={"youzhuan!"};uchar cdis8[]={"daoche!"};sbit M1 = P1^0;sbit M2 = P1^1;sbit M3 = P1^2;sbit M4 = P1^3;sbit EN12 = P1^4;sbit EN34 = P1^5;uchar IRCOM[7];uchar m,n;uchar t=2;uchar g;uchar code digit[]={"0123456789"};uint v;uchar count;bit flag;void delayxms(uchar t);void delay(unsigned char x) ;void delay1(int ms);void motor();void lcd_display();/*检查LCD忙状态lcd_busy为1时,忙,等待。
//51单片机做的红外遥控实验(C语言)#include<reg51.h>#define u8 unsigned char#define u16 unsigned int#define ID 0x00 //本遥控器的ID号sbit ir=P3^3;code u8 seg[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //0-9的段码code u8 s[]={1,0x40,0x48,0x04,0x02,0x05,0x54,0x0A,0x1E,0x0E}; u8 buf[4];bit ir_f=0;u8 nu;void delay(u16 x){while(x--);}void show(u16 x){u8 i=0,k=0;u8 s[4];kk:s[i]=x%10;if((x/10)>=1){x=x/10;i++;goto kk;}k=i+1;for(i=0;i<k;i++){P0=seg[s[i]];P2=~(8>>i);delay(300);P0=0XFF;P2=0XFF;}}void timer0_init(){TH0=0;TL0=0;TMOD|=0x01;TR0=0;}u16 low_test(){u16 t;TR0=1;while((ir==0)&&((TH0&0X80)!=0X80));TR0=0;t=TH0;t<<=8;t|=TL0;TH0=0;TL0=0; //t=(TH*256+TL0);//机器周期数return t;}u16 high_test(){u16 t;TR0=1;while((ir==1)&&((TH0&0X80)!=0X80));TR0=0;t=TH0;t<<=8;t|=TL0;TH0=0;TL0=0;return t;}/*u16 time_test(bit x){}*/u8 receive_8bit(){u8 d,i;u16 t;for(i=0;i<8;i++){t=low_test();t=high_test();d>>=1;if((t>=2750)&&(t<=3100)){d|=0x80;}}return d;}void ir_decode(){u16 t;u8 i;if(ir==0)//有遥控信号{t=low_test();//8295-9000us,倍频的是16590-18000if((t>=14500)&&(t<=18000))//检查引导码低电平时间{t=high_test();if((t>=8000)&&(t<=9000))//检查高电平{for(i=0;i<4;i++){buf[i]=receive_8bit();}if(buf[0]==(~buf[1]))//检查系统码是否正确{if(buf[0]==ID){if(buf[2]==(~buf[3])){//具体按键处理ir_f=1; //遥控有效}}}}}}}/*void key(){if(buf[2]==0x40){P1^=(1<<0);}if(buf[2]==0x48){P1^=(1<<1);}}*/void ir_execuse(){if(ir_f==1){switch(buf[2]){case 0x40:P1^=(1<<0);break;case 0x48:P1^=(1<<1);break;case 0x04:P1^=(1<<2);break;case 0x02:P1^=(1<<3);break;case 0x05:P1^=(1<<4);break;case 0x54:P1^=(1<<5);break;case 0x0A:P1^=(1<<6);break;case 0x1E:P1^=(1<<7);break;}ir_f=0;}}void show_d(){u8 j;for(j=0;j<10;j++){if(s[j]==buf[2]){nu=j;break;}}show(nu);}void isr_init(){EA=1;EX1=1;//外部中断,一直看3.3有没有下降沿。
我们在用c语言编程时往往第一行就是头文件,51单片机为reg51.h或reg52.h,51单片机相对来说比较简单,头文件里面内容不多,像飞思卡尔、ARM 系列的单片机头文件往往内容就非常多,尽管如此,对一些初次接触单片机的朋友来说,51的头文件还是搞不太清楚,今天具体来说明一下。
1)“文件包含”处理概念所谓“文件包含”是指在一个文件内将另外一个文件的内容全部包含进来。
因为被包含的文件中的一些定义和命令使用的频率很高,几乎每个程序中都可能要用到,为了提高编程效率,减少编程人员的重得劳动,将这些定义和命令单独组成一个文件,如reg51.h,然后用#include<reg51.h>包含进来就可以了,这个就相当于工业上的标准零件,拿来直接用就可以了。
2)寄存器地址及位地址声明的原因reg51.h里面主要是一些特殊功能寄存器的地址声明,对可以位寻址的,还包括一些位地址的声明,如果如sfr P1=0x80; sfr IE=0xA8;sbit EA=0xAF等。
sfr P1 = 0x90这句话表示:P1口所对应的特殊功能寄存器P1在内存中的地址为0x80,sbit EA=0xAF这句话表示EA这一位的地址为0xAF。
注意这里出现了一个使用很频繁的sfr和sbit。
sfr 表示特殊功能寄存器的意思,它并非标准C 语言的关键字,而是Keil 为能直接访问80C51中的SFR 而提供了一个新的关键词,其用法是:sfr 特殊功能寄存器名=地址值(注意对于头文件里“特殊功能寄存器名”,用户实际上也可以修改的,如P1=0x80,也可改为A1=0x80,但sfr 和地址值则不能更改,否者会编译出错。
)sbit表示位的意思,它也是非标准C 语言的关键字,编写程序时如需操作寄存器的某一位(可位寻址的寄存器才能用)时,需定义一个位变量,此时就要要到sbit,如sbit deng=P1^0,sbit EA = 0xAF;需要注意的是,位定义时有些特殊,用法有三种:第一种方法:sbit 位变量名=寄存器位地址值第二种方法:sbit 位变量名=SFR 名称^寄存器位值(0-7)第三种方法:sbit 位变量名=SFR 地址值^寄存器位值如:sbit IT0=0x88 (1)说明:0x88是IT0 的位地址值sbit deng=P1^2 (2)说明:其中P1 必须先用sfr 定义好sbit EA=0xA8^7 (3)说明:0xA8 就是IE寄存器的地址值以上三种定义方法需注意的是 IT0 deng EA可由用户随便定义,但必须满足C语言对变量名的定义规则。
自制51单片机常用头文件
#ifndef __COM_H__
#define __COM_H__
#define uchar unsigned char
#define uint unsigned int
#define XTAL 11059200 // CUP 晶振频率
#define baudrate 9600 // 通信波特率
void sendmsg(uint ps)
{
SBUF = ps; // 要发送的字符放入缓冲区
while(TI == 0); // 一直等等,直到发送完数据为止
TI = 0;
}
uint rcvmsg(void) //调用此函数前,要先调用RI,查看是否收到数据,确定已收到的话,再调用此函数
{
RI=0; //要先将RI=0再返回,否则,返回后,RI=0这句就不执行了。
return SBUF;
}
void initcom(void)
{
TMOD = 0x20; // 定时器1工作于8位自动重载模式, 用于产生波特率
TH1=(unsigned char)(256 - (XTAL / (32L * 12L * baudrate)));
TL1=(unsigned char)(256 - (XTAL / (32L * 12L * baudrate))); // 定时器1赋初值
SM0 = 0; //串口工作方式控制
SM1 = 1; //串口工作方式控制 //这两个共同控制了串口工作方式为 0;
REN = 1; //串口接收允许
PCON = 0x00;
TR1 = 1; //允许串口接收
ES = 0; //关闭串口中断
}
#endif。
C51中头文件的写法一、头文件位置#include ; 优先在系统默认路径查找头文件#include“xxx.h”有现在项目路径查找头文件二、#ifndef和#endif通常形式为#ifndef _xxxx_h_#define _xxxx_h_.........(头文件具体内容)#endif这样的写法表示,如果_xxxx_h_还没有被定义,那么头文件内容将被执行,如果已经定义过了,那么头文件内容就不执行了。
作用在于,如果某头文件被不同c文件同时调用,那么里面的内容不至于因为重复定义而出错,因为不管调用几次头文件,其内容只有在第一次出现时被执行,同时定义一个_xxxx_h_,以后再次调用时,头文件内容被忽略。
三、函数和宏假设有如下文件 main.caaa.caaa.h其中,,aaa.c里面有一个宏X,一个函数Y,且函数Y 中使用了Xaaa.h里面申明了函数Ymain.c里包含了aaa.h文件,调用了函数Y,但没有定义宏X那么,编译时不会出错,这表示,函数Y中出现宏X 时,它会在自身所在的c文件,即aaa.c里面查找宏变化1:如上情况不变,但是在main.c里面将整个函数Y重新写一遍编译出错,提示 “error C202: 'X': undefined identifier”说明此时函数Y在main.c文件中找不到宏X,因此提示为未定义的符号变化2:将aaa.c中的宏剪切到main.c,其余情况不变编译出错,同样提示“error C202: 'X': undefined identifier”结论:函数中如果出现宏,那么该函数能且只能在其自身所在的c文件中查找该宏,如果二者不在同个c 文件,必然出错。
新概念51单片机C语言教程----入门、提高、开发、拓展全攻略郭天祥编著电子工业出版社例2.2.1编写程序,点亮第一个发光二极管(part2_1.c P27)#include <reg52.h> //52系列单片机头文件sbit led1=P1^0; //声明单片机P1口的第一位void main() //主函数{led1=0; /*点亮第一个发光二极管*/}例2.2.2编写程序,点亮P1口的若干二极管(part2_2.c P39)#include <reg52.h> //52系列单片机头文件void main() //主函数{P1=0xaa;//while(1);}例2.5.1利用for语句延时特性,编写第一个发光二极管以间隔1S亮灭闪动的程序(part2_3.c P42)#include <reg52.h> //52系列单片机头文件#define uint unsigned int //宏定义sbit led1=P1^0; //声明单片机P1口的第一位uint i,j;void main() //主函数{while(1) //大循环{led1=0; /*点亮第一个发光二极管*/for(i=1000;i>0;i--) //延时for(j=110;j>0;j--);led1=1; /*关闭第一个发光二极管*/for(i=1000;i>0;i--) //延时for(j=110;j>0;j--);}}- 2 - 例2.6.1编写程序使第一个发光二极管以间隔500ms亮灭闪动。
(part2_4.c P48)#include <reg52.h> //52系列单片机头文件#define uint unsigned int //宏定义sbit led1=P1^0; //声明单片机P1口的第一位void delay1s(); //声明子函数void main() //主函数{while(1) //大循环{led1=0; /*点亮第一个发光二极管*/delay1s(); //调用延时子函数led1=1; /*关闭第一个发光二极管*/delay1s(); //调用延时子函数}}void delay1s() //子函数体{uint i,j;for(i=500;i>0;i--)for(j=110;j>0;j--);}例2.7.1编写程序使第一个二极管以亮200ms、灭800ms的方式闪动。
这个是我自己编写的51单片机的库函数对应的头文件,在网上本人还分享了很多热门模块的库函数,都是现成的,欢迎下载!!!!#ifndef__CONFIG_H#define__CONFIG_H#include<myreg51.h>#include<intrins.h>#include<stdio.h>#include<string.h>#include<math.h>/**************************选择晶振频率*******************************///#define MAIN_freq 22118400L //定义主时钟//#define MAIN_freq 12000000L //定义主时钟12M hz#define MAIN_freq 11059200L//定义主时钟11.0592M hz//#define MAIN_freq 5529600L //定义主时钟//#define MAIN_freq 24000000L //定义主时钟/**************************定义常用词*******************************/#define uint unsignedint#define sint signedint#define uchar unsignedchar#define schar signedchar#define error 1//定义错误返回1#define right 0//定义正确返回0/***********************************************************/#endif#ifndef __MYREG51_H__#define __MYREG51_H__sfr PSW =0xD0;sfr ACC =0xE0;sfr B =0xF0;sfr SP =0x81;sfr DPL =0x82;sfr DPH =0x83;sfr PCON =0x87;sfr TCON =0x88;sfr TMOD =0x89;sfr TL0 =0x8A;sfr TL1 =0x8B;sfr TH0 =0x8C;sfr TH1 =0x8D;sfr IE =0xA8;sfr IP =0xB8;sfr SCON =0x98;sfr SBUF =0x99;/* BIT Register *//* PSW */sbit CY =0xD7;//左移的时候把最高位移动到了CY中sbit AC =0xD6;sbit F0 =0xD5;sbit RS1 =0xD4;sbit RS0 =0xD3;sbit OV =0xD2;sbit P =0xD0;/* TCON */sbit TF1 =0x8F;sbit TR1 =0x8E;sbit TF0 =0x8D;sbit TR0 =0x8C;sbit IE1 =0x8B;sbit IT1 =0x8A;sbit IE0 =0x89;sbit IT0 =0x88;/* IE */sbit EA =0xAF;sbit ES =0xAC;sbit ET1 =0xAB;sbit EX1 =0xAA;sbit ET0 =0xA9;sbit EX0 =0xA8;/* IP */sbit PS =0xBC;sbit PT1 =0xBB;sbit PX1 =0xBA;sbit PT0 =0xB9;sbit PX0 =0xB8;/* P3 */sbit RD =0xB7;sbit WR =0xB6;sbit T1 =0xB5;sbit T0 =0xB4;sbit INT1 =0xB3;sbit INT0 =0xB2;sbit TXD =0xB1;sbit RXD =0xB0;/* SCON */sbit SM0 =0x9F;sbit SM1 =0x9E;sbit SM2 =0x9D;sbit REN =0x9C;sbit TB8 =0x9B;sbit RB8 =0x9A;sbit TI =0x99;sbit RI =0x98;/* BYTE Register *//***********************引脚定义********************************/ /* P0 */sfr P0 =0x80;sbit P00 = P0 ^0;sbit P01 = P0 ^1;sbit P02 = P0 ^2;sbit P03 = P0 ^3;sbit P04 = P0 ^4;sbit P05 = P0 ^5;sbit P06 = P0 ^6;sbit P07 = P0 ^7;/* P1 */sfr P1 =0x90;sbit P10 = P1 ^0;sbit P11 = P1 ^1;sbit P12 = P1 ^2;sbit P13 = P1 ^3;sbit P14 = P1 ^4;sbit P15 = P1 ^5;sbit P16 = P1 ^6;sbit P17 = P1 ^7;/* P2 */sfr P2 =0xA0;sbit P20 = P2 ^0;sbit P21 = P2 ^1;sbit P22 = P2 ^2;sbit P23 = P2 ^3;sbit P24 = P2 ^4;sbit P25 = P2 ^5;sbit P26 = P2 ^6;sbit P27 = P2 ^7;/* P3 */sfr P3 =0xB0;sbit P30 = P3 ^0;sbit P31 = P3 ^1;sbit P32 = P3 ^2;sbit P33 = P3 ^3;sbit P34 = P3 ^4;sbit P35 = P3 ^5;sbit P36 = P3 ^6;sbit P37 = P3 ^7;#endif。