单片机定时器时钟
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
思路
1.硬件准备。备齐所需硬件。
2.软件模拟或开发板演示。
3.软件编写。
4.问题提出与解决。
5.焊接电路。
一、硬件准备
1.四个按键。用于调时、分、秒,一个备用。
2.单片机一片。STC。
3.1602液晶电路。1个液晶屏,1个10K电阻,1个10欧电阻,1个可变电阻。
4.排阻,10K。
5.晶振电路。含1个晶振、2个30pF电容。
6.复位电路。含1个按键、1个10K电阻,1个1K电阻,1个10uF电容。
7.电源电路。电源接口、1个1K电阻,1个发光二极管,1个10uF电容。
购买:
10个按键,10个30pF电容,10个发光二极管,10个10uF电容,10个1K电阻,10个10K 电阻。
二、开发板模拟
1.初步设计:按直觉感受下设计过程,感知到存在的问题,以便提高关注度。
1)显示初始时间:给定初始显示值,如12:34:52,分别使用1、2、4、5、7、8数码管显示。2)时间递增:用计时器计时,秒60则分进1,分60则时进1,时24则归零。
3)调时按键:用四个独立按键分别调时、分、秒,留一个备用。
4)复位归零:按复位按钮,则全部归零。
2.过程实施:根据直觉设想,分别实现模块功能并实际验证与修改
1)自由显示数码管:参照现有程序,阅读理解后直接拷贝。
①共阳极数码管如下图:
静态显示时,每个数码管需要1组8个I/O口,而实际需要六个数码管,显然不够。译码器可以解决该问题。
②译码器实现动态显示数码管。
译码器三个输入端的8种组合,可以有8个输出端。这样单片机的3个I/O口就可以完成一个数码管显示。但是,要同时显示两个数码管,一个译码器是不可以解决的,这就需要两个译码器并能控制其通断,这就需要额外的I/O口。为解决此问题,下面提出一个规划:功能:6个单片机I/O口,最多能同时显示8个数码管,这就需要9个译码器。
方法:3个单片机口用于控制1个译码器,这样就可以有8个接口,用于控制其它8个译码器通断,另外3个单片机口用于同时提供给8个译码器数值,而谁要显示,由1个译码器的输出口控制。另外给予适当延时,以实现动态显示。
问题:这样就需要9个译码器,硬件需求比较大。假设能控制数码管的接口,这样1个译码器就够了。
③多个数码管动态显示。
1个74HC138译码器,用于控制共阴数码管的位选取;1个74HC573锁存器,用于提供数码管数值。控制开断时间,可实现多个数码管动态显示。原理图如下:
原理简介:数码管共阴极位选由74HC138译码器控制,数据端由74HC573锁存器控制,单片机P0口控制锁存器数据端。译码器输出互斥值以决定哪个数码管显示,依次循环来动态显示数码管。P0口在每次循环赋予不同值,通过位选以传递给对应的数码管。另外,也可以不用译码器,用P2口直接作位选控制。
2)程序编写:编写时钟显示程序,下载到开发板显示时钟。
①显示初始时间:12-34-52
建立一个数组,给8个数码管分别赋予对应值。赋值给P0口,通过锁存器传递给数码管;再通过译码器以控制位选依次循环以动态显示。小问题:1. 每个数值对应的16进制码是多少?(可根据已有程序查询)2. 译码器动态位选时有没有次序要求?(理论上应没有,实验时加以关注)
程序主体如下:
//数码管数值代码0-9
unsigned char code Disp_Tab[] =
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40}; //段码控制
//建立数组,存储赋给P0口以传递到数码管的数值
Ledout[0]=Disp_Tab[1]; //值为1
Ledout[1]=Disp_Tab[2]; //值为2
Ledout[2]=Disp_Tab[10]; //值为-
Ledout[3]=Disp_Tab[4]; //值为4
Ledout[4]=Disp_Tab[6; //值为6
Ledout[5]=Disp_Tab[10]; //值为-
Ledout[6]=Disp_Tab[3]; //值为3
Ledout[7]=Disp_Tab[8]; //值为8
//循环依次将数值传递到数码管,再利用位选端逐次显示。注意,每个值只能对应一个位选,否则会出现混乱
for( i=0; i<8; i++)
{
LE = 0; //输出使能,锁存器不输出数据
P0 = LedOut[7-i]; //硬件数码管为从右到左
LE = 1; //输出使能,锁存器将8位数据一口吐出
P2 = dispbit[i]; //使用查表法进行位选
delay(150); //扫描间隔时间太长会数码管会有闪烁感
}
LE = 0; //锁存器不输出数据
②按秒计时。两种解决方案:一是递增整数,通过求余分别赋值到时分秒;二是进位法,秒到60分增1,分到60时增1。计时方法有两种:一是用延迟函数,一般不太准,但可应付作业,且程序简单;二是用定时器,相对准确,且可拓展学习范围。此处采用由简到难的顺利逐步实现,故先采用整数求余数和延迟函数。
整数求余:递增值为一整数allSCount,由延迟函数判定,约1秒递增依次,有现成程序。对60求余得秒secCount,求除得总分allMCount,secCount对10求余为秒个位,对10求除为秒十位;allMinCount再对60求余得具体分minCount,继续求余得分个位,求除得分十位;对allMCount求除60得总时allHCount,再对24求余得具体时hourCount,对10求余得时个位,求除得时十位。
程序为:
int allSCount=0;//总秒数初始为0
int secCount=allSCount%60;//得具体秒数
Ledout[0]=Disp_Tab[secCount%10];//右1数码管为秒个位
Ledout[1]=Disp_Tab[secCount%10];//右2数码管为秒十位
int allMCount=allSCount/60;//得总分钟数
int minCount=allMCount%60;//得具体分钟数
Ledout[3]=Disp_Tab[minCount%10];//右4数码管为秒个位
Ledout[4]=Disp_Tab[minCount%10];//右5数码管为秒十位
int allHCount=allMCount/60;//得总小时数
int hourCount=allHCount%24;//得具体小时数
Ledout[6]=Disp_Tab[hourCount%10];//右6数码管为秒个位
Ledout[7]=Disp_Tab[hourCount%10];//右7数码管为秒十位