/*====================================
GN1302時(shí)鐘驅(qū)動(dòng)程序案例參考
====================================*/
//調(diào)用1602顯示驅(qū)動(dòng),在此文件內(nèi)已包含51頭文件和定義數(shù)據(jù)類型
#include "LCD1602.h"
/*====================================
IO接口定義
====================================*/
sbit TSCLK = P1^0; //時(shí)鐘
sbit TIO = P1^1; ? //數(shù)據(jù)
sbit TRST = P1^2; ?//使能
#define MAIN_Fosc ?11059200UL ?//宏定義主時(shí)鐘HZ
#define GN1302_W_ADDR 0x80 ? ? //寫時(shí)鐘日歷寄存器起始地址
#define GN1302_R_ADDR 0x81 ? ? //讀時(shí)鐘日歷寄存器起始地址
//時(shí)鐘日歷暫存數(shù)組,秒、分、時(shí)、日、月、周、年 初值為= 21年9月1日 周3 00:00:00
//用作上電初始化配置時(shí)間使用
uchar TimeData[7]={0, 0, 0, 1, 9, 3, 21};
/*=================================================
*函數(shù)名稱:Delay_Ms
*函數(shù)功能:12T 51單片機(jī)自適應(yīng)主時(shí)鐘毫秒級(jí)延時(shí)函數(shù)
*說明:需定義MAIN_Fosc(晶振主頻單位HZ)
*輸入:ms:要延時(shí)的毫秒
=================================================*/
void Delay_Ms(INT16U ms)
{
?INT16U i;
?do
?{
?i = MAIN_Fosc / 96000;?
?while(--i); ? ? //96T per loop
?}
?while(--ms);
}
/*=================================================
*函數(shù)名稱:GN1302_W_Byte
*函數(shù)功能:GN1302寫一字節(jié)數(shù)據(jù)
*輸入:dat:要寫入的數(shù)據(jù)
=================================================*/
void GN1302_W_Byte(uchar dat)
{
uchar i;
for(i = 0; i < 8; i++) //每次寫1bit,寫8次
{
?TSCLK = 0; ? ?//拉低時(shí)鐘總線
?TIO = dat & 0x01; ?//從一字節(jié)最低位開始寫
?TSCLK = 1; ? ?//拉高時(shí)鐘總線,GN1302把數(shù)據(jù)讀走
?dat >>= 1; ? ?//數(shù)據(jù)右移一位?
}?
}
/*=================================================
*函數(shù)名稱:GN1302_R_Byte
*函數(shù)功能:GN1302讀一字節(jié)
*輸出:dat:讀取的數(shù)據(jù)
=================================================*/
uchar GN1302_R_Byte()
{
uchar i, dat;
for(i = 0; i < 8; i++) ?//每次寫1bit,寫8次
{
?TSCLK = 0; ? ? //拉低時(shí)鐘總線,GN1302把數(shù)據(jù)放到數(shù)據(jù)總線上
?dat >>= 1; ? ? ?//數(shù)據(jù)右移一位,數(shù)據(jù)從最低位開始讀?
?if(TIO) dat |= 0x80;//讀取數(shù)據(jù)
?TSCLK = 1; ? ? //拉高時(shí)鐘總線
}
return dat; ? ? ?//返回讀取的數(shù)據(jù)
}
/*=================================================
*函數(shù)名稱:GN1302_W_DAT
*函數(shù)功能:寫GN1302數(shù)據(jù)一次寫2個(gè)字節(jié)
*說明:先寫命令后寫數(shù)據(jù)
*調(diào)用:GN1302_W_Byte()
*輸入:cmd:需要寫的命令 ,dat:需要些的數(shù)據(jù)
=================================================*/
void GN1302_W_DAT(uchar cmd, uchar dat)
{
TRST = 0; ? //拉低使能端
TSCLK = 0; ? ? ? ? ?//拉低數(shù)據(jù)總線
TRST = 1; ? //拉高使能端,開始寫數(shù)據(jù)
GN1302_W_Byte(cmd); ?//寫命令
GN1302_W_Byte(dat); ?//寫數(shù)據(jù)
}
/*=================================================
*函數(shù)名稱:GN1302_R_DAT
*函數(shù)功能:讀GN1302數(shù)據(jù)
*說明:先寫入命令字節(jié)后讀出對(duì)應(yīng)數(shù)據(jù)
*調(diào)用: GN1302_W_Byte();GN1302_R_Byte();
*輸入: cmd:需要寫的命令
*輸出: dat:讀出的數(shù)據(jù)
=================================================*/
uchar GN1302_R_DAT(uchar cmd)
{
uchar dat;
TRST = 0; ? //拉低使能端
TSCLK = 0; ? //拉低數(shù)據(jù)總線
TRST = 1; ? //拉高使能端,開始寫數(shù)據(jù)
GN1302_W_Byte(cmd); ?//寫命令
dat = GN1302_R_Byte(); ?//讀出數(shù)據(jù)
return dat; ? //返回讀出數(shù)據(jù)
}
/*=================================================
*函數(shù)名稱:GN1302_Clear_WP
*函數(shù)功能:清除GN1302寫保護(hù)
*說明:先寫入命令0x8e(寫控制寄存器)接著向該寄存器寫0x00
*調(diào)用:GN1302_W_DAT()
=================================================*/
void GN1302_Clear_WP()
{
GN1302_W_DAT(0x8e,0x00); ?//把控制寄存器WP位置0
}
/*=================================================
*函數(shù)名稱:GN1302_Set_WP
*函數(shù)功能:設(shè)置GN1302寫保護(hù)
*說明:先寫入命令0x8e(寫控制寄存器)接著向該寄存器寫0x80
*調(diào)用:GN1302_W_DAT()
=================================================*/
void GN1302_Set_WP()
{?
GN1302_W_DAT(0x8e,0x80); //把控制寄存器WP位置1
TRST = 0; ? //拉低使能端
TSCLK = 0; ? //拉低數(shù)據(jù)總線
}?
/*=================================================
*函數(shù)名稱:Set_GN1302_Time
*函數(shù)功能:設(shè)置GN1302時(shí)鐘日歷數(shù)據(jù)
*說明:把時(shí)鐘日歷暫存數(shù)組TimeData數(shù)據(jù)轉(zhuǎn)換為BCD碼并寫入到GN1302時(shí)鐘日歷寄存器中
*調(diào)用:GN1302_Clear_WP();GN1302_W_DAT();GN1302_Set_WP();
*輸入:addr:需要寫入寄存器的地址 ,TimeData數(shù)組:時(shí)鐘日歷初始值
=================================================*/
void Set_GN1302_Time(uchar addr)
{
uchar i, j;
GN1302_Clear_WP(); ? ? ?//清除寫保護(hù)
for(i = 0; i < 7; i++) ? ? ?//寫入7個(gè)字節(jié)的時(shí)鐘初始值
{
?j = TimeData[i]/10; ? ? ? ? ? ? ?//BCD碼轉(zhuǎn)換
?TimeData[i] %= 10; ? ? ? ? ? ? ? //BCD碼轉(zhuǎn)換
?TimeData[i] += j*16; ? ? ? ? ? ? //BCD碼轉(zhuǎn)換
?GN1302_W_DAT(addr, TimeData[i]); //先寫GN1302時(shí)鐘日歷起始地址,再寫數(shù)據(jù)
?addr += 2; ? ? ? ? ? ? ? ? ? //時(shí)鐘日歷寄存器地址+2轉(zhuǎn)向下一個(gè)寄存器
}
GN1302_Set_WP(); ? ? ? ? ? ? //開起寫保護(hù) ?
}
/*=================================================
*函數(shù)名稱:Read_GN1302_Time
*函數(shù)功能:讀取GN1302時(shí)鐘數(shù)據(jù)
*說明: 讀取GN1302時(shí)鐘數(shù)據(jù) 返回?cái)?shù)據(jù)存入時(shí)鐘日歷暫存
?數(shù)組TimeData(數(shù)據(jù)格式BCD碼)
*調(diào)用:GN1302_Clear_WP();GN1302_R_DAT();GN1302_Set_WP();
*輸入: addr:需要讀取時(shí)鐘日歷寄存器的起始地址
=================================================*/
void Read_GN1302_Time(uchar addr)
{
uchar i;
GN1302_Clear_WP(); ? ? //清楚些保護(hù)
for(i = 0; i < 7; i++) //從GN1302讀取7個(gè)字節(jié)的時(shí)鐘日歷數(shù)據(jù)
{
?TimeData[i] = GN1302_R_DAT(addr);//先寫入要讀取數(shù)據(jù)的寄存器起始地址,再讀出數(shù)據(jù)存入TimeData數(shù)組
?addr += 2; ? ? ? ? ? ? ? ? ? //時(shí)鐘日歷寄存器地址+2轉(zhuǎn)向下一個(gè)寄存器
}
GN1302_Set_WP(); ? ? ? ?//開起寫保護(hù)
}?
/*=================================================
*函數(shù)名稱:main
*函數(shù)功能:主函數(shù) 1602液晶顯示GN1302數(shù)據(jù)
? ? Date:年-月-日-星期
? ? Time:時(shí):分:秒
=================================================*/
void main()
{
InitLcd1602(); ? ? ? ? ? ? ? //1602初始化
Set_GN1302_Time(GN1302_W_ADDR); //先寫入時(shí)鐘日歷寄存器起始地址再設(shè)置時(shí)鐘日歷初值
?
LcdShowStr(0,0,"Date:"); ?//1602顯示字符串
LcdShowStr(0,1,"Time:"); ?//1602顯示字符串
while(1)
{
?Read_GN1302_Time(GN1302_R_ADDR); //先寫入時(shí)鐘日歷寄存器起始地址再讀出時(shí)鐘日歷寫入到TimeData數(shù)組中
?DisplayOneStr (5,0,TimeData[6]); //年
?DisplayOneChar (7,0,'-'); ? //-
?DisplayOneStr (8,0,TimeData[4]); //月
?DisplayOneChar (10,0,'-'); ? //-
?DisplayOneStr (11,0,TimeData[3]);//日
?DisplayOneChar (13,0,'-'); ? //-
?DisplayOneStr (14,0,TimeData[5]);//星期
DisplayOneStr (6,1,TimeData[2]); //時(shí)
?DisplayOneChar (8,1,':'); ? //:
?DisplayOneStr (9,1,TimeData[1]); //分
?DisplayOneChar (11,1,':'); ? //:
?DisplayOneStr (12,1,TimeData[0]);//秒
?Delay_Ms(1000); ? ? ?//延時(shí)1秒
} ?
}
審核編輯?黃昊宇
?
評(píng)論