3步教你如何用51单片机制作秒表

发布时间:2023-10-12  

和很多朋友一样,在学51单片机的过程中我们肯定会涉及到制作一个秒表,牵涉到把单片机的多个部分组合起来使用,这对于我们初学者来说可能显得有些困难,我同大家一样,百思不得其解,最后头都弄大了才把这个秒表制作出来,为了给以后的朋友们一些思路,一些参考,所以在这里我把自己制作的整个详细过程整理出来供大家参考。我调试出来是没有问题的,各方面都稳定运行,由于我水平有限,中间可能会有不对的地方,欢迎大家指正,我们一起学习,一起进步!


我将分为三个部分来介绍:1.整体思路,2.硬件电路方面,3.软件编程方面。


1、整体思路

利用51单片机制作秒表时,我介绍精确到十分位(即0.1s)的制作,并让其拥有启动,暂停,复位三个功能。

用到的单片机部分:定时器部分,独立按键的检测与应用,数码管的显示,并结合一些简单的程序即可实现。

用5位数码管来进行显示,分别显示秒的十分位,秒的个位,秒的十位,分的个位,分的十位。用定时器定时50ms,2个定时器中断即是0.1s,即秒的十分位,20个定时器中断即是1s,60个1s即是1分钟,通过程序将5位数码管的值分离出来,并进行显示。这就是我在数码管显示方面的思路,如果不是太清楚,结合我下面软件编程方面的程序来看你可能就会明白,我会在那部分做详细介绍,看完了可能你就懂了。

利用独立按键设置启动/暂停键和清零键,利用独立按键的检测,若启动/暂停按键按下,秒表则启动或者暂停,按下复位键,秒表清零复位。我在程序后面全都有注释,不用担心。看完你就会明白了。

这是我制作的的流程图:

“ms100”表示秒的十分位,"s"表示秒的个位,“s1”表示秒的十位,“min”表示分的个位,“min1”表示分的十位。

“cnt”表示秒的计数位,即多少个一秒,定时满一秒加1,“minu”表示分的计数位,即多少个一分钟,一分钟加1,

这个流程图提供了大致思路,要结合下面的程序部分一起看。可能有些简陋,请多多包涵!

看起来是不是好简单?有木有?请继续往下看。

2、硬件电路方面

每个人的硬件可能都不一样,(哪些控制数码管的位选,哪些控制数码管的段选,哪些控制独立按键等等),大家在自己制作过程中都要仔细考虑,我在这里就用我自己的硬件进行介绍。

这是我的数码管的电路图:(将J12用杜邦线接到对应的P0口,将J16用杜邦线接到对应的P1口)

位选端我用P1口控制,段选端我用P0口控制。在图中我已标明秒的个位s,秒的十位s1,分的个位min,分的十位min1所对应的数码管。该数码管是共阴极。

秒的十分位我用的是另一个共阳数码管。我用P3口控制该数码管的段选,其图如下:

而独立按键我用的P2^7控制“启动/暂停键”,P2^6控制复位键:电路图如下:(将JP5通过杜邦线接到P3口)

硬件电路基本上就是这些,由于分和秒之间要用小数点分隔开,所以分的个位对应的数码管的段码要用带小数点的段码,其余的数码管则不用。

硬件方面是为看懂软件程序做准备,下面我们就开始我们的软件程序方面吧!

3、软件程序方面

#include

#defineucharunsignedchar

#defineuintunsignedint

#definePIN0P0//数码管段选端

#definePIN1P1//数码管位选端

#definePIN3P3//十分位数码管的段码端

sbitstart=P2^7;//启动/暂停按钮

sbitreset=P2^6;//复位按钮

uintcnt=0;//1s的次数的计数值

uintnum=0;//进入中断次数的计数值(一次50ms)

uintnum1=0;//0.1s的次数的计数值

ucharcodetable[]={0x3f,0x06,0x5b,

0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};

//不带小数点的共阴极数码管段码0-9

ucharcodetable1[]={0xbf,0x86,

0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};

//带小数点的共阴极数码管段码0-9

charcodetable2[]={0xc0,0xf9,0xa4,

0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

//不带小数点的共阳极数码管段码0-9

voidDisplay(uintw,uinta,uintb,uintc,uintd);//声明显示函数

voidInitTimer0();//声明定时器初始化函数

voidDelayms(uintx);//声明延时函数

voidmain()

{

uintms100=0;//秒的十分位

uints,s1,min,min1,minu=0;

//依次是秒的个位,秒的十位,分的个位,分的十位

InitTimer0();//初始化定时器

while(1)//进入死循环

{

if(start==0)//检测启动/暂停键是否按下

Delayms(20);//延时消抖

{

if(start==0)//消抖之后再次检测

{

TR0=!TR0;//定时器的控制位取反

while(!start);//等待按键释放

}

}

if(reset==0)//检测复位键是否按下

{

Delayms(20);//延时消抖

if(reset==0)//消抖之后再次检测

{

num=0;

num1=0;//进入中断次数值清0

ms100=0;//十分位的计数值清0

cnt=0;//秒的计数值清0

minu=0;//分的计数值清0

while(!reset);//等待按键释放

}

}

if(num1>=2)//检测是否达到0.1s,(两个50ms)

{

num1=0;//进入中断次数值清零

ms100++;//秒的十分位的计数值加1

if(ms100>=10)//若秒的十分位计数值达到10

{

ms100=0;//清零秒的十分位的计数值

num1=0;//进入中断次数值置0

}

}

if(num>=20)//判断计时时间是否达到1s(20个50ms)

{

num=0;//进入中断次数值置0

cnt++;//秒的计数值加1

if(cnt>=60)//判断是否达到60s

{

cnt=0;//若达到60s,将秒的计数值置零

minu++;//分的计数值加1

if(minu>=60)//判断是否达到60分钟,一般秒表是用不到60分的,这是为了程序的严谨性

{

TR0=!TR0;//达到60分钟则关闭定时器并清零所有的计数值

num1=0;

num=0;

ms100=0;

cnt=0;

minu=0;

}

}

}

s=cnt%10;//从秒的计数值里面分离秒的个位

s1=cnt/10;//从秒的计数值里面分离秒的十位

min=minu%10;//从分的计数值里面分离分的个位

min1=minu/10;//从分的计数值里面分离分的十位

Display(ms100,s,s1,min,min1);//显示这5个数

}

}

voidInitTimer0()//定时器初始化函数

{

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

TH0=(65536-45872)/256;//装初值(定时50ms),晶振11.0592MHz

TL0=(65536-45872)%256;

EA=1;//打开总中断

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

TR0=0;//先不要启动定时器

}

voidTIMER0()interrupt1//定时器中断服务函数

{

TH0=(65536-45872)/256;//重装初值

TL0=(65536-45872)%256;

num++;//让进入中断次数值加1,用于判断是否达到1s

num1++;//让进入中断次数值加1,用于判断是否达到0.1s

}

voidDelayms(uintx)//延时xms

{

uinti,j;

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

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

}

voidDisplay(uintw,uinta,uintb,uintc,uintd)//定义显示函数

{

PIN3=table2[w];//秒的十分位的段选

Delayms(5);

PIN0=table[a];//秒的个位的段选

PIN1=0x7f;//秒的个位的位选

Delayms(5);

PIN0=table[b];//秒的十位的段选

PIN1=0xbf;//秒的十位的位选

Delayms(5);

PIN0=table1[c];//分的个位的段选(带小数点)

PIN1=0xdf;//分的个位的位选

Delayms(5);

PIN0=table[d];//分的十位的段选

PIN1=0xef;//分的十位的位选

Delayms(5);

}

由于在打字时可能不小心会弄错一丁点程序,我都是一个字母一个字母手打的,所以请大家理解思路即可,根据这个思路自己去写,这样得到的知识才是属于自己的。毕竟 “读别人的故事,悟自己的人生”。

下面来几张实物图给大家看一下我这个秒表的实际效果。

编译结果:

烧写进单片机的效果:(没有按启动按钮之前)

按了启动按钮之后,秒表将会自动开始计时,由于无法演示动态过程,只能在中间按下暂停键给大家看看效果:

按下复位键后:

由于我用的是一个比较完整的51开发板,所以里面有很多部分,大家只需要注意观察数码管部分就好。

下面再来一个完整的图:

结束语

至此,利用51单片机制作的秒表就已经完成了!若是文章中有什么不懂的地方或者是自己在制作过程中遇到什么问题都可以联系我,或者给我留言,我一定竭尽全力帮助大家!我们一起学习,一起进步!希望大家都能在看完这篇文章后自己动手成功制作出一个秒表,祝愿大家学好单片机!当然,由于自身水平有限,文章中肯定会存在错误或者是考虑不周的的地方,恳请不吝赐教!谢谢大家!


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>