单片机课程设计 电子时钟 12.docx
- 文档编号:5320875
- 上传时间:2023-05-08
- 格式:DOCX
- 页数:18
- 大小:120.17KB
单片机课程设计 电子时钟 12.docx
《单片机课程设计 电子时钟 12.docx》由会员分享,可在线阅读,更多相关《单片机课程设计 电子时钟 12.docx(18页珍藏版)》请在冰点文库上搜索。
单片机课程设计电子时钟12
JIANGSUUNIVERSITY
单片机原理及应用
课程设计
学院名称:
计算机科学与通信工程
专业班级:
通信工程0801
学生姓名:
学生学号:
********12
指导教师:
熊书明
2011年01月
日历时钟与键盘显示程序设计
一.设计目的:
掌握日历时钟的编程方法,了解SMBus的编程方法。
进一步掌握T0计数器的用法和中断服务的过程。
用C51语言设计一个时钟,使其有自动报时和闹铃功能,并且可以通过键盘对当前时间进行校正,可以用键盘设置闹钟时间。
二.设计要求:
1.能能在LED显示器上实现正常的时分秒计时
2.通过键盘输入当前时间,并从该时间开始计时
3.有校时、校分功能
4.有报时功能,通过指示灯表示
5.有闹时功能,闹时时间可以设定,通过指示灯表示
三.系统流程图:
四.设计和实现:
(一).键盘输入模块
1.HD7279芯片功能:
HD7279是一片具有串行接口的,可用于驱动8位共阴极式数码管(或64只独立LED)的智能显示驱动芯片,该芯片同时还可连接多达64键的键盘矩阵,单片即可完成LED显示、键盘接口的全部功能。
HD7279内部含有译码器,可直接接受BCD码或者16进制码,并同时具有两种译码方式,此外还有消隐、闪烁、左移、右移、段寻址等多种控制指令。
HD7279具有片选信号,可方便地实现多于8位的显示或多于64键的键盘接口。
2.键盘输入模块程序设计
charGetKeyValue(void)
{
charKeyValue;
if(CPT1CN&0x40)return-1;//无键按下
Send7279Byte(0x15);//发读键盘指令00010101
KeyValue=Receive7279Byte();
NOSELECT7279;//置CS高电平
returnKeyValue;
}
voidWaitKeyOff(void)
{
while(!
(CPT1CN&0x40));
}
voidinputnum(void)//i=5开始,输入数字xianshidisptime[5-i]i=5--0
{//fugeidertime[j]
charj,KeyValue,i;
i=5;
while
(1)
{
KeyValue=GetKeyValue();
WaitKeyOff();
if(((KeyValue%16)>=0)&&((KeyValue%16)<=9))//i=543210
{
disptime[5-i]=KeyValue;
if(((disptime[0]<=1)||((disptime[0]==2)&&(disptime[1]<4)))&&(disptime[2]<6)&&(disptime[4]<6))
{Send7279Byte(0xC8+i);//
Send7279Byte(KeyValue);
NOSELECT7279;
i--;
}
}
if(i<0)break;
}
for(j=0;j<3;j++)//int-char
{
dertime[j]=disptime[2*j]*10+disptime[2*j+1];
}
if(set1)
{
set1=!
set1;//设置时间
}
if(set2)
{
set2=!
set2;//设置时间
}
if((KeyValue%16)==0x0f)
{
set=!
set;
}
if(set)//起停*****
{
if((KeyValue%16)==0x0e)
{
set1=!
set1;//设置时间
}
if((KeyValue%16)==0x0d)
{
set2=!
set2;//设置闹钟
}
if(set1)//设置时间**********
{
DispLED("------",0);
inputnum();
for(j=0;j<3;j++)//int-char
{
time[j]=dertime[j];
}
}
if(set2)//设置闹钟********
{DispLED("------",0);
inputnum();
for(j=0;j<3;j++)//int-char
{
nowtime[j]=dertime[j];//nowtime[j]闹钟时间
}
}
}
else
{
switch(KeyValue%16)//校时
{
case1:
time[0]=(time[0]+1+24)%24;break;//校时加1
case2:
time[0]=(time[0]-1+24)%24;break;//校时减1
case3:
time[1]=(time[1]+1+60)%60;break;//校分加1
case4:
time[1]=(time[1]-1+60)%60;break;//校分减1
case0xd:
FlashLED(8);break;//暂停闪烁
default:
break;
}
}
}
}
}
(二)LED显示模块和闪烁模块
1.LED数码管工作原理及显示码:
图1这是一个7段两位带小数点10引脚的LED数码管
图2引脚定义
每一笔划都是对应一个字母表示DP是小数点.
数码管分为共阳极的LED数码管、共阴极的LED数码管两种。
下图例举的是共阳极的LED数码管,共阳就是7段的显示字码共用一个电源的正。
led数码管原理图示意:
图3引脚示意图
从上图可以看出,要是数码管显示数字,有两个条件:
1、是要在VT端(3/8脚)加正电源;2、要使(a,b,c,d,e,f,g,dp)端接低电平或“0”电平。
这样才能显示的。
共阳极LED数码管的内部结构原理图图4:
图4共阳极LED数码管的内部结构原理图
共阴极LED数码管的内部结构原理图:
图5共阴极LED数码管的内部结构原理图
LED数码管要正常显示,就要用驱动电路来驱动数码管的各个段码,从而显示出我们要的数位,因此根据LED数码管的驱动方式的不同,可以分为静态式和动态式两类。
A、静态显示驱动:
静态驱动也称直流驱动。
静态驱动是指每个数码管的每一个段码都由一个单片机的I/O埠进行驱动,或者使用如BCD码二-十进位*器*进行驱动。
静态驱动的优点是编程简单,显示亮度高,缺点是占用I/O埠多,如驱动5个数码管静态显示则需要5×8=40根I/O埠来驱动,要知道一个89S51单片机可用的I/O埠才32个呢。
故实际应用时必须增加*驱动器进行驱动,增加了硬体电路的复杂性。
B、动态显示驱动:
数码管动态显示介面是单片机中应用最为广泛的一种显示方式之一,动态驱动是将所有数码管的8个显示笔划"a,b,c,d,e,f,g,dp"的同名端连在一起,另外为每个数码管的公共极COM增加位元选通控制电路,位元选通由各自独立的I/O线控制,当单片机输出字形码时,所有数码管都接收到相同的字形码,但究竟是那个数码管会显示出字形,取决于单片机对位元选通COM端电路的控制,所以我们只要将需要显示的数码管的选通控制打开,该位元就显示出字形,没有选通的数码管就不会亮。
透过分时轮流控制各个LED数码管的COM端,就使各个数码管轮流受控显示,这就是动态驱动。
在轮流显示过程中,每位元数码管的点亮时间为1~2ms,由于人的视觉暂留现象及发光二极体的余辉效应,尽管实际上各位数码管并非同时点亮,但只要扫描的速度足够快,给人的印象就是一组稳定的显示资料,不会有闪烁感,动态显示的效果和静态显示是一样的,能够节省大量的I/O埠,而且功耗更低。
unsignedcharcodeBdSeg[]={
0x7e,0x30,0x6d,0x79,//0123
0x33,0x5b,0x5f,0x70,//4567
0x7f,0x7b,0x77,0x1f,//89ab
0x4e,0x3d,0x4f,0x47,//cdef
0x00,0x01};
/*
;b6
;----
;b1|b0|b5
;----small
;b2|b3|b4
;----.b7
*/
2.LED显示模块的程序设计
voidDispLED(char*DispBuf,charShowDot)//ShowDot显示小数点位
{
chari,ch;
ShowDot--;
for(i=0;i<6;i++)
{
ch=DispBuf[i];
if((ch>='a')&&(ch<='f'))
{
ch-='a';ch+=0xa;
}
if((ch>='A')&&(ch<='F'))
{
ch-='A';ch+=0xa;
}
Send7279Byte(0x90+5-i);//不译码
if(ch=='')
Send7279Byte(0x00);
else
if(ch=='-')
Send7279Byte(0x01);
else
{
if(ShowDot==i)
Send7279Byte(0x80|BdSeg[ch&0x0f]);
else
Send7279Byte(BdSeg[ch&0x0f]);
}
}
NOSELECT7279;//置CS高电平
}
if(set!
=1)
{
for(i=0;i<3;i++)//int-char
{
disptime[2*i]=time[i]/10;
disptime[2*i+1]=time[i]%10;
}
DispLED(disptime,0);//显示时间************
}
3.LED闪烁模块程序设计
voidFlashLED(unsignedcharNo)
{
chari;
Send7279Byte(0x88);//发闪烁指令
i=0x1;
while(No)//将第一位移到第No位
{
i=i<<1;
No--;
}
Send7279Byte(~i);//1闪烁
NOSELECT7279;//置CS高电平
}
(三)主函数和中断服务程序实现
1.主程序
voidmain(void)
{
charj,KeyValue;
WDTCN=0xde;
WDTCN=0xad;//关看门狗
SYSCLK_Init();//初始化时钟
Timer0_Init();//初始化定时器
PORT_Init();//初始化IO口
SPI0_Init();//初始化SPI0
CPT1CN|=0x80;//使能比较器1
REF0CN=0x03;//使能片内参考电压
DAC0CN|=0x80;//使能DAC0
DAC0H=0;DAC0L=0;
EA=1;//开中断
Delay1us(25000);//等待25ms复位时间
Send7279Byte(0xA4);//发复位指令
NOSELECT7279;
DispLED(disptime,0);//显示初始时间
while
(1)
{
KeyValue=GetKeyValue();
WaitKeyOff();
if((KeyValue%16)==0x0f)
{
set=!
set;
}
if(set)//起停*****
{
if((KeyValue%16)==0x0e)
{
set1=!
set1;//设置时间
}
if((KeyValue%16)==0x0d)
{
set2=!
set2;//设置闹钟
}
if(set1)//设置时间**********
{
DispLED("------",0);
inputnum();
for(j=0;j<3;j++)//int-char
{
time[j]=dertime[j];
}
}
if(set2)//设置闹钟********
{DispLED("------",0);
inputnum();
for(j=0;j<3;j++)//int-char
{
nowtime[j]=dertime[j];//nowtime[j]闹钟时间
}
}
}
else
{
switch(KeyValue%16)//校时
{
case1:
time[0]=(time[0]+1+24)%24;break;//校时加1
case2:
time[0]=(time[0]-1+24)%24;break;//校时减1
case3:
time[1]=(time[1]+1+60)%60;break;//校分加1
case4:
time[1]=(time[1]-1+60)%60;break;//校分减1
case0xd:
FlashLED(8);break;//暂停闪烁
default:
break;
}
}
}
}
2.中断服务程序
voidTimer0_ISR(void)interrupt1//25ms
{
inti;
TH0=0x9e;
TL0=0x58;
if(set==1)
return;
Count1ms--;//unsignedcharCount1ms会小于0,因为无符号会溢出,计数次数变大所以延迟大
if(Count1ms==0)//秒
{
Count1ms=40;
time[2]=time[2]+1;
if((time[1]==59)&&(time[2]==55))//报时功能***********
Send7279Byte(0xbf);
//闹钟功能***********
if((time[0]==nowtime[0])&&(time[1]==nowtime[1])&&(time[2]==nowtime[2]))
Send7279Byte(0xbf);
if(((time[1]*60+time[2]-nowtime[1]*60-nowtime[2])>30)&&(time[0]==nowtime[0]))
FlashLED(8);
if(time[2]>=60)//向分进位
{
time[2]=0;
time[1]=time[1]+1;
if(time[1]>=60)//向时进位
{
time[1]=0;
time[0]=time[0]+1;
if((time[1]==00)&&(time[2]==00))
FlashLED(8);
if(time[0]>=24)
{
time[0]=0;
}
}
}
if(set!
=1)
{
for(i=0;i<3;i++)//int-char
{
disptime[2*i]=time[i]/10;
disptime[2*i+1]=time[i]%10;
}
DispLED(disptime,0);//显示时间************
}
}
}
五:
运行结果和心得体会
(一)运行结果:
通过编译、链接、下载,LED显示管能够正常显示时、分、秒,时钟可以从00:
00:
00到23:
59:
59然后再到00:
00:
00。
可以正常校时。
按键盘上1按键时小时加1,按2键小时减1,按3键分钟加1,按4键分钟减1。
可以在键盘上对当前时间进行设置。
按F键,然后按E键,再从键盘键入当前时间。
当时间到**:
59:
55时LED显示管开始闪烁进行整点报时,到**:
00:
00时停止闪烁,当然可以通过按键D停止闪烁。
在键盘上先按F键,然后按D键,在从键盘键入想要设定的闹钟时间。
但时钟时间运行到设定的闹钟时间时,LED显示管连续闪烁30秒进行闹钟。
当然也可一通过按键D让其停止闪烁。
(二)心得体会:
时光飞逝,一转眼,一个学期又进尾声了,本学期的单片机课程设计也在一周内完成了。
俗话说“好的开始是成功的一半”。
说起课程设计,我认为最重要的就是做好设计的预习,认真的研究老师给的题目,选一个自己有兴趣的题目。
其次,要把老师上过的相关重点知识在温习一遍。
最后,要重视程序的模块化,修改的方便,也要注重程序的调试,掌握其方法。
虽然这次的课程设计算起来在实验室的时间只有四天,但在这四天学到了不少东西。
平时上课很多含糊的知识通过这次课程设计中有点明白了。
而且也能比较熟练的在实验平台上进行操作。
记得之前做实验时对操作平台胡乱操作,已经把设备连接好了,可重新运行时总是断开重连,断开重连,在这次课设中彻底改掉这个不好的习惯。
当然,由于我们没有上微机原理等基础课程,直接跨到单片机,基础很薄弱,在做的过程中遇到了不少困难。
最后在老师和同学的帮助下得以解决。
在这次难得的课程设计过程中我锻炼了自己的思考能力和动手能力。
通过这次课设,加强了我思考问题的完整性和实际生活联系的可行性。
再次感谢老师的辅导以及同学的帮助,是他们让我有了一个更好的认识,无论是学习还是生活,生活是实在的,要踏实走路。
课程设计时间虽然很短,但我学习了很多的东西,使我眼界打开,感受颇深。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 单片机课程设计 电子时钟 12 单片机 课程设计 电子 时钟
![提示](https://static.bingdoc.com/images/bang_tan.gif)