標題:
基于51單片機的1602顯示源代碼
[打印本頁]
作者:
小小學(xué)究
時間:
2017-10-19 16:58
標題:
基于51單片機的1602顯示源代碼
#include<reg52.h>
#define uchar unsigned char//宏定義
#define uint unsigned int//宏定義
sbit dula=P2^6;//控制數(shù)碼管
sbit wela=P2^7;
sbit rs=P3^5;//控制液晶數(shù)據(jù)名命令選擇
sbit lcden=P3^4;//液晶寫數(shù)據(jù)控制
sbit s1=P3^0;//控制矩陣鍵盤的S9
sbit s2=P3^1;//控制矩陣鍵盤的S13
sbit s3=P3^2;//控制矩陣鍵盤的S17
sbit rd=P3^7;//申明RD的位
uchar count,date,shi,fen,miao,s1num;
uchar code table[]=" 2017-10-17 MON";//初始化顯示日期
uchar code table1[]=" 19:28:20";//初始化顯示時間
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void write_com(uchar com)//寫指令函數(shù)
{
rs=0;//數(shù)據(jù)置低
lcden=0;//lcden拉低
P0=com;
delay(5);
lcden=1;//拉高
delay(5);//穩(wěn)定五毫秒
lcden=0;//拉低
}
void write_date(uchar date)//寫指數(shù)據(jù)函數(shù)
{
rs=1;//數(shù)據(jù)置高
lcden=0;//lcden拉低
P0=date;
delay(5);
lcden=1;//拉高
delay(5);//穩(wěn)定五毫秒
lcden=0;//拉低
}
void init()
{
uchar num;
dula=0;//關(guān)閉數(shù)碼管
wela=0;
lcden=0;//通過1602的資料顯示lcden初始為低
/* 一定注意這里的賦值與程序開頭的自定義賦值,當(dāng)二者賦值一致的時候才會正常走動,不也一樣時就會出現(xiàn)錯誤,原因未知*/
fen=28;
miao=20;
shi=19;
/***************************************************/
write_com(0x38);//設(shè)置16X2顯示,5X7點陣,8位數(shù)據(jù)接口
delay(5);
write_com(0x0c);//00001100開顯示,不顯示光標
write_com(0x06);//00000110,讀入一個字符后指針和光標都加一,整屏不移動
write_com(0x01);//清零,不清零會顯示出錯
write_com(0x80);//指針賦值,寫入地址,表示從第一行開始寫
for(num=0;num<15;num++)//第一行共需要15個顯示位,顯示位數(shù)一定要一一對應(yīng)
{
write_date(table[num]);//寫數(shù)據(jù)進去
delay(5);
}
write_com(0x80+0x40);//寫入第二行的地址
for(num=0;num<12;num++)//第二行共需要11個顯示位,顯示位數(shù)一定要一一對應(yīng),
{
write_date(table1[num]);//寫數(shù)據(jù)進去
delay(5);
}
TMOD=0x01;//采用定時器0的方式1
TH0=(65536-50000)/256;//裝初值
TL0=(65536-50000)%256;
EA=1;//開總中斷
ET0=1;//打開T0中斷
TR0=1;//啟動定時器0
}
void write_sfm(uchar add,uchar date)//寫動態(tài)數(shù)據(jù)到時分秒表中
{
uchar shi,ge;//時、分、秒、都由兩個數(shù)字表示,分離開
shi=date/10;//分離出數(shù)據(jù)的十位
ge=date%10;//分離個位
write_com(0x80+0x40+add); //寫動態(tài)到第二行中
write_date(0x30+shi);//通過1602的字符手冊,讓十位顯示0(0x30),送數(shù)據(jù)到第二行
write_date(0x30+ge);//通過1602的字符手冊,讓個位顯示0(0x30),送數(shù)據(jù)到第二行
}
void keyscan()//編寫按鍵控制時鐘函數(shù)
{//5
rd=0;//讓RD接地,要控制那一列就讓那一列接地,通過矩陣鍵盤原理圖判斷
if(s1==0)//檢測s1是否按下
{//4
s1num++;//每按下一次s1就加一
delay(5);//延時消抖
if(s1==0)//判斷s1確實被按下
{
while(!s1);//檢測是否松手
if(s1num==1)//按下第一次讓秒閃爍
{
TR0=0;//關(guān)閉定時器,禁止時鐘繼續(xù)走動
write_com(0x80+0x40+11);//控制第二行的第幾位
write_com(0x0f);//顯示光標,并讓光標閃爍,0x0f來源于1602的原理圖
}
if(s1num==2)//按下第二次讓分閃爍
{
TR0=0;//關(guān)閉定時器,禁止時鐘繼續(xù)走動
write_com(0x80+0x40+8);//控制第二行的第幾位
write_com(0x0f);//顯示光標,并讓光標閃爍,0x0f來源于1602的原理圖
}
if(s1num==3)//按下第三次讓時閃爍
{
TR0=0;//關(guān)閉定時器,禁止時鐘繼續(xù)走動
write_com(0x80+0x40+5);//控制第二行的第幾位
write_com(0x0f);//顯示光標,并讓光標閃爍,0x0f來源于1602的原理圖
}
if(s1num==4)//第四次按下,清零,讓光標不閃爍
{
s1num=0;//清零
write_com(0x0c);//光標停止閃爍
TR0=1;//開啟定時器,時鐘重新開始走動
}
}
}//4
if(s1num!=0)//確認s1鍵被按下
{//3
if(s2==0)//檢測s2被按下
{//2
delay(5);
if(s2==0)//確定s2被按下
{//1
while(!s2);
if(s1num==1)//確定讓秒加一
{
miao++;
if(miao==60)
miao=0;
write_sfm(10,miao);
write_com(0x80+0x40+10);
}
if(s1num==2)//確定讓分加一
{
fen++;
if(fen==60)
fen=0;
write_sfm(7,fen);
write_com(0x80+0x40+7);
}
if(s1num==3)//確定讓時加一
{
shi++;
if(shi==24)
shi=0;
write_sfm(4,shi);
write_com(0x80+0x40+4);
}
}//1
}//2
if(s3==0)//檢測s3被按下
{//2
delay(5);
if(s3==0)//確定s2被按下
{//1
while(!s3);
if(s1num==1)//確定讓秒加一
{
miao--;
if(miao==0)
miao=60;
write_sfm(10,miao);
write_com(0x80+0x40+10);
}
if(s1num==2)//確定讓分加一
{
fen++;
if(fen==0)
fen=60;
write_sfm(7,fen);
write_com(0x80+0x40+7);
}
if(s1num==3)//確定讓時加一
{
shi++;
if(shi==0)
shi=24;
write_sfm(4,shi);
write_com(0x80+0x40+4);
}
}//1
}//2
} //3
}//5
void main()
{
init();
while(1)
{
keyscan();
if(count==20)//判斷是否到了1秒
{
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);//10表示table1[]中的秒位正好在第十個字符位后面
}
}
}
void timer0() interrupt 1//選擇中斷源
{
TH0=(65536-50000)/256;//裝初值
TL0=(65536-50000)%256;
count++;
}
復(fù)制代碼
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1