实验8051+Proteus定时计数器仿真.docx

上传人:b****7 文档编号:9940566 上传时间:2023-02-07 格式:DOCX 页数:27 大小:20.71KB
下载 相关 举报
实验8051+Proteus定时计数器仿真.docx_第1页
第1页 / 共27页
实验8051+Proteus定时计数器仿真.docx_第2页
第2页 / 共27页
实验8051+Proteus定时计数器仿真.docx_第3页
第3页 / 共27页
实验8051+Proteus定时计数器仿真.docx_第4页
第4页 / 共27页
实验8051+Proteus定时计数器仿真.docx_第5页
第5页 / 共27页
点击查看更多>>
下载资源
资源描述

实验8051+Proteus定时计数器仿真.docx

《实验8051+Proteus定时计数器仿真.docx》由会员分享,可在线阅读,更多相关《实验8051+Proteus定时计数器仿真.docx(27页珍藏版)》请在冰豆网上搜索。

实验8051+Proteus定时计数器仿真.docx

实验8051+Proteus定时计数器仿真

实验:

8051+Proteus定时/计数器仿真

一、定时器控制单只LED

/*名称:

定时器控制单只LED

说明:

LED在定时器的中断例程控制下不断闪烁。

*/

#include

#defineucharunsignedchar

#defineuintunsignedint

sbitLED=P0^0;

ucharT_Count=0;

//主程序

voidmain()

{

TMOD=0x00;//定时器0工作方式0

TH0=(8192-5000)/32;//5ms定时

TL0=(8192-5000)%32;

IE=0x82;//允许T0中断

TR0=1;

while

(1);

}

//T0中断函数

voidLED_Flash()interrupt1

{

TH0=(8192-5000)/32;//恢复初值

TL0=(8192-5000)%32;

if(++T_Count==100)//0.5s开关一次LED

{

LED=~LED;

T_Count=0;

}

}

二、TIMER0控制流水灯

/*名称:

TIMER0控制流水灯说明:

定时器控制P0、P2口的LED滚动显示,本例未使用中断函数。

*/

#include

#include

#defineucharunsignedchar

#defineuintunsignedint

//主程序

voidmain()

{

ucharT_Count=0;

P0=0xfe;

P2=0xfe;

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

TH0=(65536-40000)/256;//40ms定时

TL0=(65536-40000)%256;

TR0=1;//启动定时器

while

(1)

{

if(TF0==1)

{

TF0=0;

TH0=(65536-40000)/256;//恢复初值

TL0=(65536-40000)%256;

if(++T_Count==5)

{

P0=_crol_(P0,1);

P2=_crol_(P2,1);

T_Count=0;

}

}

}

}

三、定时器控制4个LED滚动闪烁

/*名称:

定时器控制4个LED滚动闪烁

说明:

4只LED在定时器控制下滚动闪烁。

*/

#include

#defineucharunsignedchar

#defineuintunsignedint

sbitB1=P0^0;

sbitG1=P0^1;

sbitR1=P0^2;

sbitY1=P0^3;

uinti,j,k;

//主程序

voidmain()

{

i=j=k=0;

P0=0xff;

TMOD=0x02;//定时器0工作方式2

TH0=256-200;//200us定时

TL0=256-200;

IE=0x82;

TR0=1;//启动定时器

while

(1);

}

//T0中断函数

voidLED_Flash_and_Scroll()interrupt1

{

if(++k<35)return;//定时中断若干次后执行闪烁

k=0;

switch(i)

{

case0:

B1=~B1;break;

case1:

G1=~G1;break;

case2:

R1=~R1;break;

case3:

Y1=~Y1;break;

default:

i=0;

}

if(++j<300)return;//每次闪烁持续一段时间

j=0;

P0=0xff;//关闭显示

i++;//切换到下一个LED

}

四、T0控制LED实现二进制计数

/*名称:

T0控制LED实现二进制计数

说明:

本例对按键的计数没有使用查询法,没有使用外部中断函数,没有使用定时或计数中断函数。

而是启用了计数器,连接在T0引脚的按键每次按下时,会使计数寄存器的值递增,其值通过LED以二进制形式显示

*/

#include

//主程序

voidmain()

{

TMOD=0x05;//定时器0为计数器,工作方式1,最大计数值65535

TH0=0;//初值为0

TL0=0;

TR0=1;//启动定时器

while

(1)

{

P1=TH0;

P2=TL0;

}

}

五、TIMER0与TIMER1控制条形LED

/*名称:

TIMER0与TIMER1控制条形LED

说明:

定时器T0定时控制上一组条形LED,滚动速度较快

定时器T1定时控制下一组条形LED,滚动速度较慢

*/

#include

#include

#defineucharunsignedchar

#defineuintunsignedint

uchartc0=0,tc1=0;

//主程序

voidmain()

{

P0=0xfe;

P2=0xfe;

TMOD=0x11;//定时器0、定时器1均工作于方式1

TH0=(65536-15000)/256;//定时器0:

15ms

TL0=(65536-15000)%256;

TH1=(65536-50000)/256;//定时器1:

50ms

TL1=(65536-50000)%256;

IE=0x8a;

TR0=1;//启动定时器

TR1=1;

while

(1);

}

//T0中断函数

voidTime0()interrupt1

{

TH0=(65536-15000)/256;//恢复定时器0初值

TL0=(65536-15000)%256;

if(++tc0==10)//150ms转换状态

{

tc0=0;

P0=_crol_(P0,1);

}

}

//T1中断函数

voidTime1()interrupt3

{

TH0=(65536-50000)/256;//恢复定时器1初值

TL0=(65536-50000)%256;

if(++tc1==10)//500ms转换状态

{

tc1=0;

P2=_crol_(P2,1);

}

}

六、10s的秒表

/*名称:

10s的秒表

说明:

首次按键计时开始,再次按键暂停,第三次按键清零。

*/

#include

#defineucharunsignedchar

#defineuintunsignedint

sbitK1=P3^7;

uchari,Second_Counts,Key_Flag_Idx;

bitKey_State;

ucharDSY_CODE[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};

//延时

voidDelayMS(uintms)

{

uchart;

while(ms--)for(t=0;t<120;t++);

}

//处理按键事件

voidKey_Event_Handle()

{

if(Key_State==0)

{

Key_Flag_Idx=(Key_Flag_Idx+1)%3;

switch(Key_Flag_Idx)

{

case1:

EA=1;ET0=1;TR0=1;break;

case2:

EA=0;ET0=0;TR0=0;break;

case0:

P0=0x3f;P2=0x3f;i=0;Second_Counts=0;

}

}

}

//主程序

voidmain()

{

P0=0x3f;//显示00

P2=0x3f;

i=0;

Second_Counts=0;

Key_Flag_Idx=0;//按键次数(取值0,1,2,3)

Key_State=1;//按键状态

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

TH0=(65536-50000)/256;//定时器0:

15ms

TL0=(65536-50000)%256;

while

(1)

{

if(Key_State!

=K1)

{

DelayMS(10);

Key_State=K1;

Key_Event_Handle();

}

}

}

//T0中断函数

voidDSY_Refresh()interrupt1

{

TH0=(65536-50000)/256;//恢复定时器0初值

TL0=(65536-50000)%256;

if(++i==2)//50ms*2=0.1s转换状态

{

i=0;

Second_Counts++;

P0=DSY_CODE[Second_Counts/10];

P2=DSY_CODE[Second_Counts%10];

if(Second_Counts==100)Second_Counts=0;//满100(10s)后显示00

}

}

七、用计数器中断实现100以内的按键计数

/*名称:

用计数器中断实现100以内的按键计数

说明:

本例用T0计数器中断实现按键技术,由于计数寄存器初值为1,因此

P3.4引脚的每次负跳变都会触发T0中断,实现计数值累加。

计数器的清零用外部中断0控制。

*/

#include

#defineucharunsignedchar

#defineuintunsignedint

//段码

ucharcodeDSY_CODE[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};

ucharCount=0;

//主程序

voidmain()

{

P0=0x00;

P2=0x00;

TMOD=0x06;//计数器T0方式2

TH0=TL0=256-1;//计数值为1

ET0=1;//允许T0中断

EX0=1;//允许INT0中断

EA=1;//允许CPU中断

IP=0x02;//设置优先级,T0高于INT0

IT0=1;//INT0中断触发方式为下降沿触发

TR0=1;//启动T0

while

(1)

{

P0=DSY_CODE[Count/10];

P2=DSY_CODE[Count%10];

}

}

//T0计数器中断函数

voidKey_Counter()interrupt1

{

Count=(Count+1)%100;//因为只有两位数码管,计数控制在100以内(00~99)

}

//INT0中断函数

voidClear_Counter()interrupt0

{

Count=0;

}

八、100000s以内的计时程序

/*名称:

100000s以内的计时程序

说明:

在6只数码管上完成0~99999.9s。

*/

#include

#include

#defineucharunsignedchar

#defineuintunsignedint

//段码

ucharcodeDSY_CODE[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};

//6只数码管上显示的数字

ucharDigits_of_6DSY[]={0,0,0,0,0,0};

ucharCount;

sbitDot=P0^7;

//延时

voidDelayMS(uintms)

{

uchart;

while(ms--)for(t=0;t<120;t++);

}

//主程序

voidmain()

{

uchari,j;

P0=0x00;

P3=0xff;

Count=0;

TMOD=0x01;//计数器T0方式1

TH0=(65536-50000)/256;//50ms定时

TL0=(65536-50000)%256;

IE=0x82;

TR0=1;//启动T0

while

(1)

{

j=0x7f;

//显示Digits_of_6DSY[5]~Digits_of_6DSY[0]的内容

//前面高位,后面低位,循环中i!

=-1亦可写成i!

=0xff

for(i=5;i!

=-1;i--)

{

j=_crol_(j,1);

P3=j;

P0=DSY_CODE[Digits_of_6DSY[i]];

if(i==1)Dot=1;//加小数点

DelayMS

(2);

}

}

}

//T0中断函数

voidTimer0()interrupt1

{

uchari;

TH0=(65536-50000)/256;//恢复初值

TL0=(65536-50000)%256;

if(++Count!

=2)return;

Count=0;

Digits_of_6DSY[0]++;//0.1s位累加

for(i=0;i<=5;i++)//进位处理

{

if(Digits_of_6DSY[i]==10)

{

Digits_of_6DSY[i]=0;

if(i!

=5)Digits_of_6DSY[i+1]++;//如果0~4位则分别向高一位进位

}

elsebreak;//若某低位没有进位,怎循环提前结束

}

}

九、定时器控制数码管动态显示

/*名称:

定时器控制数码管动态显示

说明:

8个数码管上分两组动态显示年月日与时分秒,本例的位显示延时用定时器实现。

*/

#include

#include

#defineucharunsignedchar

#defineuintunsignedint

//段码,最后一位是“-”的段码

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

//待显示的数据:

09-12-25与23-59-58(分两组显示)

ucharcodeTable_of_Digits[][8]={{0,9,10,1,2,10,2,5},{2,3,10,5,9,10,5,8}};

uchari,j=0;

uintt=0;

//主程序

voidmain()

{

P3=0x80;//位码初值

TMOD=0x00;//计数器T0方式0

TH0=(8192-4000)/32;//4ms定时

TL0=(8192-4000)%32;

IE=0x82;

TR0=1;//启动T0

while

(1);

}

//T0中断函数控制数码管刷新显示

voidDSY_Show()interrupt1

{

TH0=(8192-4000)/32;//恢复初值

TL0=(8192-4000)%32;

P0=0xff;//输出位码和段码

P0=DSY_CODE[Table_of_Digits[i][j]];

P3=_crol_(P3,1);

j=(j+1)%8;//数组第i行的下一字节索引

if(++t!

=350)return;//保持刷新一段时间

t=0;

i=(i+1)%2;//数组行i=0时显示年月日,i=1时显示时分秒

}

十、用定时器设计的门铃

/*名称:

用定时器设计的门铃

说明:

按下按键时蜂鸣器发出叮咚的门铃声。

*/

#include

#defineucharunsignedchar

#defineuintunsignedint

sbitKey=P1^7;

sbitDoorBell=P3^0;

uintp=0;

//主程序

voidmain()

{

DoorBell=0;

TMOD=0x00;//T0方式0

TH0=(8192-700)/32;//700us定时

TL0=(8192-700)%32;

IE=0x82;

while

(1)

{

if(Key==0)//按下按键启动定时器

{

TR0=1;

while(Key==0);

}

}

}

//T0中断控制点阵屏显示

voidTimer0()interrupt1

{

DoorBell=~DoorBell;

p++;

if(p<400)//若需要拖长声音,可以调整400和800

{

TH0=(8192-700)/32;//700us定时

TL0=(8192-700)%32;

}

elseif(p<800)

{

TH0=(8192-1000)/32;//1ms定时

TL0=(8192-1000)%32;

}

else

{

TR0=0;

p=0;

}

}

十一、演奏音阶

/*名称:

演奏音阶

说明:

本例使用定时器演奏一段音阶,播放由K1控制。

*/

#include

#defineucharunsignedchar

#defineuintunsignedint

sbitK1=P1^0;

sbitSPK=P3^4;

uinti=0;//音符索引

//14个音符放在方式2下的定时寄存器(TH0,TL0)

ucharcodeHI_LIST[]={0,226,229,232,233,236,238,240,241,242,244,245,246,247,248};

ucharcodeLO_LIST[]={0,4,13,10,20,3,8,6,2,23,5,26,1,4,3};

//定时器0中断函数

voidT0_INT()interrupt1

{

TL0=LO_LIST[i];

TH0=HI_LIST[i];

SPK=~SPK;

}

//延时

voidDelayMS(uintms)

{

uchart;

while(ms--)for(t=0;t<120;t++);

}

//主程序

voidmain()

{

TMOD=0x00;//T0方式0

IE=0x82;

SPK=0;

while

(1)

{

while(K1==1);//未按键等待

while(K1==0);//等待释放

for(i=1;i<15;i++)

{

TR0=1;//播放一个音符

DelayMS(500);//播放延时

TR0=0;

DelayMS(50);

}

}

}

十二、按键控制定时器选播多段音乐

/*名称:

按键控制定时器选播多段音乐

说明:

本例内置3段音乐,K1可启动停止音乐播放,K2用于选择音乐段。

*/

#include

#include

#defineucharunsignedchar

#defineuintunsignedint

sbitK1=P1^0;//播放和停止键

sbitSPK=P3^7;//蜂鸣器

ucharSong_Index=0,Tone_Index=0;//当前音乐段索引,音符索引

//数码管段码表

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

//标准音符频率对应的延时表

ucharcodeHI_LIST[]={0,226,229,232,233,236,238,240,241,242,244,245,246,247,248};

ucharcodeLO_LIST[]={0,4,13,10,20,3,8,6,2,23,5,26,1,4,3};

//三段音乐的音符

ucharcodeSong[][50]=

{

{1,2,3,1,1,2,3,1,3,4,5,3,4,5,5,6,5,3,5,6,5,3,5,3,2,1,2,1,-1},

{3,3,3,4,5,5,5,5,6,5,3,5,3,2,1,5,6,53,3,2,1,1,-1},

{3,2,1,3,2,1,1,2,3,1,1,2,3,1,3,4,5,3,4,5,5,6,5,3,5,3,2,1,3,2,1,1,-1}

};

//三段音乐的节拍

ucharcodeLen[][50]=

{

{1,1,1,1,1,1,1,1,1,1,2,1,1,2,1,1,1,1,1,1,1,1,1,1,1,2,1,2,-1},

{1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,2,2,-1},

{1,1,2,1,1,2,1,1,1,1,1,1,1,1,1,1,2,1,1,2,1,1,1,1,1,1,1,2,1,1,2,2,-1}

};

//外部中断0

voidEX0_INT()interrupt0

{

TR0=0;//播放结束或者播放中途切换歌曲时停止播放

Song_Index=(Song_Index+1)%3;//跳到下一首的开头

Tone_Index=0;

P2=DSY_CODE[Song_Index];//数码管显示当前音乐段号

}

//定时器0中断函数

voidT0_INT()interrupt1

{

TL0=LO_LIST[Song[Song_Index][Tone_Index]];

TH0=HI_LIST[Song[Song_Index][Tone_Index]];

SPK=~SPK;

}

//延时

voidDelayMS(uintms)

{

uchart;

while(ms--)for(t=0;t<120;t++);

}

//主程序

voidmai

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 文学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1