如何用单片机做一个简单的倒计时器

如何用单片机做一个简单的倒计时器,第1张

51单片机实现数码管99秒倒计时,其实很简单,就是使用定时器中断来实现。目的就是学习怎样用单片机实现倒计时,从而实现一些延时控制类的东西,99秒只是一个例子,你完全可以做出任意倒计时如10秒倒计时程序。定时器定时时间计算公式:初值X=M(最大计时)-计数值。

初值,换算成十六进制,高位给TH0,低位给TL0,如果用定时器0的话。

M(最大计时)如果是16位的,就是2的16次方,最大定时,65535 微秒,实现1秒定时,可以通过定时10毫秒,然后100次改变一次秒值即可。10*100毫秒=1S

计数值:你要定时多长时间,如果定时1毫秒,就是1000微秒,(单位为微秒),如果定时10毫秒,就是10000(微秒),当然,最大定时被定时器本身位数限制了,最大2的16次方(16位定时计数器),只能定时65.535毫秒。定时1S当然不可能1S定时器中断。

下面为实现99秒倒计时C语言源程序

/*了解定时器,这样的话,就可以做一些基本的实验了,如定时炸d~~,10秒后打开关闭继电器*/

/*数码管,12M晶振*/

#include <reg52.h>

#define uchar unsigned char

sbit p11=P1^1 //连的是继电器。。

code unsigned char tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}

uchar shiwei

uchar gewei

void delay(unsigned int cnt)

{

while(--cnt)

}

void main()

{

TMOD|=0x01 /*定时器016位定时器X=65535-10000(10毫秒)=55535=D8F0(十六进制)定时10ms

*/

TH0=0xd8

TL0=0xf0

IE=0x82 //这里是中断优先级控制EA=1(开总中断),ET0=1(定时器0允许中断),这里用定时器0来定时

TR0=1 //开定时器0

while(1)

{

P0=shiwei //99的十位

P2=0 //99的个位,

delay(300) //动态扫描数码管延时

P0=gewei

P2=1

delay(300)

}

}

void tim(void) interrupt 1 using 1//定时器0中断

{

static uchar second=99,count //99只是一个数,可以任意改,因为这里只学习怎样实现倒计时

TH0=0xd8 //定时10毫秒

TL0=0xf0

count++

if(count==100) //10毫秒定时,10*100=1000(毫秒)=1秒

{

count=0

second--

if(second==0)

{

p11=0 //这里让继电器动作,当然动作之后,要复位才能等下次倒定时再动作。

second=99 //回到99再循环来,当然,可以做其他的控制,

}

shiwei=tab[second/10] //数码管10位

gewei=tab[second%10] //数码管个位

}

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

要求是能进行9999秒倒计时

用C语言实现

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

#include<at89X51.h>

#define uchar unsigned char

#define uint unsigned int

uchar num_qian,num_bai,num_shi,num_ge//定义千位,百位,十位,个位。

uint time//要显示的时间0~9999

uint tcnt//计时单元

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

//以下是端口定义

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

sbit key_qian=P1^0//按键"千加1"

sbit key_bai =P1^2//按键"百加1"

sbit key_shi =P1^4//按键"十加1"

sbit key_ge =P1^6//按键"个加1"

sbit laba =P3^1//喇叭

void delay(unsigned int z)//1毫秒延时子函数

{

unsigned int x,y

for(x=zx>0x--)

for(y=110y>0y--)

}

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

//以下是七段数码管驱动程序

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

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

** 功能描述: 中断接受字符串驱动程序

**占用引脚资源 P30

**占用系统资源 串口中断;中断向量4

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

#define DUAN P0

#define WEI P2

unsigned char code dispcode[]=

{

0x3F,/*0*/

0x06,/*1*/

0x5B,/*2*/

0x4F,/*3*/

0x66,/*4*/

0x6D,/*5*/

0x7D,/*6*/

0x07,/*7*/

0x7F,/*8*/

0x6F,/*9*/

}//共阴段码表

//0,1,2,3,4,5,6,7,8,9,A,b,C,c,d,E,F,NULL,-

uchar code dispbitcode[]=

{0xef,0xdf,0xbf,0x7f}//共阴位码表

uchar dispbuf[4],dispcount//开辟四个显示缓冲区

void ledinit()/***初始化子函数,定时器0刷新显示内容***/

{

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

TH0=(65536-5000)/256//定时器16位模式

TL0=(65536-5000)%256//溢出时间:5ms

TR0=1//开启定时器0

ET0=1//使能定时器0

EA=1 //系统使能

}

void leddisp()//固定显示某些数字

{

dispbuf[0]=time/1000

dispbuf[1]=time%1000/100

dispbuf[2]=time%100/10

dispbuf[3]=time%10

}

void keytest()//按键检测程序

{

if(!key_qian)//如果千位按键

{

delay(5)//5毫秒延时去抖

if(!key_qian)//如果千位按键的确按下了

{

num_qian++//千位数字加一

while(!key_qian)//等待按键松开

}

time+=num_qian*1000//千位数字加1

}

if(!key_bai)//如果百位按键

{

delay(5)//5毫秒延时去抖

if(!key_bai)//如果百位按键的确按下了

{

num_bai++//百位数字加一

while(!key_bai)//等待按键松开

}

time+=num_bai*100//百位数字加1

}

if(!key_shi)//如果十位按键

{

delay(5)//5毫秒延时去抖

if(!key_shi)//如果十位按键的确按下了

{

num_shi++//千位数字加一

while(!key_shi)//等待按键松开

}

time+=num_shi*10//十位数字加1

}

if(!key_ge)//如果千位按键

{

delay(5)//5毫秒延时去抖

if(!key_ge)//如果个位按键的确按下了

{

num_qian++//千位数字加一

while(!key_ge)//等待按键松开

}

time+=num_ge//个位数字加1

}

}

void main()//主程序

{

ledinit()//数码管中断初始化,定时器0刷新显示内容

while(1)//大循环

{

if((!key_qian)||(!key_bai)||(!key_shi)||(!key_ge))//如果四个按键中的任何一个被按下

keytest()//执行按键检测程序

leddisp()//不断的刷新显示内容

}

}

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

//以下是定时器0刷新数码管显示内容驱动程序

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

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

** 功能描述: 七段数码管驱动程序

**占用引脚资源: 数码管段选,数码管位选

**占用系统资源T0

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

void t0(void) interrupt 1 //using 0

{

TH0=(65536-5000)/256 //5ms中断

TL0=(65536-5000)%256//16位定时器模式

WEI=0xff//关位选

DUAN=dispcode[dispbuf[dispcount]]//段选

WEI=dispbitcode[dispcount]//开位选

dispcount++

if(dispcount==5)

dispcount=0

tcnt++ //计数个数加一

if(tcnt==5*200)//满足1S了

{

tcnt=0//计数个数归零

time--//时间减一

if(time==0)//时间

while(1)

}

if(time<10)//时间小于10

laba=~laba//声音报警

}

这是9999秒倒计时的

C语言

#include

#define

uint

unsigned

int

#define

uchar

unsigned

char

sbit

p27=P2^7//数码管位选端定义

uchar

c,i

//数码管译码表

unsigned

char

code

NumDecode[]

=

{

0XC0,//0

0XF9,//1

0XA4,//2

0XB0,//3

0X99,//4

0X92,//5

0X82,//6

0XF8,//7

0X80,//8

0X90,//9

}

void

main()

{

i=0//10秒计时设置

c=0//中断次数计数

p27=1//数码管位选端关闭

TMOD=1//设置定时器0为工作方式1

TH0=(65536-46080)/256//定时50ms高8位求模

TL0=(65536-46080)%256//定时50ms低8位求余

EA=1//开总中断

ET0=1//定时器0中断

TR0=1//启动定时器0

while(1)

{

if(c==20)//50ms中断20次

{

c=0

i++//倒计时总数每秒减1

}

if(i<10)

{

p27=0//数码管位选选通

P0=NumDecode[i]//显示数据

}

else

//循环计时设置

{

i=0

}

}

}

void

timer0()

interrupt

1//定时器0中断入口

{

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

TL0=(65536-46080)%256

c++//中断次数

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/11051298.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-13
下一篇 2023-05-13

发表评论

登录后才能评论

评论列表(0条)

保存