1. 程式人生 > >STC微控制器之1602顯示時鐘

STC微控制器之1602顯示時鐘

/****為了簡單起見,調整時間是隻添加了s1和s2,刪除了s3的功能,若調過了可通過s2迴圈一圈 ****/
/****From Brandon 2016-09-17 ****/
/****關鍵點:按鍵掃描和定時器0的中斷程式比較生疏,需再看 ****/
#include<reg51.h>

sbit LCD_rs=P1^0;
sbit LCD_rw=P1^1;
sbit LCD_en=P2^5;
sbit s1=P3^0;
sbit rd=P3^7;
sbit wr=P3^6;
sbit s2=P3^1;
sbit s3=P3^2;

unsigned char code table[]="  2016-9-15 THU";
unsigned char code table1[]="    00:00:00";

unsigned char num,count,s1num;
char miao,shi,fen;  //

void Delay(unsigned char i)
{
unsigned char j,k;
for(j=i;j>0;j--)
for(k=110;k>0;k--);
}

void LCD_Write_com(unsigned char a)
{
LCD_rs=0;
Delay(5);
LCD_rw=0;
Delay(5);
P0=a;
Delay(5);
LCD_en=1;
Delay(5);
LCD_en=0;
}

void LCD_Write_data(unsigned char b)
{
LCD_rs=1;
Delay(5);
LCD_rw=0;
Delay(5);
P0=b;
LCD_en=1;
Delay(5);
LCD_en=0;
Delay(5);
}

void LCD_init()
{
Delay(15);
LCD_Write_com(0x38);
Delay(5);
LCD_Write_com(0x08);
Delay(5);
LCD_Write_com(0x01);
Delay(5);
LCD_Write_com(0x06);
Delay(5);
LCD_Write_com(0x0C);
Delay(5);
}

void Time0_init()
{
TMOD=0x01;  //定時器0工作在模式1,
TH0=(65536-50000)/256;  //高8位=60
TL0=(65536-50000)%256;  //低8位
TR0=1; //開定時器0
ET0=1; //使能定時器0中斷
EA=1;  //開總中斷
}

void Write_sfm(unsigned char add,unsigned char date)
{
unsigned char shi,ge;
shi=date/10;
ge=date%10;
LCD_Write_com(0x80+0x40+add);
LCD_Write_data(0x30+shi);   //0x30表示的是對應數字的ASC碼
LCD_Write_data(0x30+ge);    //0x30表示的是對應數字的ASC碼
}

void Keyscan()
{
rd=0;
if(s1==0)   //s1摁下
{
Delay(5);
if(s1==0)
{
      s1num++;
   while(!s1);//等待s1鬆開
   if(s1num==1)
     {
 TR0=0;  //關定時器0
 LCD_Write_com(0x80+0x40+10);//游標定位到1602第二行第11個字元處
 LCD_Write_com(0x0f);//開顯示,顯示游標,游標閃爍
                     }
}
if(s1num==2)
{
TR0=0;
LCD_Write_com(0x80+0x40+7);
LCD_Write_com(0x0f);
      }
if(s1num==3)
{
TR0=0;
LCD_Write_com(0x80+0x40+4);
LCD_Write_com(0x0f);
      }
if(s1num==4)
{
s1num=0;
LCD_Write_com(0x0c); //開顯示,不顯示游標
TR0=1;  //開定時器
      }

   }
if(s1num!=0)  //若s1num不等於0
{
if(s2==0)   //s2摁下
{
Delay(5);
if(s2==0)
{
while(!s2);  //s2鬆開後while迴圈結束
if(s1num==1)
{
miao++;
if(miao==60)
miao=0;
Write_sfm(10,miao);
LCD_Write_com(0x80+0x40+10);
         }
if(s1num==2)
{
fen++;
if(fen==60)
fen=0;
Write_sfm(7,fen);
LCD_Write_com(0x80+0x40+7);
         }
if(s1num==3)
{
shi++;
if(shi==24)
shi=0;
Write_sfm(4,shi);
LCD_Write_com(0x80+0x40+4);
          }
}
      }
    }
}

void main()
{
wr=0;
LCD_init();
LCD_Write_com(0x80);  //不能寫到for函式裡面,否則顯示不正常
for(num=0;num<15;num++)
{
LCD_Write_data(table[num]);
Delay(5);
         }
LCD_Write_com(0x80+0x40);   //不能寫到for函式裡面,否則顯示不正常
for(num=0;num<12;num++)
{
LCD_Write_data(table1[num]);
Delay(5);
         }
Time0_init();
while(1)      //試試此處加一個冒號,提示什麼警告,感悟:除錯時要會對警告進行分析
{
Keyscan();
         }
}

//以下程式待自己編寫
void timer0() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;  //50000*(11.0592/12)ms定時,若晶振為12MHz,則為50ms
count++;
if(count==18)         //此處表示18個以上的數字,即1s,注意有誤差
{
count=0;
miao++;
if(miao==60)
{
miao=0;
fen++;
if(fen==60)
{
fen=0;
shi++;
if(shi==24)
{
shi=0;
}
Write_sfm(4,shi);
}
Write_sfm(7,fen);
}
Write_sfm(10,miao);

}

}