2024年6月5日发(作者:)

0xff}; //以0xff作为音符的结束标志

//以下是简谱中每个音符的节拍

//"4"对应4个延时单位,"2"对应2个延时单位,"1"对应1个延时单位

unsigned char code JP[ ]={4,1,1,4,1,1,2,

2,2,2,2,8,

4,2,3,1,2,2,

10,

4,2,2,4,4,

2,2,2,2,4,

2,2,2,2,2,2,2,

10,

4,4,4,2,2,

4,2,4,4,

100

4,2,2,2,2,2,2,

10,

4,2,2,4,4,

2,2,2,2,6,

4,2,2,4,1,1,4,

10,

4,2,2,4,1,1,4,

10

};

EA=1; //开总中断

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

TMOD=0x00; // 使用定时器T0的模式1(13位计数器)

while(1) //无限循环

101

{

i=0; //从第1个音符f[0]开始播放

while(f[i]!=0xff) //只要没有读到结束标志就继续播放

{

C=460830/f[i];

TH0=(8192-C)/32; //可证明这是13位计数器TH0高8位的赋初值方

TL0=(8192-C)%32; //可证明这是13位计数器TL0低5位的赋初值方

TR0=1; //启动定时器T0

for(j=0;j

delay(); //延时1个节拍单位

TR0=0; //关闭定时器T0

i++; //播放下一个音符

102

}

}

}

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

函数功能:定时器T0的中断服务子程序,使P3.7引脚输出音频的方波

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

void Time0(void ) interrupt 1 using 1

{

sound=!sound; //将P3.7引脚输出电平取反,形成方波

TH0=(8192-C)/32; //可证明这是13位计数器TH0高8位的赋初值方法

TL0=(8192-C)%32; //可证明这是13位计数器TL0低5位的赋初值方法

}

//实例50-1:输出50个矩形脉冲

103

#include //包含51单片机寄存器定义的头文件

sbit u=P1^4; //将u位定义为P1.4

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

函数功能:延时约30ms (3*100*100=30 000μs =30m

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

void delay30ms(void)

{

unsigned char m,n;

for(m=0;m<100;m++)

for(n=0;n<100;n++)

;

}

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

104

函数功能:主函数

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

void main(void)

{

unsigned char i;

u=1; //初始化输出高电平

for(i=0;i<50;i++) //输出50个矩形脉冲

{

u=1;

delay30ms();

u=0;

delay30ms();

}

105

while(1)

; //无限循环,防止程序“跑飞”

}

//实例50-2:计数器T0统计外部脉冲数

#include //包含51单片机寄存器定义的头文件

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

函数功能:主函数

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

void main(void)

{

TMOD=0x06; // TMOD=0000 0110B,使用计数器T0的模式2

EA=1; //开总中断

ET0=0; //不使用定时器T0的中断

106

TR0=1; //启动T0

TH0=0; //计数器T0高8位赋初值

TL0=0; //计数器T0低8位赋初值

while(1) //无限循环,不停地将TL0计数结果送P1口

P1=TL0;

}

//实例51-2:定时器T0的模式2测量正脉冲宽度

#include //包含51单片机寄存器定义的头文件

sbit ui=P3^2; //将ui位定义为P3.0(INT0)引脚,表示输入电压

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

函数功能:主函数

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

void main(void)

107

{

TMOD=0x0a; // TMOD=0000 1010B,使用定时器T0的模式2,GATE置1

EA=1; //开总中断

ET0=0; //不使用定时器T0的中断

TR0=1; //启动T0

TH0=0; //计数器T0高8位赋初值

TL0=0; //计数器T0低8位赋初值

while(1) //无限循环,不停地将TL0计数结果送P1口

{

while(ui==0) //INT0为低电平,T0不能启动

;

TL0=0; //INT0为高电平,启动T0计时,所以将TL0清0

while(ui==1) //在INT0高电平期间,等待,计时

108

;

P1=TL0; //将计时结果送P1口显示

}

}

//实例52:用定时器T0控制输出高低宽度不同的矩形波

#include //包含51单片机寄存器定义的头文件

sbit u=P3^0; //将u位定义为P3.0,从该引脚输出矩形脉冲

unsigned char Countor; //设置全局变量,储存负跳变累计数

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

函数功能:延时约30ms (3*100*100=30 000μs =30ms)

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

void delay30ms(void)

{

109

unsigned char m,n;

for(m=0;m<100;m++)

for(n=0;n<100;n++)

;

}

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

函数功能:主函数

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

void main(void)

{

unsigned char i;

EA=1; //开放总中断

EX0=1; //允许使用外中断

110

IT0=1; //选择负跳变来触发外中断

Countor=0;

for(i=0;i<100;i++) //输出100个负跳变

{

u=1;

delay30ms();

u=0;

delay30ms();

}

while(1)

; //无限循环, 防止程序跑飞

}

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

111

函数功能:外中断T0的中断服务程序

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

void int0(void) interrupt 0 using 0 //外中断0的中断编号为0

{

Countor++;

P1=Countor;

}

//实例53:用外中断0的中断方式进行数据采集

#include //包含51单片机寄存器定义的头文件

sbit S=P3^2; //将S位定义为P3.2,

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

函数功能:主函数

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

112

void main(void)

{

EA=1; //开放总中断

EX0=1; //允许使用外中断

IT0=1; //选择负跳变来触发外中断

P1=0xff;

while(1)

; //无限循环, 防止程序跑飞

}

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

函数功能:外中断T0的中断服务程序

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

void int0(void) interrupt 0 using 0 //外中断0的中断编号为0

113

{

P1=~P1; //每产生一次中断请求,P1取反一次。

}

//实例54-1:输出负脉宽为200微秒的方波

#include //包含51单片机寄存器定义的头文件

sbit u=P1^4; //将u位定义为P1.4

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

函数功能:主函数

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

void main(void)

{

TMOD=0x02; //TMOD=0000 0010B,使用定时器T0的模式2

EA=1; //开总中断

114

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

TH0=256-200; //定时器T0的高8位赋初值

TL0=256-200; //定时器T0的高8位赋初值

TR0=1; //启动定时器T0

while(1) //无限循环,等待中断

;

}

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

函数功能:定时器T0的中断服务程序

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

void Time0(void) interrupt 1 using 0 //"interrupt"声明函数为中断服务函数

{

u=~u; //将P1.4引脚输出电平取反,产生方波

115

}

//实例54-2:测量负脉冲宽度

#include //包含51单片机寄存器定义的头文件

sbit u=P3^2; //将u位定义为P3.2

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

函数功能:主函数

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

void main(void)

{

TMOD=0x02; //TMOD=0000 0010B,使用定时器T0的模式2

EA=1; //开放总中断

EX0=1; //允许使用外中断

IT0=1; //选择负跳变来触发外中断

116

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

TH0=0; //定时器T0赋初值0

TL0=0; //定时器T0赋初值0

TR0=0; //先关闭T0

while(1)

; //无限循环, 不停检测输入负脉冲宽度

}

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

函数功能:外中断0的中断服务程序

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

void int0(void) interrupt 0 using 0 //外中断0的中断编号为0

{

TR0=1; //外中断一到来,即启动T0计时

117

TL0=0; //从0开始计时

while(u==0) //低电平时,等待T0计时

;

P1=TL0; //将结果送P1口显示

TR0=0; //关闭T0

}

//实例55:方式0控制流水灯循环点亮

#include //包含51单片机寄存器定义的头文件

#include //包含函数_nop_()定义的头文件

unsigned char code Tab[]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};//流水灯

控制码,该数组被定义为全局变量

sbit P17=P1^7;

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

函数功能:延时约150ms

118

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

void delay(void)

{

unsigned char m,n;

for(m=0;m<200;m++)

for(n=0;n<250;n++)

;

}

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

函数功能:发送一个字节的数据

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

void Send(unsigned char dat)

{

119

P17=0; //P1.7引脚输出清0信号,对74LS164清0

_nop_(); //延时一个机器周期

_nop_(); //延时一个机器周期,保证清0完成

P17=1; //结束对74LS164的清0

SBUF=dat; //将数据写入发送缓冲器,启动发送

while(TI==0) //若没有发送完毕,等待

;

TI=0; //发送完毕,TI被置“1”,需将其清0

}

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

函数功能:主函数

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

void main(void)

120

{

unsigned char i;

SCON=0x00; //SCON=0000 0000B,使串行口工作于方式0

while(1)

{

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

{

Send(Tab[i]); //发送数据

delay(); //延时

}

}

}

121

//实例56-1:数据发送程序

#include //包含单片机寄存器的头文件

unsigned char code Tab[ ]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};

//流水灯控制码,该数组被定义为全局变量

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

函数功能:向PC发送一个字节数据

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

void Send(unsigned char dat)

{

SBUF=dat;

while(TI==0)

;

122

TI=0;

}

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

函数功能:延时约150ms

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

void delay(void)

{

unsigned char m,n;

for(m=0;m<200;m++)

for(n=0;n<250;n++)

;

}

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

123

函数功能:主函数

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

void main(void)

{

unsigned char i;

TMOD=0x20; //TMOD=0010 0000B,定时器T1工作于方式2

SCON=0x40; //SCON=0100 0000B,串口工作方式1

PCON=0x00; //PCON=0000 0000B,波特率9600

TH1=0xfd; //根据规定给定时器T1赋初值

TL1=0xfd; //根据规定给定时器T1赋初值

TR1=1; //启动定时器T1

while(1)

{

124

for(i=0;i<8;i++) //模拟检测数据

{

Send(Tab[i]); //发送数据i

delay(); //50ms发送一次检测数据

}

}

}

//实例56-2:数据接收程序

#include //包含单片机寄存器的头文件

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

函数功能:接收一个字节数据

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

unsigned char Receive(void)

125

{

unsigned char dat;

while(RI==0) //只要接收中断标志位RI没有被置“1”

; //等待,直至接收完毕(RI=1)

RI=0; //为了接收下一帧数据,需将RI清0

dat=SBUF; //将接收缓冲器中的数据存于dat

return dat;

}

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

函数功能:主函数

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

void main(void)

{

126

TMOD=0x20; //定时器T1工作于方式2

SCON=0x50; //SCON=0101 0000B,串口工作方式1,允许接收(REN=1)

PCON=0x00; //PCON=0000 0000B,波特率9600

TH1=0xfd; //根据规定给定时器T1赋初值

TL1=0xfd; //根据规定给定时器T1赋初值

TR1=1; //启动定时器T1

REN=1; //允许接收

while(1)

{

P1=Receive(); //将接收到的数据送P1口显示

}

}

127

//实例57-1:数据发送程序

#include //包含单片机寄存器的头文件

sbit p=PSW^0;

unsigned char code Tab[ ]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};

//流水灯控制码,该数组被定义为全局变量

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

函数功能:向PC发送一个字节数据

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

void Send(unsigned char dat)

{

ACC=dat;

TB8=p;

SBUF=dat;

128

while(TI==0)

;

TI=0;

}

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

函数功能:延时约150ms

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

void delay(void)

{

unsigned char m,n;

for(m=0;m<200;m++)

for(n=0;n<250;n++)

;

129

}

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

函数功能:主函数

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

void main(void)

{

unsigned char i;

TMOD=0x20; //TMOD=0010 0000B,定时器T1工作于方式2

SCON=0xc0; //SCON=1100 0000B,串口工作方式3,

//SM2置0,不使用多机通信,TB8置0

PCON=0x00; //PCON=0000 0000B,波特率9600

TH1=0xfd; //根据规定给定时器T1赋初值

TL1=0xfd; //根据规定给定时器T1赋初值

130

TR1=1; //启动定时器T1

while(1)

{

for(i=0;i<8;i++) //模拟检测数据

{

Send(Tab[i]); //发送数据i

delay(); //50ms发送一次检测数据

}

}

}

//实例57-2:数据接收程序

#include //包含单片机寄存器的头文件

sbit p=PSW^0;

131

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

函数功能:接收一个字节数据

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

unsigned char Receive(void)

{

unsigned char dat;

while(RI==0) //只要接收中断标志位RI没有被置"1"

; //等待,直至接收完毕(RI=1)

RI=0; //为了接收下一帧数据,需将RI清0

ACC=SBUF; //将接收缓冲器中的数据存于dat

if(RB8==p)

{

dat=ACC;

132

return dat;

}

}

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

函数功能:主函数

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

void main(void)

{

TMOD=0x20; //定时器T1工作于方式2

SCON=0xd0; //SCON=1101 0000B,串口工作方式1,允许接收(REN=1)

PCON=0x00; //PCON=0000 0000B,波特率9600

TH1=0xfd; //根据规定给定时器T1赋初值

TL1=0xfd; //根据规定给定时器T1赋初值

133

TR1=1; //启动定时器T1

REN=1; //允许接收

while(1)

{

P1=Receive(); //将接收到的数据送P1口显示

}

}

//实例58:单片机向PC发送数据

#include //包含单片机寄存器的头文件

unsigned char code Tab[ ]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};

//流水灯控制码,该数组被定义为全局变量

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

函数功能:向PC发送一个字节数据

134

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

void Send(unsigned char dat)

{

SBUF=dat;

while(TI==0)

;

TI=0;

}

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

函数功能:延时约150ms

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

void delay(void)

{

135

unsigned char m,n;

for(m=0;m<200;m++)

for(n=0;n<250;n++)

;

}

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

函数功能:主函数

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

void main(void)

{

unsigned char i;

TMOD=0x20; //TMOD=0010 0000B,定时器T1工作于方式2

SCON=0x40; //SCON=0100 0000B,串口工作方式1

136

PCON=0x00; //PCON=0000 0000B,波特率9600

TH1=0xfd; //根据规定给定时器T1赋初值

TL1=0xfd; //根据规定给定时器T1赋初值

TR1=1; //启动定时器T1

while(1)

{

for(i=0;i<8;i++) //模拟检测数据

{

Send(Tab[i]); //发送数据i

delay(); //150ms发送一次数据

}

}

}

137

//实例59:单片机接收PC发出的数据

#include //包含单片机寄存器的头文件

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

函数功能:接收一个字节数据

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

unsigned char Receive(void)

{

unsigned char dat;

while(RI==0) //只要接收中断标志位RI没有被置“1”

; //等待,直至接收完毕(RI=1)

RI=0; //为了接收下一帧数据,需将RI清0

dat=SBUF; //将接收缓冲器中的数据存于dat

return dat;

138

}

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

函数功能:主函数

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

void main(void)

{

TMOD=0x20; //定时器T1工作于方式2

SCON=0x50; //SCON=0101 0000B,串口工作方式1,允许接收(REN=1)

PCON=0x00; //PCON=0000 0000B,波特率9600

TH1=0xfd; //根据规定给定时器T1赋初值

TL1=0xfd; //根据规定给定时器T1赋初值

TR1=1; //启动定时器T1

REN=1; //允许接收

139

while(1)

{

P1=Receive(); //将接收到的数据送P1口显示

}

}

/*****************************************************************数码管

显示*****数码管显示******************** 数码管显示****************数

码管显示***************************************************/

//实例60:用LED数码显示数字5

#include // 包含51单片机寄存器定义的头文件

void main(void)

{

P2=0xfe; //P2.0引脚输出低电平,数码显示器接通电源准备点亮

P0=0x92; //让P0口输出数字"5"的段码92H

140

}

//实例61:用LED数码显示器循环显示数字0~9

#include // 包含51单片机寄存器定义的头文件

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

函数功能:延时函数,延时一段时间

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

void delay(void)

{

unsigned char i,j;

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

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

;

}

141

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

函数功能:主函数

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

void main(void)

{

unsigned char i;

unsigned char

Tab[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

//数码管显示0~9的段码表,程序运行中当数组值不发生变化时,

//前面加关键字code ,可以大大节约单片机的存储空间

P2=0xfe; //P2.0引脚输出低电平,数码显示器DS0接通电源工作

while(1) //无限循环

{

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

142

code

{

P0=Tab[i]; //让P0口输出数字的段码92H

delay(); //调用延时函数

}

}

}

//实例62:用数码管慢速动态扫描显示数字"1234"

#include // 包含51单片机寄存器定义的头文件

void delay(void) //延时函数,延时一段时间

{

unsigned char i,j;

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

for(j=0;j<250;j++)

143

;

}

void main(void)

{

while(1) //无限循环

{

P2=0xfe; //P2.0引脚输出低电平,DS0点亮

P0=0xf9; //数字1的段码

delay();

P2=0xfd ; //P2.1引脚输出低电平,DS1点亮

P0=0xa4; //数字2的段码

delay();

P2=0xfb; //P2.2引脚输出低电平,DS2点亮

144

P0=0xb0; //数字3的段码

delay();

P2=0xf7; //P2.3引脚输出低电平,DS3点亮

P0=0x99; //数字4的段码

delay();

P2=0xff;

}

}

//实例63:用LED数码显示器伪静态显示数字1234

#include // 包含51单片机寄存器定义的头文件

void delay(void) //延时函数,延时约0.6毫秒

{

unsigned char i;

145

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

;

}

void main(void)

{

while(1) //无限循环

{

P2=0xfe; //P2.0引脚输出低电平,DS0点亮

P0=0xf9; //数字1的段码

delay();

P2=0xfd ; //P2.1引脚输出低电平,DS1点亮

P0=0xa4; //数字2的段码

delay();

146

P2=0xfb; //P2.2引脚输出低电平,DS2点亮

P0=0xb0; //数字3的段码

delay();

P2=0xf7; //P2.3引脚输出低电平,DS3点亮

P0=0x99; //数字4的段码

delay();

P2=0xff;

}

}

//实例64:用数码管显示动态检测结果

#include // 包含51单片机寄存器定义的头文件

#include //包含随机函数rand()的定义文件

unsigned char i; //记录中断次数

147

unsigned int x; //随机检测的数据

unsigned char code

Tab[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //数码管显示0~9

的段码表

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

函数功能:快速动态扫描延时,延时约0.9毫秒

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

void delay(void)

{

unsigned int i;

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

;

}

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

148

函数功能:4位数的数码显示器显示

入口参数:k

出口参数:无

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

void display(unsigned int k)

{

P2=0xfe; //即P2=1111 1110B,P2.0引脚输出低电平,数码显示器DS0接通

电源

P0=Tab[k/1000]; //显示千位

delay();

P2=0xfd ; //即P2=1111 1101B,P2.1引脚输出低电平,数码显示器DS1接通电

P0=Tab[(k%1000)/100]; //显示百位

delay();

149

P2=0xfb; //即P2=1111 1011B,P2.2引脚输出低电平,数码显示器DS2接通电

P0=Tab[(k%100)/10]; //显示十位

delay();

P2=0xf7; //即P2=1111 0111B ,P2.3引脚输出低电平,数码显示器DS3接通电

P0=Tab[k%10];//显示个位

delay();

P2=0xff; //关闭所有显示器

}

void main(void) //主函数

{

TMOD=0x01; //使用定时器T0

TH0=(65536-46083)/256; //将定时器计时时间设定为46083×1.085微秒

=50000微秒=50毫秒

150

TL0=(65536-46083)%256;

EA=1; //开启总中断

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

TR0=1; //启动定时器T0开始运行

while(1)

{

display(x); //调用检测结果的显示程序

}

}

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

函数功能:定时器T0的中断服务程序

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

151

void Time0(void) interrupt 1 using 1

{

TR0=0; //关闭定时器T0

i++; //每来一次中断,i自加1

if(i==20) //够20次中断,即1秒钟进行一次检测结果采样

{

x=rand()/10; //随机产生一个从0到32767的整数,再将其除以10,获得

一个随机4位数,模拟检测结果

i=0; //将i清0,重新统计中断次数

}

TH0=(65536-46083)/256; //重新给计数器T0赋初值

TL0=(65536-46083)%256;

TR0=1; //启动定时器T0

152

}

//实例65:数码秒表设计

#include // 包含51单片机寄存器定义的头文件

unsigned char

Tab[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

//数码管显示0~9的段码表

unsigned char int_time; //记录中断次数

unsigned char second; //储存秒

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

函数功能:快速动态扫描延时,延时约0.6毫秒

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

void delay(void)

{

unsigned char i;

153

code

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

;

}

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

函数功能:显示秒

入口参数:k

出口参数:无

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

void DisplaySecond(unsigned char k)

{

P2=0xfb; //P2.6引脚输出低电平, DS6点亮

P0=Tab[k/10]; //显示十位

delay();

154

P2=0xf7; //P2.7引脚输出低电平, DS7点亮

P0=Tab[k%10]; //显示个位

delay();

P2=0xff; //关闭所有数码管

}

void main(void) //主函数

{

TMOD=0x01; //使用定时器T0

TH0=(65536-46083)/256; //将定时器计时时间设定为46083×1.085微秒

//=50000微秒=50毫秒

TL0=(65536-46083)%256;

EA=1; //开启总中断

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

155

TR0=1; //启动定时器T0开始运行

int_time=0; //中断次数初始化

second=0; //秒初始化

while(1)

{

DisplaySecond(second); //调用秒的显示子程序

}

}

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

//函数功能:定时器T0的中断服务程序

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

void interserve(void ) interrupt 1 using 1

{

156

TR0=0; //关闭定时器T0

int_time ++; //每来一次中断,中断次数int_time自加1

if(int_time==20) //够20次中断,即1秒钟进行一次检测结果采样

{

int_time=0; //中断次数清0

second++; //秒加1

if(second==60)

second =0; //秒等于60就返回0

}

TH0=(65536-46083)/256; //重新给计数器T0赋初值

TL0=(65536-46083)%256;

TR0=1; //启动定时器T0

}

157

//实例66:数码时钟设计

#include // 包含51单片机寄存器定义的头文件

unsigned char Tab[ ]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

//control shape

unsigned char port[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};

unsigned char int_time ; //中断次数计数变量

unsigned char second; //秒计数变量

unsigned char minute; //分钟计数变量

unsigned char hour; //小时计数变量

/////////////////////////////////////////////////////

void delay(void) //延时函数,延时约0.6ms

{

unsigned char j;

for(j=0;j<200;j++)

158

;

}

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

函数功能:显示秒的子程序

入口参数:s

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

void DisplaySecond(unsigned char s)

{

P2=0xbf; //P2.6引脚输出低电平, DS6点亮

P0=Tab[s/10]; //显示十位

delay();

P2=0x7f; //P2.7引脚输出低电平, DS7点亮

P0=Tab[s%10]; //显示个位

159

delay();

P2=0xff; //关闭所有数码管

}

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

函数功能:显示分钟的子程序

入口参数:m

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

void DisplayMinute(unsigned char m)

{

P2=0xf7; // P2.3引脚输出低电平, DS3点亮

P0=Tab[m/10];//显示个位

delay();

P2=0xef; // P2.4引脚输出低电平, DS4点亮

160

P0=Tab[m%10];

delay();

P2=0xdf; //P2.5引脚输出低电平, DS5点亮

P0=0xbf; //分隔符“-”的段码

delay();

P2=0xff; //关闭所有数码管

}

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

函数功能:显示小时的子程序

入口参数:h

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

void DisplayHour(unsigned char h)

{

161

P2=0xfe; //P2.0引脚输出低电平, DS0点亮

P0=Tab[h/10]; //显示十位

delay();

P2=0xfd; //P2.1引脚输出低电平, DS1点亮

P0=Tab[h%10]; //显示个位

delay();

P2=0xfb; //P2.2引脚输出低电平, DS2点亮

P0=0xbf; //分隔符“-”的段码

delay();

P2=0xff; //关闭所有数码管

}

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

函数功能:主函数

162

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

void main(void)

{

TMOD=0x01; //使用定时器T0

EA=1; //开中断总允许

ET0=1; //允许T0中断

TH0=(65536-46083)/256; //定时器高八位赋初值

TL0=(65536-46083)%256; //定时器低八位赋初值

TR0=1;

int_time=0; //中断计数变量初始化

second=0; //秒计数变量初始化

minute=0; //分钟计数变量初始化

163

hour=0; //小时计数变量初始化

while(1)

{

DisplaySecond(second); //调用秒显示子程序

delay();

DisplayMinute(minute); //调用分钟显示子程序

delay();

DisplayHour(hour);

delay();

}

}

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

164

函数功能:定时器T0的中断服务子程序

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

void interserve(void ) interrupt 1 using 1 //using Time0

{

int_time++;

if(int_time==20)

{

int_time=0; //中断计数变量清0

second++; //秒计数变量加1

}

if(second==60)

{

second=0; //如果秒计满60,将秒计数变量清0

165

minute++; //分钟计数变量加1

}

if(minute==60)

{

minute=0; //如果分钟计满60,将分钟计数变量清0

hour++; //小时计数变量加1

}

if(hour==24)

{

hour=0; //如果小时计满24,将小时计数变量清0

}

TH0=(65536-46083)/256; //定时器重新赋初值

TL0=(65536-46083)%256;

166

}

//实例67:用LED数码管显示计数器T0的计数值

#include //包含51单片机寄存器定义的头文件

sbit S=P3^2 ; //将S位定义为P3.2引脚

unsigned char Tab[ ]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

//段码表

unsigned char x;

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

函数功能: 延时约0.6ms

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

void delay(void)

{

unsigned char j;

167

for(j=0;j<200;j++)

;

}

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

函数功能:显示计数次数的子程序

入口参数:x

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

void Display(unsigned char x)

{

P2=0xf7; //P2.6引脚输出低电平,DS6点亮

P0=Tab[x/10]; //显示十位

delay();

P2=0xfb; //P2.7引脚输出低电平,DS7点亮

168

P0=Tab[x%10]; //显示个位

delay();

}

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

函数功能:主函数

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

void main(void)

{

EA=1; //开放总中断

EX0=1; //允许使用外中断

IT0=1; //选择负跳变来触发外中断

x=0;

169

while(1)

Display(x);

}

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

函数功能:外中断T0的中断服务程序

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

void int0(void) interrupt 0 using 0 //外中断0的中断编号为0

{

x++;

if(x==100)

x=0;

}

170

//实例68:静态显示数字“59”

#include //包含51单片机寄存器定义的头文件

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

函数功能:主函数

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

void main(void)

{

P0=0x92; //将数字5的段码送P0口

P1=0x90; //将数字9的段码送P1口

while(1) //无限循环,防止程序跑飞

;

}

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

键盘控制*********键盘控制*************** ***************键盘控制****

171

*****键盘控制**** ******

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

//实例69:无软件消抖的独立式键盘输入实验

#include // 包含51单片机寄存器定义的头文件

sbit S1=P1^4; //将S1位定义为P1.4引脚

sbit LED0=P3^0; //将LED0位定义为P3.0引脚

void main(void) //主函数

{

LED0=0; //P3.0引脚输出低电平

while(1)

{

if(S1==0) //P1.4引脚输出低电平,按键S1被按下

LED0=!LED0; //P3.0引脚取反

}

172

}

//实例70:软件消抖的独立式键盘输入实验

#include // 包含51单片机寄存器定义的头文件

sbit S1=P1^4; //将S1位定义为P1.4引脚

sbit LED0=P3^0; //将LED0位定义为P3.0引脚

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

函数功能:延时约30ms

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

void delay(void)

{

unsigned char i,j;

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

for(j=0;j<100;j++)

173

;

}

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

函数功能:主函数

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

void main(void) //主函数

{

LED0=0; //P3.0引脚输出低电平

while(1)

{

if(S1==0) //P1.4引脚输出低电平,按键S1被按下

{

delay(); //延时一段时间再次检测

174

if(S1==0) // 按键S1的确被按下

LED0=!LED0; //P3.0引脚取反

}

}

}

//实例71:CPU控制的独立式键盘扫描实验

#include //包含51单片机寄存器定义的头文件

sbit S1=P1^4; //将S1位定义为P1.4引脚

sbit S2=P1^5; //将S2位定义为P1.5引脚

sbit S3=P1^6; //将S3位定义为P1.6引脚

sbit S4=P1^7; //将S4位定义为P1.7引脚

unsigned char keyval; //储存按键值

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

175

函数功能:流水灯延时

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

void led_delay(void)

{

unsigned char i,j;

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

for(j=0;j<250;j++)

;

}

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

函数功能:软件消抖延时

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

void delay30ms(void)

176

{

unsigned char i,j;

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

for(j=0;j<100;j++)

;

}

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

函数功能:正向流水点亮LED

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

void forward(void)

{

P3=0xfe; //第一个灯亮

led_delay();

177

P3=0xfd; //第二个灯亮

led_delay();

P3=0xfb; //第三个灯亮

led_delay();

P3=0xf7;

led_delay();

P3=0xef;

led_delay();

P3=0xdf;

led_delay();

P3=0xbf;

led_delay();

P3=0x7f;

//第四个灯亮

//第五个灯亮

//第六个灯亮

//第七个灯亮

//第八个灯亮

178

led_delay();

P3=0xff;

P3=0xfe; //第一个灯亮

led_delay();

}

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

函数功能:反向流水点亮LED

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

void backward(void)

{

P3=0x7f; //第八个灯亮

led_delay();

P3=0xbf; //第七个灯亮

179

led_delay();

P3=0xdf; //第六个灯亮

led_delay();

P3=0xef;

led_delay();

P3=0xf7;

led_delay();

P3=0xfb;

led_delay();

P3=0xfd;

led_delay();

P3=0xfe;

led_delay();

//第五个灯亮

//第四个灯亮

//第三个灯亮

//第二个灯亮

//第一个灯亮

180

}

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

函数功能:关闭所有LED

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

void stop(void)

{

P3=0xff;

}

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

函数功能:闪烁点亮LED

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

void flash(void)

{

181

P3=0xff;

led_delay();

P3=0x00;

led_delay();

}

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

函数功能:键盘扫描子程序

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

void key_scan(void)

{

if((P1&0xf0)!=0xf0) //第一次检测到有键按下

{

delay30ms(); //延时20ms再去检测

182

if(S1==0) //按键S1被按下

keyval=1;

if(S2==0) //按键S2被按下

keyval=2;

if(S3==0) //按键S3被按下

keyval=3;

if(S4==0) //按键S4被按下

keyval=4;

}

}

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

函数功能:主函数

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

183

void main(void) //主函数

{

keyval=0; //按键值初始化为0,什么也不做

while(1)

{

key_scan();

switch(keyval)

{

case 1:forward();

break;

case 2:backward();

break;

case 3:stop();

184

break;

case 4: flash();

break;

}

}

}

//实例72:定时器中断控制的独立式键盘扫描实验

#include //包含51单片机寄存器定义的头文件

sbit S1=P1^4; //将S1位定义为P1.4引脚

sbit S2=P1^5; //将S2位定义为P1.5引脚

sbit S3=P1^6; //将S3位定义为P1.6引脚

sbit S4=P1^7; //将S4位定义为P1.7引脚

unsigned char keyval; //储存按键值

185

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

函数功能:流水灯延时

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

void led_delay(void)

{

unsigned char i,j;

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

for(j=0;j<250;j++)

;

}

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

函数功能:软件消抖延时

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

186

void delay20ms(void)

{

unsigned char i,j;

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

for(j=0;j<60;j++)

;

}

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

函数功能:正向流水点亮LED

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

void forward(void)

{

P3=0xfe; //第一个灯亮

187

led_delay();

P3=0xfd; //第二个灯亮

led_delay();

P3=0xfb;

led_delay();

P3=0xf7;

led_delay();

P3=0xef;

led_delay();

P3=0xdf;

led_delay();

P3=0xbf;

led_delay();

//第三个灯亮

//第四个灯亮

//第五个灯亮

//第六个灯亮

//第七个灯亮

188

P3=0x7f; //第八个灯亮

led_delay();

P3=0xff;

P3=0xfe; //第一个灯亮

led_delay();

}

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

函数功能:反向流水点亮LED

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

void backward(void)

{

P3=0x7f; //第八个灯亮

led_delay();

189

P3=0xbf; //第七个灯亮

led_delay();

P3=0xdf; //第六个灯亮

led_delay();

P3=0xef;

led_delay();

P3=0xf7;

led_delay();

P3=0xfb;

led_delay();

P3=0xfd;

led_delay();

P3=0xfe;

//第五个灯亮

//第四个灯亮

//第三个灯亮

//第二个灯亮

//第一个灯亮

190

led_delay();

}

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

函数功能:关闭所有LED

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

void stop(void)

{

P3=0xff; //关闭8个LED

}

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

函数功能:闪烁点亮LED

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

void flash(void)

191

{

P3=0xff; //关闭8个LED

led_delay();

P3=0x00; //点亮8个LED

led_delay();

}

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

函数功能:主函数

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

void main(void) //主函数

{

TMOD=0x01; //使用定时器T0的模式1

EA=1; //开总中断

192

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

TR0=1; //启动定时器T0

TH0=(65536-1000)/256; //定时器T0赋初值,每计数200次(217微秒)发送

一次中断请求

TL0=(65536-1000)%256; //定时器T0赋初值

keyval=0; //按键值初始化为0,什么也不做

while(1)

{

switch(keyval)

{

case 1:forward();

break;

case 2:backward();

break;

193

case 3:stop();

break;

case 4: flash();

break;

}

}

}

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

函数功能:定时器T0的中断服务子程序

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

void Time0_serve(void) interrupt 1 using 1

{

if((P1&0xf0)!=0xf0) //第一次检测到有键按下

194

{

delay20ms(); //延时20ms再去检测

if(S1==0) //按键S1被按下

keyval=1;

if(S2==0) //按键S2被按下

keyval=2;

if(S3==0) //按键S3被按下

keyval=3;

if(S4==0) //按键S4被按下

keyval=4;

}

TH0=(65536-1000)/256;

TL0=(65536-1000)%256;

195

}

//实例73:独立式键盘控制的4级变速流水灯

#include // 包含51单片机寄存器定义的头文件

unsigned char speed; //储存流水灯的流动速度

sbit S1=P1^4; //位定义S1为P1.4

sbit S2=P1^5; //位定义S2为P1.5

sbit S3=P1^6; //位定义S3为P1.6

sbit S4=P1^7; //位定义S4为P1.7

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

函数功能:延时20ms的子程序

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

void delay20ms(void) //3*i*j+2*i=3*100*60+2*100=20000μs=20ms;

{

196

unsigned char i,j;

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

for(j=0;j<60;j++)

;

}

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

函数功能:延时可调子程序

入口参数:x

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

void delay(unsigned char x)

{

unsigned char k;

for(k=0;k

197

delay20ms();

}

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

函数功能:主函数

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

void main(void)

{

TMOD=0x02; //使用定时器T0的模式2

EA=1; //开总中断

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

TR0=1; //定时器T0开始运行

TH0=256-200; //定时器T0赋初值,每200微妙来1次中断请求

TL0=256-200;

198

speed=3; //默认流水灯流水点亮延时20ms×3=60ms

while(1)

{

P3=0xfe;

delay(speed);

P3=0xfd;

delay(speed);

P3=0xfb;

delay(speed);

P3=0xf7;

delay(speed);

P3=0xef;

delay(speed);

//第一个灯亮

//调用延时可调子程序

//第二个灯亮

//第三个灯亮

//第四个灯亮

//第五个灯亮

199