#include <reg52.h>
#include "intrins.h" //_nop_();延時函數用
#define uchar unsigned char
#define uint unsigned int
sbit DS1302_SCLK =P1^0; //時鐘
sbit DS1302_IO =P1^1; //數據輸入輸出
sbit DS1302_RST =P1^2; //復位/片選線
sbit lcd_psb = P3^2; //串/并口選擇
sbit lcd_rw = P2^5; //讀寫控制
sbit lcd_rs = P2^6; //寄存器選擇 0為指令 1為數據
sbit lcd_EN = P2^7; //lcd使能信號(并口)
struct S_TIME
{
uchar SEC; //00~59
uchar MIN; //00~59
uchar HR; //00-23
uchar DATE; //00-31
uchar MONTH; //01-12
uchar DAY; //01-07
uchar YEAR; //00-99
}TIME={0x00,0x22,0x16,0x11,0x05,0x05,0x18};//初始化時間參數
uchar dtime[7][2]={
{0x20,0x20}, //秒 十位和個位
{0x20,0x20}, //分 十位和個位
{0x20,0x20}, //時 十位和個位
{0x20,0x20}, //日 十位和個位
{0x20,0x20}, //月 十位和個位
{0x20,0x20}, //周 十位和個位
{0x20,0x20} //年 十位和個位
};
/********************************************************************
//函數名稱: DS1302_WByte
//函數功能: 往DS1302 寫入 1 Byte 數據
//輸入值: ndata: 寄存器的數據或地址
//返回值: 無
***********************************************************************/
void DS1302_WByte(uchar ndata)
{
uchar i;
for(i=8; i>0; i--) //循環8次寫入8位數據
{
DS1302_IO = (bit)(ndata&0x01); //取最低位數據,從0位至7位依次傳送
DS1302_SCLK = 1; //給一個脈沖,將數據寫入1302
_nop_();
DS1302_SCLK = 0;
ndata>>=1; //即ndata = ndata >> 1;
}
}
/********************************************************************
//函數名稱: DS1302_RByte
//函數功能: 從DS1302讀取 1 Byte數據
//輸入值: 無
//返回值: ndata:讀取的數據
***********************************************************************/
uchar DS1302_RByte(void)
{
uchar i;
uchar ndata=0;
for(i=8;i>0;i--) //循環8次讀出8位數據
{
DS1302_IO=1; //初始化數據IO
ndata>>=1; //即ndata = ndata >> 1;
if(DS1302_IO) ndata|=0x80; //從數據口讀取1位數據
DS1302_SCLK = 1; //給一個脈沖
_nop_();
DS1302_SCLK = 0;
}
return (ndata); //返回結果
}
/********************************************************************
//函數名稱: DS1302_Wdata
//函數功能: 往DS1302某地址寫入某數據
//輸入值: nAddr: DS1302地址, ndata: 要寫的數據
//返回值: 無
***********************************************************************/
void DS1302_Wdata(uchar nAddr, uchar ndata)
{
DS1302_RST=0;
DS1302_SCLK=0;
DS1302_RST=1;
DS1302_WByte(nAddr); // 寫1Byte地址
DS1302_WByte(ndata); // 寫1Byte數據
DS1302_SCLK=1;
DS1302_RST=0;
}
/********************************************************************
//函數名稱: DS1302_Rdata
//函數功能: 從DS1302某地址讀取數據
//輸入值: nAddr: DS1302地址
//返回值: ndata: 讀取的數據
***********************************************************************/
uchar DS1302_Rdata(uchar nAddr)
{
uchar ndata;
DS1302_RST=0;
DS1302_SCLK=0;
DS1302_RST=1;
DS1302_WByte(nAddr); /* 地址,命令 */
ndata = DS1302_RByte(); /* 讀1Byte數據 */
DS1302_SCLK=1;
DS1302_RST=0;
return(ndata);
}
/********************************************************************
//函數名稱: InitDS1302
//函數功能: DS1302初始時間設定
//輸入值: 無
//返回值: 無
***********************************************************************/
void InitDS1302(void)
{
DS1302_Wdata(0x8e,0x00); //控制命令,WP=0,寫操作
DS1302_Wdata(0x90,0xa5);
/*
地址0x90為充電寄存器,可以對充電電流進行限制,寫入
內容高4位固定為1010(其他組合均不能充電),低4
位的首2位是選擇內部降壓二極管的個數的,01代表在
充電回路串入1個二極管,10代表串入2個;最后2位可
設定串入的電阻的數值:01為2k歐,10為4k歐,11為8k歐。
*/
DS1302_Wdata(0x80,TIME.SEC); //秒
DS1302_Wdata(0x82,TIME.MIN); //分
DS1302_Wdata(0x84,TIME.HR); //時
DS1302_Wdata(0x86,TIME.DATE); //日
DS1302_Wdata(0x88,TIME.MONTH);//月
DS1302_Wdata(0x8a,TIME.DAY); //星期
DS1302_Wdata(0x8c,TIME.YEAR); //年
DS1302_Wdata(0x8e,0x80); //控制命令,WP=1,寫保護
}
/********************************************************************
//函數名稱: GetDS1302
//函數功能: DS1302當前時間讀取
//輸入值: 無
//返回值: 無
***********************************************************************/
void GetDS1302(void)
{
TIME.SEC = DS1302_Rdata(0x81); //從DS1302讀取秒數據
dtime[0][1]=(TIME.SEC>>4)+0x30; //十位
dtime[0][0]=(TIME.SEC&0x0F)+0x30; //個位
TIME.MIN = DS1302_Rdata(0x83); //從DS1302讀取分數據
dtime[1][1]=(TIME.MIN>>4)+0x30; //十位
dtime[1][0]=(TIME.MIN&0x0F)+0x30; //個位
TIME.HR = DS1302_Rdata(0x85); //從DS1302讀取時數據
dtime[2][1]=(TIME.HR>>4)+0x30; //十位
dtime[2][0]=(TIME.HR&0x0F)+0x30; //個位
TIME.DATE = DS1302_Rdata(0x87); //從DS1302讀取日數據
dtime[3][1]=(TIME.DATE>>4)+0x30; //十位
dtime[3][0]=(TIME.DATE&0x0F)+0x30; //個位
TIME.MONTH = DS1302_Rdata(0x89); //從DS1302讀取月數據
dtime[4][1]=(TIME.MONTH>>4)+0x30; //十位
dtime[4][0]=(TIME.MONTH&0x0F)+0x30; //個位
TIME.DAY = DS1302_Rdata(0x8b); //從DS1302讀取星期數據
dtime[5][1]=(TIME.DAY>>4)+0x30; //十位
dtime[5][0]=(TIME.DAY&0x0F)+0x30; //個位
TIME.YEAR = DS1302_Rdata(0x8d); //從DS1302讀取年數據
dtime[6][1]=(TIME.YEAR>>4)+0x30; //十位
dtime[6][0]=(TIME.YEAR&0x0F)+0x30; //個位
}
void delay(int ms)
{
while(ms--)
{
uchar i;
for(i=0;i<250;i++)
{
_nop_();
_nop_();
_nop_();
_nop_();
}
}
}
bit lcd_busy()
{
bit result;
P0=0X00; //關掉數碼管的信號。阻止數碼管受到P0口信號的影響
lcd_rs = 0;
lcd_rw = 1;
lcd_EN = 1;
delay(1);
result = (bit)(P0&0x80);
lcd_EN = 0;
return(result);
}
void lcd_init(void)
{
lcd_psb = 1; //并口方式
lcd_wcmd(0x34); //擴展指令
delay(5);
lcd_wcmd(0x30); //基本指令
delay(5);
lcd_wcmd(0x0c); //顯示光標開關
delay(5);
lcd_wcmd(0x01); //清除lcd的顯示內容
delay(5);
}
void lcd_wcmd(uchar cmd)
{
while(lcd_busy());
lcd_rs = 0;
lcd_rw = 0;
lcd_EN = 0;
lcd_data=cmd;
delay(1);
lcd_EN = 1;
delay(1);
lcd_EN = 0;
}
void DisplayDdram(uchar *hz)
{
while(*hz!= '\0')
{
lcd_wdata(*hz);//地址里面的值
hz++;
}
}
void lcd_wdata(uint dat)
{
while(lcd_busy());
lcd_rs = 1;
lcd_rw = 0;
lcd_EN = 0;
lcd_data = dat;
delay(1);
lcd_EN = 1;
delay(1);
lcd_EN = 0;
}
void lcd_pos(uchar x,uchar y)
{
uchar pos;
if(x==0)
{
x = 0x80;
}else if(x==1)
{
x= 0x90;
}else if(x==2)
{
x = 0x88;
}else if(x==3)
{
x = 0x98;
}
pos = x + y;
lcd_wcmd(pos);
}void main()
{
lcd_init();
while(1)
{
lcd_pos(1,3);
DisplayDdram("dtime[0][1]");
lcd_pos(1,4);
DisplayDdram("dtime[0][0]");
}
|