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

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

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

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

实验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=0;

TH0=<65536-40000>/256;//恢复初值

TL0=<65536-40000>%256;

if<++T_Count==5>

{

P0=_crol_;

P2=_crol_;

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

{

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_;

}

}

//T1中断函数

voidTime1<>interrupt3

{

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

TL0=<65536-50000>%256;

if<++tc1==10>//500ms转换状态

{

tc1=0;

P2=_crol_;

}

}

六、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

{

uchart;

whilefor;

}

//处理按键事件

voidKey_Event_Handle<>

{

if

{

Key_Flag_Idx=%3;

switch

{

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

=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];

ifSecond_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=%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

{

uchart;

whilefor;

}

//主程序

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

=-1;i-->

{

j=_crol_;

P3=j;

P0=DSY_CODE[Digits_of_6DSY[i]];

ifDot=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//进位处理

{

if

{

Digits_of_6DSY[i]=0;

if

=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_;

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

if<++t!

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

t=0;

i=%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//按下按键启动定时器

{

TR0=1;

while;

}

}

}

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

voidTimer0<>interrupt1

{

DoorBell=~DoorBell;

p++;

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

{

TH0=<8192-700>/32;//700us定时

TL0=<8192-700>%32;

}

elseif

{

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

{

uchart;

whilefor;

}

//主程序

voidmain<>

{

TMOD=0x00;//T0方式0

IE=0x82;

SPK=0;

while<1>

{

while;//未按键等待

while;//等待释放

for

{

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=%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

{

uchart;

whilefor;

}

//主程序

voidmain<

展开阅读全文
相关搜索

当前位置:首页 > 总结汇报

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

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