陶灿灿1162510124单片机课程设计报告.docx
《陶灿灿1162510124单片机课程设计报告.docx》由会员分享,可在线阅读,更多相关《陶灿灿1162510124单片机课程设计报告.docx(22页珍藏版)》请在冰豆网上搜索。

陶灿灿1162510124单片机课程设计报告
河海大学物联网工程学院(常州)
单片机课程设计报告
题目定时闹钟
专业自动化
学号1162510124
授课班号黄皎
学生姓名陶灿灿
指导教师黄皎
摘要
本课程设计的目的是利用动态数码管作为显示器,K1-K2作为输入按键,蜂鸣器作为声音输出,利用定时器作为时间的基准制作一个定时闹钟,并能够通过串口在PC上设定时间和闹钟【关键字】定时器动态数码管按键串口通信
ABSTRACT
Thiscourseisdesignedtousedynamicdigitaltubeasdisplay,K1-K2astheinputbuttons,buzzerasthesoundoutput,usethetimerasatimereferencetomakearegularalarmclock,andthroughtheserialportsettingtimeandalarmonthePC
【Keywords】TIMERLEDKEY
SERIALCOMMUNICATION
目录
1系统设计…………………………………………4
1.1单片机最小系统电路…………………………………………4
1.2外围电路………………………………………………………5
2实验结果及讨论…………………………………6
2.1利用定时器让数码管显示时间……………………………7
2.2加入按键……………………………………………………8
2.3加入串口……………………………………………………9
3结论………………………………………………10
4参考文献…………………………………………11
5附录………………………………………………12
1.系统设计
1.1单片机最小系统电路
主芯片:
电源及下载程序:
复位及时钟:
1.2外围电路
独立按键:
数码管
Usb转串口(因为笔记本机上没有串口):
2.实验结果及讨论
2.1利用定时器让数码管显示时间
2.1.1静态LED数码管工作原理
如图6.1所示是8段LED数码管的结构示意图,从图中可以看出,一个8段LED数码管由8个发光二极管组成。
其中7个长条形的发光管排列成“日”字形,另一个小圆点形的发光管在显示器的右下角作为显示小数点用。
这种组合的显示器可以显示0-9十个数字及部分英文字母。
7段数码管(不控制小数点)的原理也很简单,它由7个发光二极管组成。
这7个发光二极管有一个公共端,必须接GND(共阴极数码管)或者VCC(共阳极数码管);对7个二极管的另一端进行控制,相应的就能控制它们的亮暗。
不同的亮暗组合就产生了数字0~F的显示效果。
若希望数码管显示某个数字,只要给数码管的7个段选接口送相应的译码信号即可。
(程序请看附录)
2.1.251定时器操作
部分程序如下
voidTimer0_init()
{
TMOD|=0x01;
TH0=(65536-51200)/256;
TL0=(65536-51200)%256;
EA=1;
ET0=1;
TR0=1;
}
dula=1;//displaythethirthseg
P0=table[dis_buf[2]];
dula=0;
P0=0xff;
wela=1;
P0=0xfb;
wela=0;
delay
(1);
2.1.3阶段结果
数码管能正常实现闹钟的时间显示
2.2加入按键
部分程序如下
voidkey_scan()
{
ucharset_clock_flag;
if(K1==0)//changetime
{
delay(50);
if(K1==0)
{
while(!
K1);
hour++;
if(hour==24)
hour=0;
}
}
阶段结果:
按下相应的按键,能正确更改时间和设置闹钟.
2.2加入串口
2.2.1波特率计算
2.2.2串口操作
部分程序如下
voidserial_ser()interrupt4
{
if((num==0)&&(SBUF==0x01))
{
num=1;
change_flag=1;
clock_flag=0;
ES=0;
TI=1;
changtime_guide();
while(!
TI);
TI=0;
ES=1;
}
整体结果:
利用串口调试工具,能在pc机上正确更改时间和设置闹钟.
3结论
做东西要有耐心和毅力,可能这个课程设计太简单,还花费不了太多时间,但如果你静下心来认真去找些资料学习一下,比如看一下和你题目相关的郭天祥老师的51单片机的视频教程(很好,推荐给大家,他写的那本书《新概念51单片机C语言教程》写得也很好,大家不妨买来看看),或者在网上找一些与你题目相关的资料学习一下等等,你静下心来好好看看视频或者程序或者资料,一会就做完了。
你只要静下心来学学做做,肯定不会比别人慢的,这也是我参加比赛或者做电子设计行业的一些心得。
我可以毫不掩饰地告诉大家,我在做这个课程设计时,就是去再把郭天祥老师视频中讲定时器和串口设置步骤看了下(只看设置步骤,因为之前学的时候就看过不少,就十分钟左右的事,因为这个没记住,也不需要记,用的时候再去查就行),然后我就开始从上到下一句一句地在我的电脑上写程序了,我之前自己做过闹钟,所以写起来比较顺利,但是我还是按照由简单到难,先实现数码管正常显示1s的计数,然后加入按键的操作,最后加上串口的操作,三个多小时后就将全部代码调试完毕。
希望学弟学妹们珍惜大学的生活,即使之前没有学过单片机,一点也没有弄过其他电子啥的,那就从现在开始,现在开始肯定不会晚的,只要你对自己有足够的信心,你肯定在几年后会取得很大的成就。
退出太多浮躁,归于平静,你一定会成功的。
耶鲁大学校训中有一句话:
要对自己无条件自信,即使是在做错事的时候。
学弟学妹们不妨借鉴。
4参考文献
【1】郭天祥:
新概念51单片机C语言教程,电子工业出版社,2008年10月
【2】谭浩强:
C程序设计(第二版),清华大学出版社,1999年12月
5附录
1.全部程序:
#include
#include//usethefunctionprintf()init
#defineucharunsignedchar
#defineuintunsignedint
sbitdula=P2^6;
sbitwela=P2^7;
sbitK1=P3^4;//K1键调整小时
sbitK2=P3^5;//K2键调整分钟
sbitK3=P3^6;//K3键设定闹钟
sbitbeep=P2^3;
ucharcount=0,second=45,minute=0;hour=12,num=0,clock_hour=12,clock_minute=1;//countisusedtocountto1s,numisusedtocountdatareceivedfrompc
ucharhour_temp,minute_temp,change_flag,clock_flag;
uchardis_buf[6];
uchartemp[7];//temp[7]isusedtosavedatareceivedfrompc
ucharcodetable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
voidTimer0_init();
voiddisplay();//usedtodisplaycurrenttime
voiddelay(ucharms);
voidkey_scan();
voidserial_init();
voiddisplay_temp();
voidmenu();
voidchangtime_guide();
voidmain()
{
Timer0_init();
serial_init();
menu();
while
(1)
{
key_scan();
display();
}
}
voidmenu()
{
ES=0;
TI=1;
printf("\nMENU:
\n");
printf("Input01:
Changtime\n");
printf("Input02:
Setclock\n");
while(!
TI);
TI=0;
ES=1;
}
voidchangtime_guide()
{
printf("\nPleaseentersixnumbersinhexlikethistochangecurrenttime:
\n");
printf("eg:
000901050105=09:
15:
15\n");
}
voidsetclock_guide()
{
printf("\nPleaseentersixnumbersinhexlikethistosetyourclock:
\n");
printf("eg:
020202020202=22:
22:
22\n");
}
voidTimer0_init()
{
TMOD|=0x01;
TH0=(65536-51200)/256;
TL0=(65536-51200)%256;
EA=1;
ET0=1;
TR0=1;
}
voidTimer0_ser()interrupt1
{
TH0=(65536-51200)/256;
TL0=(65536-51200)%256;
count++;
if(count==18)
{
count=0;
second++;
if(second==60)
{
second=0;
minute++;
if(minute==60)
{
minute=0;
hour++;
if(hour==24)
hour=0;
}
}
}
}
voiddisplay()
{
dis_buf[0]=hour/10;
dis_buf[1]=hour%10;
dis_buf[2]=minute/10;
dis_buf[3]=minute%10;
dis_buf[4]=second/10;
dis_buf[5]=second%10;
dula=1;//displaythefirstseg
P0=table[dis_buf[0]];
dula=0;
P0=0xff;
wela=1;
P0=0xfe;
wela=0;
delay
(1);
dula=1;//displaythesecondseg
P0=table[dis_buf[1]];
dula=0;
P0=0xff;
wela=1;
P0=0xfd;
wela=0;
delay
(1);
dula=1;//displaythethirthseg
P0=table[dis_buf[2]];
dula=0;
P0=0xff;
wela=1;
P0=0xfb;
wela=0;
delay
(1);
dula=1;//displaythefourthseg
P0=table[dis_buf[3]];
dula=0;
P0=0xff;
wela=1;
P0=0xf7;
wela=0;
delay
(1);
dula=1;//displaythefifthseg
P0=table[dis_buf[4]];
dula=0;
P0=0xff;
wela=1;
P0=0xef;
wela=0;
delay
(1);
dula=1;//displaythesixthseg
P0=table[dis_buf[5]];
dula=0;
P0=0xff;
wela=1;
P0=0xdf;
wela=0;
delay
(1);
if((hour==clock_hour)&&(minute==clock_minute))
beep=0;//iftheclocktimecomes,beepison
else
beep=1;
}
voiddelay(ucharms)
{
uchari;
while(ms--)
{
for(i=0;i<120;i++);
}
}
voidkey_scan()
{
ucharset_clock_flag;
if(K1==0)//changetime
{
delay(50);
if(K1==0)
{
while(!
K1);
hour++;
if(hour==24)
hour=0;
}
}
elseif(K2==0)
{
delay(50);
if(K2==0)
{
while(!
K2);
minute++;
if(minute==60)
minute=0;
}
}
elseif(K3==0)
{
delay(50);
if(K3==0)
{
while(!
K3);
hour_temp=hour;
minute_temp=minute;
set_clock_flag=1;
while(set_clock_flag)
{
if(K1==0)//changetime
{
delay(50);
if(K1==0)
{
while(!
K1);
hour_temp++;
if(hour_temp==24)
hour_temp=0;
}
}
elseif(K2==0)
{
delay(50);
if(K2==0)
{
while(!
K2);
minute_temp++;
if(minute_temp==60)
minute_temp=0;
}
}
if(K3==0)
{
delay(50);
if(K3==0)
{
clock_hour=hour_temp;
clock_minute=minute_temp;
set_clock_flag=0;
}
}
display_temp();
}
}
}
}
voiddisplay_temp()
{
dis_buf[0]=hour_temp/10;
dis_buf[1]=hour_temp%10;
dis_buf[2]=minute_temp/10;
dis_buf[3]=minute_temp%10;
dis_buf[4]=second/10;
dis_buf[5]=second%10;
dula=1;//displaythefirstseg
P0=table[dis_buf[0]];
dula=0;
P0=0xff;
wela=1;
P0=0xfe;
wela=0;
delay
(1);
dula=1;//displaythesecondseg
P0=table[dis_buf[1]];
dula=0;
P0=0xff;
wela=1;
P0=0xfd;
wela=0;
delay
(1);
dula=1;//displaythethirthseg
P0=table[dis_buf[2]];
dula=0;
P0=0xff;
wela=1;
P0=0xfb;
wela=0;
delay
(1);
dula=1;//displaythefourthseg
P0=table[dis_buf[3]];
dula=0;
P0=0xff;
wela=1;
P0=0xf7;
wela=0;
delay
(1);
dula=1;//displaythefifthseg
P0=table[dis_buf[4]];
dula=0;
P0=0xff;
wela=1;
P0=0xef;
wela=0;
delay
(1);
dula=1;//displaythesixthseg
P0=table[dis_buf[5]];
dula=0;
P0=0xff;
wela=1;
P0=0xdf;
wela=0;
delay
(1);
}
voidserial_init()
{
TMOD|=0x20;//定时器1工作于8位自动重载模式,用于产生波特率
TH1=0xfd;//波特率9600
TL1=0xfd;
TR1=1;
REN=1;
SM0=0;//设定串口工作方式
SM1=1;
ES=1;//允许串口中断
}
voidserial_ser()interrupt4
{
if((num==0)&&(SBUF==0x01))
{
num=1;
change_flag=1;
clock_flag=0;
ES=0;
TI=1;
changtime_guide();
while(!
TI);
TI=0;
ES=1;
}
elseif((num==0)&&(SBUF==0x02))
{
num=1;
change_flag=0;
clock_flag=1;
ES=0;
TI=1;
setclock_guide();
while(!
TI);
TI=0;
ES=1;
}
elseif((change_flag==1)&&(num!
=0))
{
P1=SBUF;
temp[num]=SBUF;
num++;
if(num==7)
{
hour=(temp[1]<<3)+(temp[1]<<1)+temp[2];
minute=(temp[3]<<3)+(temp[3]<<1)+temp[4];
second=(temp[5]<<3)+(temp[5]<<1)+temp[6];
num=0;
menu();
}
}
elseif(clock_flag==1)
{
P1=SBUF;
temp[num]=SBUF;
num++;
if(num==7)
{
clock_hour=(temp[1]<<3)+(temp[1]<<1)+temp[2];
clock_minute=(temp[3]<<3)+(temp[3]<<1)+temp[4];
num=0;
menu();
}
}
RI=0;
}