/*====================================
GN1302时钟驱动程序案例参考
====================================*/
//调用1602显示驱动,在此文件内已包含51头文件和定义数据类型
#include "LCD1602.h"
/*====================================
IO接口定义
====================================*/
sbit TSCLK = P1^0; //时钟
sbit TIO = P1^1; //数据
sbit TRST = P1^2; //使能
#define MAIN_Fosc 11059200UL //宏定义主时钟HZ
#define GN1302_W_ADDR 0x80 //写时钟日历寄存器起始地址
#define GN1302_R_ADDR 0x81 //读时钟日历寄存器起始地址
//时钟日历暂存数组,秒、分、时、日、月、周、年 初值为= 21年9月1日 周3 00:00:00
//用作上电初始化配置时间使用
uchar TimeData[7]={0, 0, 0, 1, 9, 3, 21};
/*=================================================
*函数名称:Delay_Ms
*函数功能:12T 51单片机自适应主时钟毫秒级延时函数
*说明:需定义MAIN_Fosc(晶振主频单位HZ)
*输入:ms:要延时的毫秒
=================================================*/
void Delay_Ms(INT16U ms)
{
INT16U i;
do
{
i = MAIN_Fosc / 96000;
while(--i); //96T per loop
}
while(--ms);
}
/*=================================================
*函数名称:GN1302_W_Byte
*函数功能:GN1302写一字节数据
*输入:dat:要写入的数据
=================================================*/
void GN1302_W_Byte(uchar dat)
{
uchar i;
for(i = 0; i < 8; i++) //每次写1bit,写8次
{
TSCLK = 0; //拉低时钟总线
TIO = dat & 0x01; //从一字节最低位开始写
TSCLK = 1; //拉高时钟总线,GN1302把数据读走
dat >>= 1; //数据右移一位
}
}
/*=================================================
*函数名称:GN1302_R_Byte
*函数功能:GN1302读一字节
*输出:dat:读取的数据
=================================================*/
uchar GN1302_R_Byte()
{
uchar i, dat;
for(i = 0; i < 8; i++) //每次写1bit,写8次
{
TSCLK = 0; //拉低时钟总线,GN1302把数据放到数据总线上
dat >>= 1; //数据右移一位,数据从最低位开始读
if(TIO) dat |= 0x80;//读取数据
TSCLK = 1; //拉高时钟总线
}
return dat; //返回读取的数据
}
/*=================================================
*函数名称:GN1302_W_DAT
*函数功能:写GN1302数据一次写2个字节
*说明:先写命令后写数据
*调用:GN1302_W_Byte()
*输入:cmd:需要写的命令 ,dat:需要些的数据
=================================================*/
void GN1302_W_DAT(uchar cmd, uchar dat)
{
TRST = 0; //拉低使能端
TSCLK = 0; //拉低数据总线
TRST = 1; //拉高使能端,开始写数据
GN1302_W_Byte(cmd); //写命令
GN1302_W_Byte(dat); //写数据
}
/*=================================================
*函数名称:GN1302_R_DAT
*函数功能:读GN1302数据
*说明:先写入命令字节后读出对应数据
*调用: GN1302_W_Byte();GN1302_R_Byte();
*输入: cmd:需要写的命令
*输出: dat:读出的数据
=================================================*/
uchar GN1302_R_DAT(uchar cmd)
{
uchar dat;
TRST = 0; //拉低使能端
TSCLK = 0; //拉低数据总线
TRST = 1; //拉高使能端,开始写数据
GN1302_W_Byte(cmd); //写命令
dat = GN1302_R_Byte(); //读出数据
return dat; //返回读出数据
}
/*=================================================
*函数名称:GN1302_Clear_WP
*函数功能:清除GN1302写保护
*说明:先写入命令0x8e(写控制寄存器)接着向该寄存器写0x00
*调用:GN1302_W_DAT()
=================================================*/
void GN1302_Clear_WP()
{
GN1302_W_DAT(0x8e,0x00); //把控制寄存器WP位置0
}
/*=================================================
*函数名称:GN1302_Set_WP
*函数功能:设置GN1302写保护
*说明:先写入命令0x8e(写控制寄存器)接着向该寄存器写0x80
*调用:GN1302_W_DAT()
=================================================*/
void GN1302_Set_WP()
{
GN1302_W_DAT(0x8e,0x80); //把控制寄存器WP位置1
TRST = 0; //拉低使能端
TSCLK = 0; //拉低数据总线
}
/*=================================================
*函数名称:Set_GN1302_Time
*函数功能:设置GN1302时钟日历数据
*说明:把时钟日历暂存数组TimeData数据转换为BCD码并写入到GN1302时钟日历寄存器中
*调用:GN1302_Clear_WP();GN1302_W_DAT();GN1302_Set_WP();
*输入:addr:需要写入寄存器的地址 ,TimeData数组:时钟日历初始值
=================================================*/
void Set_GN1302_Time(uchar addr)
{
uchar i, j;
GN1302_Clear_WP(); //清除写保护
for(i = 0; i < 7; i++) //写入7个字节的时钟初始值
{
j = TimeData[i]/10; //BCD码转换
TimeData[i] %= 10; //BCD码转换
TimeData[i] += j*16; //BCD码转换
GN1302_W_DAT(addr, TimeData[i]); //先写GN1302时钟日历起始地址,再写数据
addr += 2; //时钟日历寄存器地址+2转向下一个寄存器
}
GN1302_Set_WP(); //开起写保护
}
/*=================================================
*函数名称:Read_GN1302_Time
*函数功能:读取GN1302时钟数据
*说明: 读取GN1302时钟数据 返回数据存入时钟日历暂存
数组TimeData(数据格式BCD码)
*调用:GN1302_Clear_WP();GN1302_R_DAT();GN1302_Set_WP();
*输入: addr:需要读取时钟日历寄存器的起始地址
=================================================*/
void Read_GN1302_Time(uchar addr)
{
uchar i;
GN1302_Clear_WP(); //清楚些保护
for(i = 0; i < 7; i++) //从GN1302读取7个字节的时钟日历数据
{
TimeData[i] = GN1302_R_DAT(addr);//先写入要读取数据的寄存器起始地址,再读出数据存入TimeData数组
addr += 2; //时钟日历寄存器地址+2转向下一个寄存器
}
GN1302_Set_WP(); //开起写保护
}
/*=================================================
*函数名称:main
*函数功能:主函数 1602液晶显示GN1302数据
Date:年-月-日-星期
Time:时:分:秒
=================================================*/
void main()
{
InitLcd1602(); //1602初始化
Set_GN1302_Time(GN1302_W_ADDR); //先写入时钟日历寄存器起始地址再设置时钟日历初值
LcdShowStr(0,0,"Date:"); //1602显示字符串
LcdShowStr(0,1,"Time:"); //1602显示字符串
while(1)
{
Read_GN1302_Time(GN1302_R_ADDR); //先写入时钟日历寄存器起始地址再读出时钟日历写入到TimeData数组中
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]); //时
DisplayOneChar (8,1,':'); //:
DisplayOneStr (9,1,TimeData[1]); //分
DisplayOneChar (11,1,':'); //:
DisplayOneStr (12,1,TimeData[0]);//秒
Delay_Ms(1000); //延时1秒
}
}
审核编辑 黄昊宇
评论
查看更多