当前位置:文档之家› 论文C51典型例程

论文C51典型例程

论文C51典型例程
论文C51典型例程

//一、把P1口的8个LED中4个点亮,4个熄灭

#include

void main()

{

P1=0xaa;

while(1);

}

简单原理图如下,有另外4个LED灯没有画出来,(实际应该是8个灯的)

//二、间隔1s闪烁

#include

sbit d1=P1^0;

void main()

{

unsigned int i,j;

while(1)

{

d1=0; //点亮

for(i=1000;i>0;i--) //延时1s。内循环一直是110,外循环1000表示1000ms for(j=110;j>0;j--); //即1s;设为500表示延时0.5s

d1=1; //熄灭

for(i=1000;i>0;i--)

for(j=110;j>0;j--);

}

}

//三、独立按键测试**************************/

void timer0(void) interrupt 1 //中断号为1

{

static unsigned char wei=0;

unsigned char weixuan=0x01;

TH0=0xf4;

TL0=0x48; //重新给定时器赋值

BCD();

P0=DISP[wei]; //送显示数据

DUAN_LE=1; //开段控制线

DUAN_LE=0;

P0=weixuan<

WEI_LE=1; //开位控制线

WEI_LE=0;

wei++; //扫描下一位

if(wei>=WEISHU)wei=0;

}

/****************************************************************************/

void main(void)

{

WEI_LE=0;

DUAN_LE=0; //锁存复位

TMOD=0x01; //定时器0工作于方式1

TH0=0xf4;

TL0=0x48; //定时3MS;定义数码管显示扫描时间

TR0=1; //允许定时器工作

ET0=1; //允许定时器中断

EA=1; //开中断

while(1)

{

if(K_T0==0)

Bit0=1;

if(K_T1==0)

Bit0=2;

if(K_INT0==0)

Bit0=3;

if(K_INT1==0)

Bit0=4; //读按键值

}

}

//4*4矩阵键盘检测和键值的数码管显示

#include

/***********************************************************************

* 共阳极七段数码管显示对应段查询表(数字0-9分别对应code_table[0]-[9])

* 分别对应a b c d e f g dp

* p00 p01 p02 p03 p04 p05 p06 p07

***********************************************************************/ unsigned char code code_table[]= //数码管十六进制编码表

{0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e}; unsigned char code m_ucKeyTab[]= //键盘十六进制编码表

{0xde,0xe7,0xd7,0xb7,0xeb,0xdb,0xbb,0xed,0xdd,0xbd,0x77,0x7b,0x7d,0x7e,0xbe, 0xee};

#define WEISHU 8 //修改该处可以做到不同位数的动态显示,本程序可以做到最多8个

#define KEY_STATUS P2 //键盘引脚

sbit WEI_LE =P1^1; //定义位控制线

sbit DUAN_LE =P1^0; //定义段控制线

unsigned char DISP[8]; //定义显示缓存器

unsigned char Bit0,Bit1,Bit2,Bit3,Bit4,Bit5,Bit6,Bit7;

/**************************************************************************** 名称: Delay

说明: 程序延时

参数: 无

返回: 无

*****************************************************************************/ void Delay()

{

unsigned char a,b;

for(a=0;a<255;a++)

for(b=0;b<255;b++);

}

/****************************************************************

* 将int型转换为4位BCD码

****************************************************************/

void BCD()

{

DISP[0]=code_table[Bit0];

DISP[1]=code_table[Bit1];

DISP[2]=code_table[Bit2];

DISP[3]=code_table[Bit3];

DISP[4]=code_table[Bit4];

DISP[5]=code_table[Bit5];

DISP[6]=code_table[Bit6];

DISP[7]=code_table[Bit7];

}

/**************************************************************************** 名称: KeyCheck()

说明: 键盘检测

参数: 无

返回: 键盘码值,若无键按下则返回16

*****************************************************************************/ unsigned char KeyCheck()

{

unsigned char a,b;

for(a=0;a<4;a++) //循环4次

{

switch(a) //改变键盘扫描码

{

case 0:KEY_STA TUS=0xef;break;

case 1:KEY_STA TUS=0xdf;break;

case 2:KEY_STA TUS=0xbf;break;

case 3:KEY_STA TUS=0x7f;break;

};

b=KEY_STATUS;

if((b&0x0f)!=0x0f) //判断是否有按键按下

{

for(a=0;a<16;a++) //根据键盘码判断那个键按下

{

if(b==m_ucKeyTab[a])

{

return a;

}

}

}

}

return 16;

}

/*************************

Timer 0 定时中断处理

**************************/

void timer0(void) interrupt 1

{

static unsigned char wei=0;

unsigned char weixuan=0x01;

TH0=0xf4;

TL0=0x48; //重新给定时器赋值

BCD();

P0=DISP[wei]; //送显示数据

DUAN_LE=1; //开段控制线

DUAN_LE=0;

P0=weixuan<

WEI_LE=1; //开位控制线

WEI_LE=0;

wei++; //扫描下一位

if(wei>=WEISHU)wei=0;

}

void main(void)

{

unsigned char ucKey;

Bit0=0;Bit1=0;Bit2=0;Bit3=0;

Bit4=0;Bit5=0;Bit6=0;Bit7=0;

WEI_LE=0;

DUAN_LE=0; //锁存复位

TMOD=0x01; //定时器0工作于方式1

TH0=0xf4;

TL0=0x48; //定时3MS;定义数码管显示扫描时间

TR0=1; //允许定时器工作

ET0=1; //允许定时器中断

EA=1; //开中断

while(1)

{

ucKey=KeyCheck(); //获得键盘值

if(ucKey!=16) //判断是否有键按下,若有则将它在数码管显示出来

{

Bit7=Bit6; //在数码管显示键盘值

Bit6=Bit5;

Bit5=Bit4;

Bit4=Bit3;

Bit3=Bit2;

Bit2=Bit1;

Bit1=Bit0;

Bit0=ucKey;

Delay();

Delay();

}

}

}

//五、1602字符液晶测试

#include"reg51.h"

#define uchar unsigned char

#define uint unsigned int

sbit LCM_RW=P2^1; /*定义引脚*/

sbit LCM_RS=P2^0;

sbit LCM_E=P2^2;

sbit WEI_LE=P1^1; //定义位控制线

sbit DUAN_LE=P1^0; //定义段控制线

#define LCM_Data P0

#define Busy 0x80 /*用于检测LCM状态字中的Busy 标识*/

void WriteDataLCM(uchar WDLCM);

void WriteCommandLCM(uchar WCLCM,BuysC);

uchar ReadDataLCM(void);

uchar ReadStatusLCM(void);

void LCMInit(void);

void DisplayOneChar(uchar X, uchar Y, uchar DData);

void DisplayStrChar(uchar X, uchar Y, uchar *DData);

void Delay5Ms(void);

void Delay400Ms(void);

uchar code cdle_net[] = {"YM100 V4.0"};

uchar code email[] = {"cany_999@https://www.doczj.com/doc/3517680658.html,"};

void main(void)

{

P0=0xFF;

DUAN_LE=1;

DUAN_LE=0;

P0=0x00;

WEI_LE=1;

WEI_LE=0; /*关闭数码管显示*/

Delay400Ms(); /*启动等待,等LCM讲入工作状态*/

LCMInit(); /*LCM初始化*/

Delay5Ms(); /*延时片刻(可不要)*/

DisplayStrChar(2, 0, cdle_net);

DisplayStrChar(0, 1, email);

while(1);

}

/*写数据*/

void WriteDataLCM(uchar WDLCM)

ReadStatusLCM(); /*检测忙*/

LCM_Data = WDLCM;

LCM_RS = 1;

LCM_RW = 0;

LCM_E = 0; /*若晶振速度太高可以在这后加小的延时*/

LCM_E = 0; /*延时*/

LCM_E = 1;

}

/*写指令*/

void WriteCommandLCM(uchar WCLCM,BuysC) /*BuysC为0时忽略忙检测*/

{

if (BuysC) ReadStatusLCM(); /*根据需要检测忙*/

LCM_Data = WCLCM;

LCM_RS = 0;

LCM_RW = 0;

LCM_E = 0;

LCM_E = 0;

LCM_E = 1;

}

/*读数据*/

uchar ReadDataLCM(void)

{

LCM_RS = 1;

LCM_RW = 1;

LCM_E = 0;

LCM_E = 0;

LCM_E = 1;

return(LCM_Data);

}

/*读状态*/

uchar ReadStatusLCM(void)

{

LCM_Data = 0xFF;

LCM_RS=0;

LCM_RW = 1;

LCM_E = 0;

LCM_E = 0;

LCM_E = 1;

while (LCM_Data & Busy); /*检测忙信号*/

return(LCM_Data);

}

void LCMInit(void) /*LCM初始化*/

{

LCM_Data = 0;

WriteCommandLCM(0x38,0); /*三次显示模式设置,不检测忙信号*/

Delay5Ms();

WriteCommandLCM(0x38,0);

Delay5Ms();

WriteCommandLCM(0x38,0);

Delay5Ms();

WriteCommandLCM(0x38,1); /*显示模式设置,开始要求每次检测忙信号*/

WriteCommandLCM(0x08,1); /*关闭显示*/

WriteCommandLCM(0x01,1); /*显示清屏*/

WriteCommandLCM(0x06,1); /* 显示光标移动设置*/

WriteCommandLCM(0x0C,1); /*显示开及光标设置*/

} /*按指定位置显示一个字符*/

void DisplayOneChar(uchar X, uchar Y, uchar DData)

{

Y &= 0x1;

X &= 0xF; /*限制X不能大于15,Y不能大于1*/ if (Y) X |= 0x40; /*当要显示第二行时地址码+0x40;*/ X |= 0x80; /*算出指令码*/

WriteCommandLCM(X, 0); /*这里不检测忙信号,发送地址码*/

WriteDataLCM(DData);

}

/*按指定位置显示一串字符*/

void DisplayStrChar(uchar X, uchar Y, uchar *DData)

{

uchar ListLength;

ListLength = 0;

Y &= 0x1;

X &= 0xF; /*限制X不能大于15,Y不能大于1*/ while (DData[ListLength]>0) /*若到达字串尾则退出*/ {

if (X <= 0xF) /*X坐标应小于0xF*/

{

DisplayOneChar(X, Y, DData[ListLength]); /*显示单个字符*/

ListLength++;

X++;

}

}

}

/*5ms延时*/ void Delay5Ms(void)

{

uint TempCyc = 5552;

while(TempCyc--);

}

/*400ms延时*/ void Delay400Ms(void)

{

uchar TempCycA = 5;

uint TempCycB;

while(TempCycA--)

{

TempCycB=7269;

while(TempCycB--);

}

}

//六、红外测试

/*************************

Timer 1定时中断处理

**************************/

void timer1(void) interrupt 3

{

static unsigned char wei=0;

unsigned char weixuan=0x01;

TH1=0xf4;

TL1=0x48; //重新给定时器赋值

BCD();

P0=DISP[wei]; //送显示数据

DUAN_LE=1; //开段控制线

DUAN_LE=0;

P0=weixuan<

WEI_LE=1; //开位控制线

WEI_LE=0;

wei++; //扫描下一位

if(wei>=WEISHU)wei=0;

}

/**********************************************/

void delay (unsigned int value) /*延时副程式*/

{

while (value!=0) value--; /*10US延时*/

}

/**********************************************/

void DL(void)

{

unsigned char i;

for(i=0;i<7;i++)

{

delay(7000);

}

}

/****************************************************************************** ****/

void process(void)

{

unsigned char i;

ET0=0;

for(i=0;i<8;i++)

{

delay(102);

if(in)goto pro_end;

}

while(!in)nop;

delay(544);

for(i=0;i<8;i++)

{

while(!in)nop;

delay(102);

if(!in){dat_1=dat_1>>0x01;}

else {delay(114);dat_1=(dat_1>>0x01)|0x80;}

}

delay(544);

for(i=0;i<8;i++)

{

while(!in)nop;

delay(102);

if(!in){dat_2=dat_2>>0x01;}

else {delay(114);dat_2=(dat_2>>0x01)|0x80;}

}

if(dat_1==0xc4&&dat_2<0x20)

{

ET0=0;

Bit0=dat_2&0x0f;

Bit1=dat_2>>4;

Bit2=0x04;

Bit3=0x0c;

ET0=1;

DL();

}

pro_end:;

ET0=1;

}

/*************************************************************/ void T0_count(void)interrupt 1 using 1

{

inter_psw=1;

}

/*************************************************************/

void main(void)

{

dat_1=0x00;

dat_2=0x00;

WEI_LE=0;

DUAN_LE=0; //锁存复位

TMOD=0x16; //定时器1工作于方式1;定时器0工作于方式2;

TH0=0xff;

TL0=0xff;

TH1=0xf4;

TL1=0x48; //定时3MS;定义数码管显示扫描时间

TR0=1;

TR1=1; //允许定时器工作

ET1=1; //允许定时器中断

ET0=1;

EA=1; //开中断

while(1)

{

if(inter_psw){process();inter_psw=0;}

}

}

相关主题
文本预览
相关文档 最新文档