产品选型

单片机秒表 4位 用单片机设计秒表,需要的程序是什么?

小编 2024-11-26 产品选型 23 0

用单片机设计秒表,需要的程序是什么?

秒表

单片机也有中断功能,它也会中断单片机主程序正常运行。今天设计的秒表是利用单片机内部资源——定时/计数器中断,前面讲过延时1秒(s),是让单片机空耗一段时间,并且延时时间不是精确的,但是定时器中断获得时间单位就比较精确,精确程度与单片机外接晶振质量有关。

常见的单片机单片机一共有5个中断,即外部中断0、外部中断1、定时/计数中断0、定时/计数中断1、串口中断。

一、制作一个秒表

.程序设计

#include<reg52.h>//头文件

#define uchar unsigned char//宏定义

#define uint unsigned int

uchar table []={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};//共阴数码管数组

uchar num,num1,shi,ge;//定义变量

void delay(uchar a)//延时函数

{

uint i,j;

for(j=a;j>0;j--)

for(i=110;i>0;i--);

}

void display(uchar shi,uchar ge)//显示函数

{

P0=table[shi];

P1=0XFE;//1111 1110选中数码管第一位

delay(5);

P0=table[ge];

P1=0XFd;//1111 1101选中数码管第二位

delay(5);

}

void t0init()//初始化

{

TMOD=0X01;//0000 0001//定时器0工作方式1

TH0=0X3C;//装入初值,50毫秒

TL0=0XB0;//装入初值

EA=1;//打开总中断开关

ET0=1;//打开定时器0中断开关

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

}

void main()//主函数

{

t0init();

while(1)//无限循环

{

display(shi,ge);

}

}

void timer0()interrupt 1 //中断函数

{

TH0=0X3C;//装入初值

TL0=0XB0;//装入初值

num++;//变量累加

if(num==20)//1秒

{

num=0;

num1++;

shi=num1/10;//取十位

ge=num1%10;//取个位

if(num1==60)

{

num1=0;

}

}

}

3.程序解释

(1)采用定时器中断必要的语句。

TMOD=0X01;

TMOD是选择定时器工作方式。0X01是定时/计数中断0工作方式1,如果是0X10是定时/计数1工作方式1。

TH0=0X3C;//装入初值

TL0=0XB0;//装入初值

如果单片机外接晶振是12M,它的时钟周期是1/12μs(微妙),12个时钟周期是一个机器周期即1μs,定时/计数0工作方式1,最大值能定时65536μs(2的16次方),约等于65ms。如果需要定时50ms,也就是计数不是从0开始,而是从15536(65536-50000)开始,15536(十进制)换算为16进制为3CB0,即“TH0=0X3C;TL0=0XB0;”,需要计时1s,只需程序中断20次。

EA=1;//打开总中断开关

EA是总开关,好比总电闸。

ET0=1;//打开定时器0中断开关。它是定时器0的开关,好比客厅总电源开关。

TR0=1;//启动定时器0。启动定时器0好比客厅的吊灯开关。

以上语句需要写在主函数中,或者作为函数,在主函数中调用。

(2)void display(uchar shi,uchar ge)//显示函数显示部分用函数形式体现,在主函数循环调用。

(3)中断函数

既然中断产生了,那么中断以后做什么?

void timer0()interrupt 1 //中断函数

{

做什么工作;

}

“timer0”自己起的名字,代表定时/计数0中断,“interrupt”不能写错,关键是它后面的数字千万也不能搞错。中断源与序号如表3-14-1。需要注意,采用工作方式1,需要在中断函数中重新装入初值。

51单片机学习19-简易秒表

前面几篇我们说到了 LED灯,数码管,按键等内容,按键和数码管组合可以设计出简易秒表。

硬件组成:单片机最小系统+数码管显示电路+3个按键

功能:一个开始键,一个暂停键,一个复位键。数码管显示的精度是00:00--59:99

仿真图:

程序:

程序内容比较多,详细的参考源代码

源代码:

#include<reg52.h> //头文件

#define uint unsigned int

#define uchar unsigned char

uchar qian;

uchar bai;

uchar shi;

uchar ge;

//共阴数码管0-F 编码表

uchar smg_dm[]={0x3f,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,};

uchar smg_dm1[]={0xbf,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,}; //0. 1. 2.----9.段码表

uchar smg_wm[]={0Xef,0Xdf,0xbf,0x7f}; //位选

uchar Display_buffer[4]={0,0,0,0}; //数码管显示缓存

sbit key1=P2^0; //开始键

sbit key2=P2^1; //暂停键

sbit key3=P2^2; //复位键

void delay_ms(uint z) //延时子程序

{

uint x,y;

for(x=z;x>0;x--)

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

}

void key(void)

{

if(key1==0)

{

delay_ms(10);

if(key1==0)

{

TR0=1;

}

while(!key1);

}

if(key2==0)

{

delay_ms(10);

if(key2==0)

{

TR0=0;

}

while(!key1);

}

if(key3==0)

{

delay_ms(10);

if(key3==0)

{

TR0=0;qian=0;bai=0;shi=0;ge=0;

}

while(!key1);

}

}

void msg_display(void)

{

uchar i;

Display_buffer[0]=qian;

Display_buffer[1]=bai;

Display_buffer[2]=shi;

Display_buffer[3]=ge;

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

{

if(i==1)

{

P2=smg_wm[i];//选位码

P1=smg_dm1[Display_buffer[i]];//选段码

delay_ms(5);

//P2=0XFF; //消影仿真这句加不加都一样

}

else

{

P2=smg_wm[i];//选位码

P1=smg_dm[Display_buffer[i]];//选段码

delay_ms(5);

//P2=0XFF; //消影

}

}

}

void main()

{

TMOD=0X01;

TH0=(65536-10000)/256;

TL0=(65536-10000)%256;

EA=1;

ET0=1;

while(1)

{

key();

msg_display();

}

}

void time0() interrupt 1

{

uchar num;

TH0=(65536-10000)/256;

TL0=(65536-10000)%256;

num++;

if(num==1)

{

num=0;

ge++;

if(ge==10)

{

ge=0;

shi++;

if(shi==10)

{

shi=0;

bai++;

if(bai==10)

{

bai=0;

qian++;

if(qian==6)

{

qian=0;

}

}

}

}

}

}

仿真结果:

相关问答

设计电子时钟 要用AT89S51 单片机 的定时器实现,用 4位 数码管...

用21134位数码管显示,用点的闪烁表示秒,就是共有52615位,7段;那么用一整个4102PIO口(8位)去对应7段数据,1653再用另外一个PIO口的部分(全部)管脚去...

ic5膜厚仪在哪看看晶振片用过几次?

ic5膜厚仪看看晶振片用过几次的方法是可从两个方面得知,一是完整型号,二是晶振实物。再者即是品牌晶振,丝印规则往往厂商品牌logo加标称频率,生产代码等信...

没接大功率电器,电表走字太快是什么原因造成的?

应"悟空小秘书"邀答!没接大功率电器,把表走字太快是什么原因造成的?1⃣️听电站的老干部讲过,过去的老式电表时代,总表与分表总和悬殊特大,当然有电损...应"悟.....

猜你喜欢