今年的单片机课程结束后,老师别出心裁的说今年咱考试内容改成课外作业,自己做个板子实现按键修改时间,用数码管显示,要求年月日时分秒都能修改,且月年闰月都要考虑。这里我没按老师要求,我不喜欢数码管显示,因为引线太多太不美观,因此自作主张,用1602代替数码管显示,也正是因为这样,导致在程序修改过程中遇见了不科学的一面苦逼了一整天终于解决:因为1602的地址以及数据的显示都要许多延时,而定时中断和串口中断又都在运行,因此,当显示还没完成就进入了下次中断。。不过。。苦逼的孩子也有春天,偶然想起前些日子调MMA8451的时候也是因为时间问题读不到数据。。终于迎刃而解。谨以此片献给同样苦逼的孩纸。。
亮点:
1.无线下载程序。
2.用电脑对板子修改时间也是无线的,且同时修改年月日时分秒,修改格式如下:比如修改为2013-12-12 11:23:23 则发送20131212112323
程序见附件:擦擦擦。。只能传图片啊,,第一篇博客 不懂。。还是贴上来吧:
/*********其中write_com(0x18)是整屏移动指令************/
#include
#include
#define uchar unsigned char
#define uint unsigned int
#define KeyPort P2
sbit key =P1^1;
unsigned char flag,a;
int j=0;
sbit led=P1^0;
sbit rs = P1^3;
//sbit rw = P1^3;
sbit lcden = P1^4;
//sbit s1=P3^0;
//sbit s2=P3^1;
//sbit s3=P3^2;
//sbit s4=P3^3;
//sbit P20=P2^0;
//sbit P21=P2^1;
//sbit P22=P2^2;
//sbit P37=P3^7;
//sbit P10=P1^0;
uchar count,num,num1,i,temp,temp1;//j;
uint year;
uchar year1,year2,yue,ri,fen,shi,fen,miao,shi1,fen1,miao1;
uchar code table[]=" 2013-05-09 ";//" PLEASE SET DATE ";//" 2013-04-21 NCHU";
uchar code table1[]=" 00:00:00 ";//" PLEASE SET TIME ";//" 2013-04-21 NCHU";
uchar table2[15];//=" 00:00:00 ";
uchar table3[15];
/*延时函数*/
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
/*显示屏命令写入函数*/
void write_com(uchar com)
{
rs=0;
// rw=0;
lcden=1;
P0=com;
delay(5);
lcden=0;
}
/*显示屏数据写入函数*/
void write_data(uchar date)
{
rs=1;
// rw=0;
lcden=1;
P0=date;
delay(5);
lcden=0;
}
/*数的分离和显示函数*/
void display(uchar add,char shu)
{
uchar shi,ge;
shi=shu/10;
ge=shu%10;
write_com(0x80+0x40+add);
write_data(0x30+shi);
write_data(0x30+ge);
}
/* void display_0(uchar add,uint shu)
{
uint qian,bai,shi,ge;
qian=shu/1000;
bai=shu%1000/100;
shi=shu%100/10;
ge=shu%10;
// shi=shu%100/10;
// bai=shu/100;
write_com(0x80+add);
write_data(qian);
write_data(0x30+bai);
write_data(0x30+shi);
write_data(0x30+ge);
} */
void display_1(uchar add,char shu)
{
uchar shi,ge;
shi=shu/10;
ge=shu%10;
write_com(0x80+add);
write_data(0x30+shi);
write_data(0x30+ge);
}
/*键盘控制时钟函数*/
/*
void keyscan()
{
// if(s1==0)
// delay(5);
// if(s1==0)
// {
// num++;
// while(!s1);
// }
// if(num==1)
// {
TR0=0;
write_com(0x80+0x40+10);
write_com(0x0f);//显示光标
if(s2==0)
delay(5);
if(s2==0)
// {
// while(!s2);
miao++;
if(miao==60)
miao=0;
display(10,miao);
// }
if(s3==0)
delay(5);
if(s3==0)
{
while(!s3);
miao--;
if(miao==-1)
miao=59;
display(10,miao);
}
}
if(num==2)
{
write_com(0x80+0x40+7);
if(s2==0)
delay(5);
if(s2==0)
{
while(!s2);
fen++;
if(fen==60)
fen=0;
display(7,fen);
}
if(s3==0)
delay(5);
if(s3==0)
{
while(!s3);
fen--;
if(fen==-1)
fen=59;
display(7,fen);
}
}
if(num==3)
{
write_com(0x80+0x40+4);
if(s2==0)
delay(5);
if(s2==0)
{
while(!s2);
shi++;
if(shi==24)
shi=0;
display(4,shi);
}
if(s3==0)
delay(5);
if(s3==0)
{
while(!s3);
shi--;
if(shi==-1)
shi=23;
display(4,shi);
}
}
if(num==4)
{
TR0=1;
num=0;
write_com(0x0C); //关闭光标
}
}
/*显示屏初始化函数*/
void init()
{
write_com(0x38); /*显示模式设置*/ //该语句可有可无
delay(5); //该语句可有可无
write_com(0x38); //该语句可有可无
delay(5); //该语句可有可无
write_com(0x38); //该语句可有可无
delay(5); //该语句可有可无
write_com(0x38);
write_com(0x08); /*显示关闭*/
write_com(0x01); /*显示清屏*/
write_com(0x06); /*显示光标移动设置*/
delay(5);
write_com(0x0C); /*显示开及光标设置*/
// P37=1;
// P20=1;
// P21=1;
// P22=1;
P0=0x00;
// P37=0;
for(i=0;i<16;i++)
{
write_data(table[i]);
delay(5);
}
write_com(0x80+0x40);
for(j=0;j<15;j++)
{
write_data(table1[j]);
delay(5);
}
///////////////////////////////////
TMOD=0x21;//设置定时器1为工作方式2以及串口中断
TH1=0xfd;
TL1=0xfd;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
ET0=1;
TR0=1;
TR1=1;
REN=1;
SM0=0;
SM1=1;
EA=1;
ES=1;
j=0;
// SBUF=a;//28;
// while(!TI);
// TI=0;
// SBUF='2';//28;
// while(!TI);
// TI=0;
// SBUF=table2[1];//28;
// while(!TI);
// TI=0;
// }
}
/*
unsigned char KeyScan(void) //键盘扫描函数,使用行列逐级扫描法
{
unsigned char Val;
KeyPort=0xf0;//高四位置高,低四位拉低
if(KeyPort!=0xf0)//表示有按键按下
{
delay(5); //去抖
if(KeyPort!=0xf0)
{ //表示有按键按下
KeyPort=0xfe; //检测第一行
if(KeyPort!=0xfe)
{
Val=KeyPort&0xf0;
Val+=0x0e;
while(KeyPort!=0xfe);
delay(5); //去抖
while(KeyPort!=0xfe);
return Val;
}
KeyPort=0xfd; //检测第二行
if(KeyPort!=0xfd)
{
Val=KeyPort&0xf0;
Val+=0x0d;
while(KeyPort!=0xfd);
delay(5); //去抖
while(KeyPort!=0xfd);
return Val;
}
KeyPort=0xfb; //检测第三行
if(KeyPort!=0xfb)
{
Val=KeyPort&0xf0;
Val+=0x0b;
while(KeyPort!=0xfb);
delay(5);//去抖
while(KeyPort!=0xfb);
return Val;
}
KeyPort=0xf7; //检测第四行
if(KeyPort!=0xf7)
{
Val=KeyPort&0xf0;
Val+=0x07;
while(KeyPort!=0xf7);
delay(5); //去抖
while(KeyPort!=0xf7);
return Val;
}
}
}
return 0xff;
}
/*------------------------------------------------
按键值处理函数,返回扫键值
------------------------------------------------
unsigned char KeyPro(void)
{
switch(KeyScan())
{
case 0x7e:return 0;break;//0 按下相应的键显示相对应的码值
case 0x7d:return 1;break;//1
case 0x7b:return 2;break;//2
case 0x77:return 3;break;//3
case 0xbe:return 4;break;//4
case 0xbd:return 5;break;//5
case 0xbb:return 6;break;//6
case 0xb7:return 7;break;//7
case 0xde:return 8;break;//8
case 0xdd:return 9;break;//9
case 0xdb:return 10+6;break;//a
case 0xd7:return 11+6;break;//b
case 0xee:return 12+6;break;//c
case 0xed:return 13+6;break;//d
case 0xeb:return 14+6;break;//e
case 0xe7:return 15+6;break;//f
default:return 0xff;break;
}
}
/*中断函数*/
void timer0() interrupt 1
{
EA=0;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
count++;
if(count==20) //在此进行计算可以减小执行程序而导致的时间差 使时钟更准确
{
count=0;
miao++;
if(miao==60)
{
miao=0;
fen++;
if(fen==60)
{
fen=0;
shi++;
if(shi==24)
{
shi=0;
ri++;
if(year%4==0&&year%100!=0||year%400==0)
{
switch(yue)
{
case 1:case 3:case 5:case 7:case 9:case 11:if(ri==32) yue++;display_1(8,yue);break;
case 2:if(ri==30) yue++;display_1(8,yue);break;
case 4:case 6:case 8:case 10:if(ri==31) yue++;display_1(8,yue);break;
case 12:if(ri==31) year++;display_1(3,year1);display_1(5,year2);break;
}
}
else
{
switch(yue)
{
case 1:case 3:case 5:case 7:case 9:case 11:if(ri==32) yue++;display_1(8,yue);break;
case 2:if(ri==29) yue++;display_1(8,yue);break;
case 4:case 6:case 8:case 10:if(ri==31) yue++;display_1(8,yue);break;
case 12:if(ri==31) year++;display_1(3,year1);display_1(5,year2);break;
}
}
}
display_1(11,ri);
}
display(4,shi);
}
display(7,fen);
}
display(10,miao);
EA=1;
}
/*主函数*/
void main()
{
j=0;
init();
temp1=SBUF;
while(1)
{
//if(key==0)
//delay(5);
//if(key==0)
if(j==16)
{ ES=0;
EA=0;
j=0;
led=0;
//write_com(0x38); /*显示模式设置*/ //该语句可有可无
// delay(5); //该语句可有可无
// write_com(0x38); //该语句可有可无
// delay(5); //该语句可有可无
// write_com(0x38); //该语句可有可无
// delay(5); //该语句可有可无
/* write_com(0x38);
write_com(0x08); //显示关闭
write_com(0x01); //显示清屏
write_com(0x06); //显示光标移动设置
delay(5);
write_com(0x0C); //显示开及光标设置
P0=0x00;
for(i=0;i<16;i++)
{
write_data(table2[i]);
delay(5);
}
write_com(0x80+0x40);
for(i=17;i<32;i++)
{
write_data(table2[i]);
delay(5);
} */
for(i=0;i<16;i++)
{
table3[i]=table2[i];
}
year=table3[1]*1000+table3[2]*100+table3[3]*10+table3[4]; //table3[1]*1000+table3[2]*100+
year1=year/100;
year2=year%100;
yue =table3[5]*10+table3[6];
ri =table3[7]*10+table3[8];
shi =table3[9]*10+table3[10];
fen =table3[11]*10+table3[12];
miao=table3[13]*10+table3[14];
display_1(3,year1);
display_1(5,year2);
display_1(8,yue);
display_1(11,ri);
display(4,shi);
display(7,fen);
display(10,miao);
EA=1;
ES=1;
led=1;
}
//disableruppt;
//else{
//enableruppt;
// while(1)
// {
// write_com(0x80+0x40);
// write_com(0x0f);//显示光标
// display(10,15);
// write_data(0x30+miao);
// write_data(0x30+1);
// write_data(0x30+15);
// while(1);
// }
}
}
void ser() interrupt 4
{
if(RI)
{
ES=0;
// flag=1;
RI=0;
temp =SBUF;
table2[j]=temp&0x0f;
j++;
ES=1;
}
}
***注明:里面好多注释掉的是之前写的键盘修改的。。没删掉 也许你用得到。