单片机实验报告.docx
《单片机实验报告.docx》由会员分享,可在线阅读,更多相关《单片机实验报告.docx(20页珍藏版)》请在冰豆网上搜索。
单片机实验报告
单片机实验报告
(电子时钟)
指导老师:
荆老师
班级:
电信2-082班
实验成员:
郭建凯
实验时间:
2010年6月24号
目录
1………………工作原理
2………………电路图
3………………程序的详细注解
4………………流程图
5………………缺点与不足
6………………心得体会
7………………指导老师评语
一、工作原理
通过单片机内部定时器产生一个1s的时钟信号,在程序里面把这个时钟信号处理成秒、分、时、星期、月、年。
通过if((ni%4==0&&ni%100!
=0)||(ni%400==0))runnia=1;语句判断闰年,并且对闰年的一些特别的月份进行处理,确定每个月份不同的天数。
然后将数据送到1602液晶屏进行显示。
对时钟的调节采用了比较简单的外部中断IN1和IN0进行处理,一个选择,一个进行调节,并且设置有调节指示变量“cs”显示在液晶屏上,已确定现在是调节那个变量。
二、电路图
时钟是基于ek100开发板,原理图如下:
三、程序的详细注解
#include
#include
#defineuintunsignedint
#defineucharunsignedchar
/****************************************/
sbitk5=P3^2;
sbitk6=P3^3;
sbitk1=P3^0;
sbitk2=P3^1;
sbitrs=P3^5;
sbitwr=P3^6;
sbitlcden=P3^4;
sbitdula=P2^6;
sbitwela=P2^7;
/****************************************/
//变量、中断次数、秒、分、时、延时、年、月、日、星期、闰年、星期变量、按键
uinta,n,miao,fen,shi,z,ni,y,r,xq,runnia,b,cs;
uchartable[]="2000-01-01>6<";
uchartable1[14]={"time:
00:
00:
00"};
/****************************************/
voidriqi();
//延时子程序
voiddelay(uintz)
{
uintx,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
/****************************************/
voidwrite_com(ucharcom)//1602写指令
{
P0=com;
rs=0;
lcden=0;
delay(10);
lcden=1;
delay(10);
lcden=0;
}
/****************************************/
voidwrite_date(uchardate)//1602写数据
{
P0=date;
rs=1;
lcden=0;
delay(10);
lcden=1;
delay(10);
lcden=0;
}
/****************************************/
voidinit()//初始化子程序
{
ni=0;
y=1;
r=1;
xq=1;
runnia=0;
b=5;
k1=1;
k2=1;
k5=1;
k6=1;
dula=0;
wela=0;
wr=0;
write_com(0x38);//1602初始化
delay(20);
write_com(0x0c);
delay(20);
write_com(0x06);
delay(20);
write_com(0x01);
delay(20);
shi=0;
fen=0;
miao=0;
TMOD=0x01;
TH0=(65536-49990)/256;
TL0=(65536-49990)%256;
EA=1;
ET0=1;
EX0=1;
EX1=1;
IT0=1;
IT1=1;
TR0=1;
}
/****************************************/
//显示子程序
voidxianshi()
{
riqi();
table1[12]=miao/10+'0';//取值
table1[13]=miao%10+'0';
table1[9]=fen/10+'0';
table1[10]=fen%10+'0';
table1[6]=shi/10+'0';
table1[7]=shi%10+'0';
table[2]=ni/10+'0';
table[3]=ni%10+'0';
table[5]=y/10+'0';
table[6]=y%10+'0';
table[8]=r/10+'0';
table[9]=r%10+'0';
table[12]=xq+'0';
write_com(0x80);
delay(10);
for(a=0;a<15;a++)
{
write_date(table[a]);
delay(10);
}
write_com(0xc0);
delay(10);
for(a=0;a<14;a++)
{
write_date(table1[a]);
delay(10);
}
}
/****************************************/
//主程序
voidmain()
{
init();
while
(1)
{
riqi();
xianshi();
}
}
/****************************************/
//中断程序
voidT_0()interrupt1
{
TH0=(65536-49950)/256;
TL0=(65536-49950)%256;
n++;
if(n==20)//延时1s
{
n=0;
miao++;
if(miao==60)//秒到60
{
miao=0;
fen++;
if(fen==60)//分到60
{
fen=0;
shi++;
if(shi==24)
{
shi=0;//时到24
r++;
b++;
b=b%7;
}
}
}
}
}
/****************************************/
voidNT_0()interrupt0//选择
{
delay(10);
if(k5==0)
{
cs++;
if(cs>=6)cs=0;
table[14]=cs+'0';//显示调节标志位
}
}
/****************************************/
voidNT_1()interrupt2
{
delay(10);
if(k6==0)
{
switch(cs)
{
case0:
{shi++;shi=shi%24;}break;//调时
case1:
{fen++;fen=fen%60;}break;
//调分
case2:
{ni++;if(ni==100)ni=1;}break;//调年
case3:
{y++;if(y==14)y=1;}break;//调月
case4:
{r++;if(r==367)r=1;}break;//调日
case5:
{b++;b=b%7;}break;//调星期
default:
cs=0;
}
riqi();
if(shi==24)b++;
}
}
/****************************************/
voidriqi()
{
xq=b+1;
runnia=0;
if((ni%4==0&&ni%100!
=0)||(ni%400==0))runnia=1;//闰年判断
switch(y)//确定本月有几天
{
case1:
{if(r==32){y++;r=1;}};break;
case2:
{if(((runnia==1)&&(r==30))||((runnia==0)&&(r==29))){y++;r=1;}};break;
case3:
{if(r==32){y++;r=1;}};break;
case4:
{if(r==31){y++;r=1;}};break;
case5:
{if(r==32){y++;r=1;}};break;
case6:
{if(r==31){y++;r=1;}};break;
case7:
{if(r==32){y++;r=1;}};break;
case8:
{if(r==31){y++;r=1;}};break;
case9:
{if(r==31){y++;r=1;}};break;
case10:
{if(r==32){y++;r=1;}};break;
case11:
{if(r==31){y++;r=1;}};break;
case12:
{if(r==32){y++;r=1;}};break;
default:
r=1;
}
if(y==13){y=1;ni++;ni=ni%99;}//最大记年0~99(2000~2199)
}
四、流程图
五、缺点与不足
1、定时器处理时间时,由于其他指令运行需要一定时间,会对实际时间造成一定影响,使时间和实际时间存在一定差距;
2、在调节时间时由于使用了外部中断,占用了中断源,不利于以后对程序得扩展,而且调节是只有加没有减,会对调节造成一定的麻烦;
六、心得体会
七、指导老师评语
附录:
修改后的程序,可以加减时间
#include
#include
#defineuintunsignedint
#defineucharunsignedchar
/****************************************/
sbitk1=P3^0;
sbitk2=P3^1;
sbitk3=P3^2;
sbitk4=P3^3;
sbitrs=P3^5;
sbitwr=P3^6;
sbitlcden=P3^4;
sbitdula=P2^6;
sbitwela=P2^7;
/****************************************/
//变量、中断次数、秒、分、时、延时、年、月、日、星期、闰年、星期变量、按键
uinta,n,miao,fen,shi,z,ni,y,r,xq,runnia,b,key,m;
uchartable[]="2010-01-01>6<";
uchartable1[14]={"time:
00:
00:
00"};
/****************************************/
voidriqi();
//延时子程序
voiddelay(uintz)
{
uintx,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
/****************************************/
voidwrite_com(ucharcom)//1602写指令
{
P0=com;
rs=0;
lcden=0;
delay(10);
lcden=1;
delay(10);
lcden=0;
}
/****************************************/
voidwrite_date(uchardate)//1602写数据
{
P0=date;
rs=1;
lcden=0;
delay(10);
lcden=1;
delay(10);
lcden=0;
}
/****************************************/
voidinit()//初始化子程序
{
m=0;
ni=10;
y=1;
r=1;
xq=1;
runnia=0;
b=5;
k1=1;
k2=1;
k3=1;
k4=1;
key=0;
dula=0;
wela=0;
wr=0;
write_com(0x38);//1602初始化
delay(20);
write_com(0x0c);
delay(20);
write_com(0x06);
delay(20);
write_com(0x01);
delay(20);
shi=0;
fen=0;
miao=0;
TMOD=0x01;//定时器初始化因为其他指令也要运行时间这里定时器初值是49.99ms
TH0=(65536-49990)/256;
TL0=(65536-49990)%256;
EA=1;
ET0=1;
//EX0=1;
//EX1=1;
IT0=1;
IT1=1;
TR0=1;
}
/***************************************/
voidtjie()//调节子程序
{
//TR0=0;
if(k2==0)
{
delay
(1);
m++;
m=m%6;
}
switch(m)
{
case0:
{if(k3==0){shi++;shi=shi%24;}if(k4==0){shi--;if((shi+1)<=0)shi=23;}}break;//调时
case1:
{if(k3==0){fen++;fen=fen%60;}if(k4==0){fen--;if((fen+1)<=0)fen=59;}}break;//调分
case2:
{if(k3==0){ni++;ni=ni%100;}if(k4==0){ni--;if(ni<=0)ni=99;}}break;//调年
case3:
{if(k3==0)y++;if(k4==0){y--;if(y<=1)y=12;}}break;//调月
case4:
{if(k3==0)r++;if(k4==0){r--;if(r<=1)r=31;}}break;//调日
case5:
{if(k3==0){b++;if(b==8)b=1;}if(k4==0){b--;}if(b<1)b=7;}break;//调星期
default:
m=0;
}
riqi();//闰年及月,日等的处理
table[14]=m+'0';//显示调节标志位
}
/****************************************/
//显示子程序
voidxianshi()
{
riqi();
table1[12]=miao/10+'0';//取值
table1[13]=miao%10+'0';
table1[9]=fen/10+'0';
table1[10]=fen%10+'0';
table1[6]=shi/10+'0';
table1[7]=shi%10+'0';
table[2]=ni/10+'0';
table[3]=ni%10+'0';
table[5]=y/10+'0';
table[6]=y%10+'0';
table[8]=r/10+'0';
table[9]=r%10+'0';
table[12]=xq+'0';
write_com(0x80);//送到1602显示
delay(10);
for(a=0;a<15;a++)
{
write_date(table[a]);
delay(10);
}
write_com(0xc0);
delay(10);
for(a=0;a<14;a++)
{
write_date(table1[a]);
delay(10);
}
}
/****************************************/
//主程序
voidmain()
{
init();
while
(1)
{
if(k1==0){key++;key=key%2;}
if(key==1)tjie();
riqi();
xianshi();
table[14]='';//关闭调节标志位
}
}
/****************************************/
//中断程序
voidT_0()interrupt1
{
TH0=(65536-49950)/256;
TL0=(65536-49950)%256;
n++;
if(n==20)//延时1s
{
n=0;
miao++;
if(miao==60)//秒到60
{
miao=0;
fen++;
if(fen==60)//分到60
{
fen=0;
shi++;
if(shi==24)
{
shi=0;//时到24
r++;//日加
b++;//星期加
if(b==8)b=1;
}
}
}
}
}
/***************************************
voidNT_0()interrupt0//选择
{
delay(10);
if(k5==0)
{
cs++;
if(cs>=6)cs=0;
table[14]=cs+'0';//显示调节标志位
}
}
/***************************************
voidNT_1()interrupt2
{
delay(10);
if(k6==0)
{
switch(cs)
{
case0:
{shi++;shi=shi%24;}break;//调时
case1:
{fen++;fen=fen%60;}break;//调分
case2:
{ni++;if(ni==100)ni=1;}break;//调年
case3:
{y++;if(y==14)y=1;}break;//调月
case4:
{r++;if(r==367)r=1;}break;//调日
case5:
{b++;b=b%7;}break;//调星期
default:
cs=0;
}
riqi();
if(shi==24)b++;
}
}
***************************************/
voidriqi()
{
xq=b;
runnia=0;
if((ni%4==0&&ni%100!
=0)||(ni%400==0))runnia=1;//闰年判断
switch(y)//确定本月有几天
{
case1:
{if(r==32){y++;r=1;}};break;
case2:
{if(((runnia==1)&&(r==30))||((runnia==0)&&(r==29))){y++;r=1;}};break;
case3:
{if(r==32){y++;r=1;}};break;
case4:
{if(r==31){y++;r=1;}};break;
case5:
{if(r==32){y++;r=1;}};break;
case6:
{if(r==31){y++;r=1;}};break;
case7:
{if(r==32){y++;r=1;}};break;
case8:
{if(r==31){y++;r=1;}};break;
case9:
{if(r==31){y++;r=1;}};break;
case10:
{if(r==32){y++;r=1;}};break;
case11:
{if(r==31){y++;r=1;}};break;
case12:
{if(r==32){y++;r=1;}};break;
default:
r=1;
}
if(y==13){y=1;ni++;ni=ni%99;}//最大记年0~99(2000~2099)