方法:首先:要学会数码管的显示程序
然后:按键的 *** 作,注意软件的消抖(具体的是延时,10ms左右)。
假设有k1~停表,k2~复位,k3~继续运行
先说停表和继续运行的
停表:如果k1按下,TR0=0;
继续运行:如果k3按下,TR0=1;
复位:直接用硬件复位单片机或者k2按下,数据清零。
要实现数据的循环:只要定时器计数到最大值时,再把最小值赋给它!
#include<reg52h>
#define uchar unsigned char
#define uint unsigned int
sbit led_1s=P1^1;
sbit led_1min=P1^2;
uint flag1=0,flag2=0;
void main()
{
TMOD=0X00; //设置工作方式
TH0=(8192-4670)/32;//装初值 晶振频率为110952MHz 5ms
TL0=(8192-4670)/32;
EA=1; //开总中断
ET0=1; //开定时器0中断
TR0=1; //启动定时器0
while(1)
{
if(flag1==200)
{
led_1s=~led_1s;
flag1=0;
flag2++;
if(flag2==60)
{
led_1min=~led_1min;
flag2=0;
}
}
}
}
/
5ms定时
/
void T0_time() interrupt 1
{
TH0=(8192-4670)/32;//重装初值
TL0=(8192-4670)/32;
flag1++;
}
刚写的,亲测可用
#include "reg51h"
sfr AUXR = 0x8e; //如果是用的AT89C51,把这句删了
sbit led=P1^0; //定义LED为P10,可以改为其他IO
unsigned char jishi;
void Timer0Init(void)//50毫秒@12000MHz
{
AUXR &= 0x7F;//定时器时钟12T模式
TMOD &= 0xF0;//设置定时器模式
TL0 = 0xB0;//设置定时初值
TH0 = 0x3C;//设置定时初值
TF0 = 0;//清除TF0标志
TR0 = 1;//定时器0开始计时
EA=1; //开总中断
}
void main()
{
Timer0Init(); //初始化定时器
while(1);
}
void tm0_isr() interrupt 1 //50毫秒中断一次
{
jishi++;
if(jishi>10) //中断十次之后
{
jishi=0; //重置计时
led=!led; //取反LED状态。
}
}
/
//p10波形为:
//1、10ms为周期的方波或持续的高、低电平(与flag、p10初始值有关),持续2秒。
//2、持续的高、低电平或10ms为周期的方波(与flag、p10初始值有关),持续2秒。
//3、重复1、2步骤。
/
#include
unsigned
int
t02s;
unsigned
char
t05ms;
bit
flag;
void
main(void)
{
tmod=0x01;
//初始化定时器。
//可以对照单片机pdf相应章节,按位对比。
//此处设置定时器0工作于“16
位定时器/
计数器,tl0、th0
全用”模式。
th0=(65536-500)/256;
//初始化定时/计数器高字节。
tl0=(65536-500)%256;
//初始化。。。。。。低字节。
tr0=1;
//启动定时器0。
//以下两句开启定时器中断,缺一不可。
et0=1;
//允许定时器0中断。
ea=1;
//开启全局中断。
while(1);
//循环,整个程序交由定时中断控制。
}
//此处为定时器中断子程序,每次定时器溢出,进入此段程序。
//根据参数定义,每5ms中断一次。
//定时器中断后,计数不停止,但是需要重新初始化定时/计数器。
void
t0(void)
interrupt
1
using
0
{
//重新“初始化定时/计数器”高、低字节。
th0=(65536-500)/256;
tl0=(65536-500)%256;
//每次中断,t02s
加
1。
t02s++;
//增加400次后(5ms
×
400
=
2s),flag标志取反。
if(t02s==400)
{
t02s=0;
flag=~flag;
}
//若中断时flag标志为0,p10口取反。
if(flag==0)
{
p1_0=~p1_0;
}
}
单片机中通过中断的方式来调用定时器。
具体的调用方式可以参考通过如下程序:
程序功能:利用定时器进行定时,实现每秒中led闪烁一次
#include<reg52h>sbit led = P0^0;
unsigned int num;
void main(void)
{
TMOD = 0x00; // 工作方式0
TH0 = (8192 - 5000) / 32; // 12M晶振下定时5ms
TL0 = (8192 - 5000) % 32;
EA = 1; // 开总中断
ET0 = 1; // 开定时器中断
TR0 = 1; // 启动定时器
while(1)
{
if(num == 200) // 定时1秒钟到
{
num = 0; // 计数器清零
led = ~led; // led灯取反,实现1秒闪烁一次
}
}
}
void timer() interrupt 1 // 定时器1工作与方式0
{
TH0 = (8192 - 5000) / 32; // 重装初值
TL0 = (8192 - 5000) % 32;
num++; // 计数器加1
}
#include <reg52h>
#define uint unsigned int
#define uchar unsigned char
sbit dula=P2^6; //段选
sbit wela=P2^7; //位选
uchar shi,ge,num1,num2; //变量
uchar code table[]={0x3f,0x06,0x5b,0x4f, //共阴极字型码
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
void delay(uint x) //延时子程序
{
uint i,j;
for(i=0;i<x;i++)
for(j=0;j<120;j++);
}
void init()
{
TMOD=0x01; //设置定时器0的工作方式
TH0=(65536-50000)/256; //装初值
TL0=(65536-50000)%256;
EA=1; //开总中断
ET0=1; //开定时器0中断
TR0=1; //启动定时器0
}
void display() //显示子程序
{
dula=1;
P0=table[ge]; //送段选数据
dula=0;
P0=0xff; //送位选数据前关闭所有显示
wela=1;
P0=0xfe; //送位选数据
wela=0;
delay(5); //延时
dula=1;
P0=table[shi];
dula=0;
P0=0xff;
wela=1;
P0=0xfd;
wela=0;
delay(5);
}
void main()
{
init();
while(1)
{
display();
}
}
void timer() interrupt 1
{
TH0=(65536-50000)/256; //重装初值
TL0=(65536-50000)%256;
num1++;
if(num1==20) //到了20次,1秒时间到
{
num1=0; //清0重新计数
num2++;
if(num2==60)
num2=0;
P1=0x00;
delay(500);
P1=0xff;
shi=num2/10; //把一个2位数分离后分别送数码管显示
ge=num2%10; //十位和个位
}
}
试了的,可以放心,采纳吧!
//定时器中断初始化
void init()
{
TMOD=0x02;//方式2
TH0=6;
TL0=6;
EA=1;
ET0=1;
TR0=1;
}
//中断函数
void time() interrupt 1
{
t++;
if(t==3686) //1s到了
m++,t=0;//m=2就是两秒了
}
1秒钟t就要加到3686,01秒t要加到多少,根据比例就算得出了,其他的也一样。时间算得出,然后在这段时间内做什么就很简单了。
以上就是关于51单片机的定时器程序,c语言编写,使用内部定时器设计一个三位秒表 (秒,十秒,分),显示秒位的变动,全部的内容,包括:51单片机的定时器程序,c语言编写,使用内部定时器设计一个三位秒表 (秒,十秒,分),显示秒位的变动,、单片机小白跪求大佬 帮忙做两个程序,用c语言程序做 一个是定时器的,两个灯。一个秒闪烁。一个分闪烁、用c语言编写,单片机LED灯并用定时器延时,每隔0.5秒使LED依次点亮等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)