|
LCD1602液晶屏顯示的萬(wàn)年歷,DS1307還有很多功能可以添加小白一個(gè)
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
YS5{9N%7R)D5P7LS6IMZXHH.png (32.99 KB, 下載次數(shù): 131)
下載附件
protues仿真圖
2017-11-17 10:51 上傳
0.png (13.73 KB, 下載次數(shù): 100)
下載附件
2017-11-17 20:23 上傳
單片機(jī)源程序如下:
- /****************************************************
- 電路圖說(shuō)明:
- 將單片機(jī)P2.7和P1.0分別與RTC(實(shí)時(shí)時(shí)鐘)的時(shí)鐘信號(hào)SCL端
- 和數(shù)據(jù)信號(hào)SDA端相連, RTC的sout引腳與單片機(jī)P3.2相連,RTC的
- 地址是11010000.獨(dú)立鍵盤(pán)k0~K3接P1.1~P1.3
- 程序功能:
- 使用時(shí)鐘芯片ds1307制作一個(gè)實(shí)時(shí)時(shí)鐘
- ******************************************************/
- #include <reg52.h>
- #include<intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- //實(shí)時(shí)時(shí)鐘兩信號(hào)線
- sbit scl=P2^7;
- sbit sda=P1^0;
- //獨(dú)立鍵盤(pán)掃描位
- sbit k0=P1^1;
- sbit k1=P1^2;
- sbit k2=P1^3;
- //液晶顯示器控制位
- sbit lcd_rs=P3^4;
- sbit lcd_e=P3^5;
- //數(shù)碼管和led鎖存器選通位
- sbit duan=P2^0;
- sbit wei=P2^1;
- sbit led=P2^2;
- void init();//初始化IIC總線,使總線處于備用狀態(tài),
- //初始化lcd并顯示上面table1和table2的值,初始化定時(shí)器0,初始化變量時(shí)分秒
- /****************IIC總線控制函數(shù)***************************/
- void IIC_start();//IIC通信開(kāi)始信號(hào)
- void IIC_stop();//IIC通信停止信號(hào)
- void IIC_un_ack();//單片機(jī)發(fā)送非應(yīng)答位
- //void IIC_ack();//單片機(jī)發(fā)送應(yīng)答位
- void IIC_check_ack();//單片機(jī)檢查應(yīng)答位
- void IIC_write_byte(uchar);//發(fā)送一字節(jié)數(shù)據(jù)
- uchar IIC_read_byte();//接收一字節(jié)數(shù)據(jù)
- void nop();//5us空操作延遲
- /**********************************/
- /**********ds1307讀寫(xiě)函數(shù)*******************/
- void ds1307_write_date(uchar ,uchar ,uchar);//向指定器件寫(xiě)一字節(jié)數(shù)據(jù)
- //參數(shù)1器件地址,參數(shù)2要存的數(shù)據(jù)存放位置8位地址
- //參數(shù)3要寫(xiě)的數(shù)據(jù)
- uchar ds1307_read_date(uchar ,uchar );//從指定器件讀一字節(jié)數(shù)據(jù),
- //參數(shù)1被通信器件地址,參數(shù)2要讀的數(shù)據(jù)存放位置8位地址
- //函數(shù)返回讀取的數(shù)據(jù)。
- void delay(uint);//基數(shù)1ms延遲程序
- /***********************************/
- /**************LCD操作函數(shù)**************************/
- uchar hour,minute,second,k0_num;//時(shí)分秒變量,菜單鍵k0第幾次按下計(jì)數(shù),ds1307跟新標(biāo)志
- //時(shí)鐘初顯示
- uchar code table1[]="2017-11-16 THUR";
- uchar code table2[]=" 23:59:55 ";
- void lcd_write_com(uchar);//向液晶顯示器寫(xiě)指令設(shè)置其顯示的格式
- void lcd_write_date(uchar);//向液晶顯示器寫(xiě)顯示的數(shù)據(jù)
- /**********************************************/
- /**************時(shí)鐘函數(shù)*******************/
- void lcd_write_second(uchar);//向lcd寫(xiě)秒
- void lcd_write_minute(uchar);//向lcd寫(xiě)分
- void lcd_write_hour(uchar);//向lcd寫(xiě)時(shí)
- void run_time();//時(shí)鐘走動(dòng)顯示
- void keyscan();//菜單鍵掃描
- /****************************************/
- /*********十進(jìn)值與BCD碼之間互換**********/
- uchar b_second,b_minute,b_hour;
- uchar dectobcd(uchar);//十進(jìn)值轉(zhuǎn)bcd碼
- uchar bcdtodec(uchar);//bcd碼轉(zhuǎn)十進(jìn)值
- /****************************************/
- void main()
- {
- init();
- while(1)
- {
- keyscan();
- }
- }
- void nop()
- {
- _nop_();_nop_();_nop_();
- _nop_();_nop_();_nop_();
- }
- void init()
- {
- uchar i;
- //將數(shù)據(jù)線和時(shí)鐘線拉高,處于備用狀態(tài)即非忙
- sda=1;
- nop();
- scl=1;
- nop();
-
- //關(guān)數(shù)碼管顯示和8個(gè)LED顯示
- duan=0;
- wei=0;
- led=0;
- lcd_e=0;
-
- //初始化寫(xiě)入LCD的時(shí)分秒
- second=55;
- minute=59;
- hour=23;
- //初始化ds1307
- ds1307_write_date(0xd0,0x07,0x10);//初始化1307的控制字,使其SOUT引腳輸出1Hz的方波。
- //初始化1307的時(shí)間
- ds1307_write_date(0xd0,6,0x14);
- ds1307_write_date(0xd0,5,0x06);
- ds1307_write_date(0xd0,4,0x09);
- ds1307_write_date(0xd0,3,0x00);
- ds1307_write_date(0xd0,2,0x23);
- ds1307_write_date(0xd0,1,0x59);
- ds1307_write_date(0xd0,0,0x55);
- //初始化液晶顯示器
- lcd_write_com(0x38);//設(shè)置16*2行,5*7點(diǎn)陣,8位數(shù)據(jù)接口
- lcd_write_com(0x06);//寫(xiě)字符指針和光標(biāo)自動(dòng)向右移動(dòng)
- lcd_write_com(0x0c);//開(kāi)顯示,不顯示光標(biāo),光標(biāo)不閃爍
- lcd_write_com(0x01);//顯示清屏
- for(i=0;i<15;i++)
- {
- lcd_write_date(table1[i]);
- }
- lcd_write_com(0x80+0x40);
- for(i=0;i<10;i++)
- {
- lcd_write_date(table2[i]);
- }
-
- //開(kāi)啟外部中斷0
- EA=1;
- EX0=1;
- IT0=1;
- }
- void IIC_start()
- {
- //在時(shí)鐘信號(hào)有效scl=1時(shí),數(shù)據(jù)線負(fù)跳變
- sda=1;
- nop();
- scl=1;
- nop();
- sda=0;
- nop();
- scl=0;//拉低為下個(gè)時(shí)鐘數(shù)據(jù)作準(zhǔn)備
- nop();
- }
- void IIC_stop()
- {
- //在時(shí)鐘信號(hào)有效scl=1時(shí),數(shù)據(jù)線正跳變,釋放總線,使總線處于備用狀態(tài)即非忙
- sda=0;
- nop();
- scl=1;
- nop();
- sda=1;
- nop();
- nop();
- nop();
- }
- void IIC_un_ack()
- {
- //時(shí)鐘信號(hào)有效時(shí),sda給1,給出非應(yīng)答
- sda=1;
- nop();
- scl=1;
- nop();
- scl=0;//拉低為下個(gè)時(shí)鐘數(shù)據(jù)作準(zhǔn)備
- nop();
- }
- /*
- void IIC_ack()
- {
- //時(shí)鐘信號(hào)有效時(shí),sda給0,給出應(yīng)答
- sda=0;
- nop();
- scl=1;
- nop();
- scl=0;//拉低為下個(gè)時(shí)鐘數(shù)據(jù)作準(zhǔn)備
- nop();
- }
- */
- void IIC_check_ack()
- {
- //uchar i;
- //時(shí)鐘信號(hào)有效時(shí),檢測(cè)數(shù)據(jù)信號(hào)sda是否為0,給0說(shuō)明有應(yīng)答信號(hào)
- scl=1;
- //while((sda==1)&&(i<255)) i++;
- nop();
- scl=0;//拉低為下個(gè)時(shí)鐘數(shù)據(jù)作準(zhǔn)備
- nop();
- }
- uchar IIC_read_byte( )
- {
- uchar i,temp;//temp用于存放從數(shù)據(jù)線讀到的數(shù)據(jù)
- for(i=0;i<8;i++)//從數(shù)據(jù)線讀取一個(gè)字節(jié)(8位)
- {
- scl=1;
- nop();
- temp=(temp<<1)|sda;//temp左移,騰出第0位,然后將數(shù)據(jù)線上的一位數(shù)用或
- //運(yùn)算存放到temp的第0位
- scl=0;//拉低為下個(gè)時(shí)鐘數(shù)據(jù)作準(zhǔn)備
- nop();
- }
- return temp;
- }
- void IIC_write_byte(uchar byte)
- {
- uchar i;
- for(i=0;i<8;i++)//向數(shù)據(jù)線寫(xiě)一個(gè)字節(jié)(8位)
- {
- byte=byte<<1;//左移位,將byte第7位移到PSW中的進(jìn)位標(biāo)志位CY中
- sda=CY;
- nop();
- scl=1;
- nop();
- scl=0;//拉低為下個(gè)時(shí)鐘數(shù)據(jù)作準(zhǔn)備
- nop();
- }
- sda=1;//釋放總線,準(zhǔn)備接收被控設(shè)備應(yīng)答信號(hào)
- nop();
- }
- void ds1307_write_date(uchar d_address,uchar r_address,uchar date)
- {
- IIC_start();
- IIC_write_byte(d_address & (~0x01));//寫(xiě)器件地址,方向是寫(xiě),所以或上0x00
- IIC_check_ack();//等待應(yīng)答
- IIC_write_byte(r_address);//寫(xiě)存儲(chǔ)器數(shù)據(jù)存放的8位地址
- IIC_check_ack();//等待應(yīng)答
- IIC_write_byte(date);//寫(xiě)一字節(jié)數(shù)據(jù)
- IIC_check_ack();//等待應(yīng)答
- IIC_stop();
- }
- uchar ds1307_read_date(uchar d_address,uchar r_address)
- {
- uchar r;
- IIC_start();
- IIC_write_byte(d_address & (~0x01));//寫(xiě)器件地址,方向是寫(xiě)
- IIC_check_ack();//等待應(yīng)答
- IIC_write_byte(r_address);//寫(xiě)存儲(chǔ)器數(shù)據(jù)存放的8位地址
- IIC_check_ack();//等待應(yīng)答
- //換方向
- IIC_start();
- IIC_write_byte(d_address|0x01);//寫(xiě)器件地址,方向是讀,所以或上1
- IIC_check_ack();
- r=IIC_read_byte();//讀取一個(gè)字節(jié)數(shù)據(jù)
- IIC_un_ack();
- IIC_stop();
- return r;//將讀到的數(shù)據(jù)返回
- }
- void delay(uint z)//晶振頻率12MHz時(shí),z=1時(shí)延遲1ms
- {
- uint a,b;
- for(a=z;a>0;a--)
- for(b=110;b>0;b--);
- }
- void lcd_write_com(uchar com)//lcd寫(xiě)指令函數(shù)定義
- {
- lcd_rs=0;
- P0=com;
- delay(1);
- lcd_e=1;
- lcd_e=0;
- delay(2);
- }
- void lcd_write_date(uchar date)//lcd寫(xiě)數(shù)據(jù)函數(shù)定義
- {
- lcd_rs=1;
- P0=date;
- delay(1);
- lcd_e=1;
- lcd_e=0;
- delay(2);
- }
- void lcd_write_second(uchar sec)//向lcd寫(xiě)秒
- {
- uchar h,l;
- h=sec/10;
- l=sec%10;
- lcd_write_com(0x80+0x40+10);
- lcd_write_date(0x30+h);
- lcd_write_date(0x30+l);
- }
- void lcd_write_minute(uchar min)//向lcd寫(xiě)分
- {
- uchar h,l;
- h=min/10;
- l=min%10;
- lcd_write_com(0x80+0x40+7);
- lcd_write_date(0x30+h);
- lcd_write_date(0x30+l);
- }
- void lcd_write_hour(uchar hou)//向lcd寫(xiě)時(shí)
- {
- uchar h,l;
- h=hou/10;
- l=hou%10;
- lcd_write_com(0x80+0x40+4);
- lcd_write_date(0x30+h);
- lcd_write_date(0x30+l);
- }
- void inter0()interrupt 0
- {
- run_time();
- }
- void run_time()//時(shí)鐘走動(dòng)函數(shù)定義
- {
- //從1307中讀出時(shí)間
- b_second=ds1307_read_date(0xd0,0);//返回函數(shù)r值秒
- b_minute=ds1307_read_date(0xd0,1);
- b_hour=ds1307_read_date(0xd0,2);
- //將讀出的時(shí)間轉(zhuǎn)換成十進(jìn)值
- second=bcdtodec(b_second);
- minute=bcdtodec(b_minute);
- hour=bcdtodec(b_hour);
- //更新lcd顯示時(shí)間
- lcd_write_second(second);
- lcd_write_minute(minute);
- lcd_write_hour(hour);
- }
- uchar dectobcd(uchar dec)//十進(jìn)值到BCD碼
- {
- uchar x,y;
- x=dec/10;//得到bcd的十位數(shù)
- y=dec%10;//得到bcd的個(gè)位數(shù)
- y=(x<<4)|y;
- return y;
- }
- uchar bcdtodec(uchar bcd)//bcd碼轉(zhuǎn)十進(jìn)值
- {
- uchar x,y;
- y=bcd/16;//得到十進(jìn)制的十位數(shù)
- x=bcd%16;//得到十進(jìn)制的個(gè)位數(shù)
- y=y*10+x;
- return y;
- }
- void keyscan()//菜單鍵按下掃描函數(shù)定義
- {
- k0=1;
- k1=1;
- k2=1;
- //判斷菜單鍵k0是否按下
- if(k0==0)
- {
- delay(5);
- if(k0==0)
- {
- while(!k0);//松手檢測(cè)
- k0_num++;//記錄菜單鍵k0是第幾次按下,而判斷是調(diào)節(jié)秒、分還是時(shí)。
- if(k0_num==1)//指示調(diào)節(jié)秒
- {
- EX0=0;//關(guān)閉外部中斷0,使時(shí)間走動(dòng)停止,準(zhǔn)備調(diào)時(shí)間
- ds1307_write_date(0xd0,0,0x80|b_second);
- lcd_write_com(0x80+0x40+11);//數(shù)據(jù)指針和光標(biāo)移動(dòng)秒出
- lcd_write_com(0x0f);//使光標(biāo)顯示,并光標(biāo)處字符格符閃爍,用來(lái)提示用戶此時(shí)可以調(diào)節(jié)
- //什么?是秒,是分還是時(shí)。
- }
- if(k0_num==2)//指示調(diào)節(jié)分
- {
- lcd_write_com(0x80+0x40+8);//數(shù)據(jù)指針和光標(biāo)移動(dòng)分出
- }
- if(k0_num==3)//指示調(diào)節(jié)時(shí)
- {
- lcd_write_com(0x80+0x40+5);//數(shù)據(jù)指針和光標(biāo)移動(dòng)時(shí)出
- }
- if(k0_num==4)//退出時(shí)間調(diào)節(jié)菜單
- {
- k0_num=0;//菜單鍵k0按下清零
- lcd_write_com(0x0c);//恢復(fù)到時(shí)鐘走動(dòng)狀態(tài),即光標(biāo)不顯示,不閃爍
- //將所調(diào)的時(shí)間轉(zhuǎn)換成bcd碼
- b_second=dectobcd(second);
- b_minute=dectobcd(minute);
- b_hour=dectobcd(hour);
- //將所調(diào)的時(shí)間向時(shí)鐘寫(xiě)入
- ds1307_write_date(0xd0,2,b_hour);
- ds1307_write_date(0xd0,1,b_minute);
- ds1307_write_date(0xd0,0,b_second);
- EX0=1;//開(kāi)外部中斷0,時(shí)間開(kāi)始繼續(xù)走動(dòng)
- }
-
- }
- }
- //判斷是否按下過(guò)時(shí)間調(diào)節(jié)菜單鍵k0,而處于需要調(diào)節(jié)時(shí)間狀態(tài)
- if(k0_num)
- {
- //判斷是否是上調(diào)鍵k1按下
- if(k1==0)
- {
- delay(5);
- if(k1==0)
- {
- while(!k1);//松手檢測(cè)
- if(k0_num==1)//上調(diào)秒
- {
- second++;
- if(second==60)
- second=0;
- lcd_write_second(second);//向lcd寫(xiě)入被修改的時(shí)間
- lcd_write_com(0x80+0x40+11);//光標(biāo)位置重定位到所要調(diào)的時(shí)間處
-
- }
- if(k0_num==2)//上調(diào)分
- {
- minute++;
- ……………………
- …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼
所有資料51hei提供下載:
DS1307實(shí)時(shí)時(shí)鐘應(yīng)用.rar
(56.62 KB, 下載次數(shù): 415)
2017-11-17 10:54 上傳
點(diǎn)擊文件名下載附件
代碼和仿真圖 下載積分: 黑幣 -5
|
評(píng)分
-
查看全部評(píng)分
|