第三十课 DS1302之一 数码管显示时钟
程序讲解:
1、DS1302头文件
/*--------------------------------------------------------------*/
//File : DS1302_A.H
//Author : NULL
//Created: 2008/6/18
/*--------------------------------------------------------------*/
#ifndef __DS1302_A_H__
#define __DS1302_A_H__
/*--------------------------------------------------------------*/
//引脚及位的定义
sbit DS1302_CLK = P2^0; //时钟引脚
sbit DS1302_IO = P2^1; //数据引脚
sbit DS1302_RST = P2^2; //复位引脚
sbit ACC0 = ACC^0;
bit ACC7 = ACC^7;
/*--------------------------------------------------------------*/
//宏定义便于理解
#define unchar unsigned char
#define unint unsigned int
#define DS1302_SECOND 0x80
#define DS1302_MINUTE 0x82
#define DS1302_HOUR 0x84
#define DS1302_WEEK 0x8A
#define DS1302_DAY 0x86
#define DS1302_MONTH 0x88
#define DS1302_YEAR 0x8C
#define DS1302_RAM(X) (0xC0+(X)*2) //用于计算RAM地址的宏运算
/*--------------------------------------------------------------*/
//定义时间类型
typedef struct _SYSTEMTIME_
{
unchar Second;
unchar Minute;
unchar Hour;
unchar Week;
unchar Day;
unchar Month;
unchar Year;
}SYSTEMTIME;
/*--------------------------------------------------------------*/
//函数声明
void DS1302_InputByte(unchar Data); //写入一个字节(内部函数)
unchar DS1302_OutputByte(void); //读取一个字节(内部函数)
void Write1302(unchar Address, unchar Data); //在指定地址写入指定的数据
unchar Read1302(unchar Address); //读取DS1302指定地址中的数据
void DS1302_SetProtect(bit Flag); //DS1302是否写入保护
void DS1302_SetTime(unchar Address, unchar Value);//设置时间函数
void DS1302_GetTime(SYSTEMTIME *Time); //读出时间
void DS1302_Initial (void); //DS1302初始化
/*--------------------------------------------------------------*/
//写入一个字节(内部函数)
void DS1302_InputByte(unchar Data)
{
unchar i;
ACC = Data;
for(i=8; i>0; i--)
{
DS1302_CLK = 0;
DS1302_IO = ACC0; //由低位到高位
DS1302_CLK = 1; //上升沿写入数据
ACC >>= 1;
}
}
/*--------------------------------------------------------------*/
//读取一个字节(内部函数)
unchar DS1302_OutputByte(void)
{
unchar i;
for(i=8; i>0; i--)
{
DS1302_CLK = 0; //下降沿读出DS1302的数据
ACC >>= 1; //读出由低到高位,只能移7次有效位!!!
ACC7 = DS1302_IO; //第一个数据
DS1302_CLK = 1;
}
return (ACC);
}
/*--------------------------------------------------------------*/
//在指定地址写入指定的数据
void Write1302(unchar Address, unchar Data)
{
DS1302_RST = 0;
DS1302_CLK = 0;
DS1302_RST = 1;
DS1302_InputByte(Address);
DS1302_InputByte(Data);
DS1302_CLK = 1;
DS1302_RST = 0;
}
/*--------------------------------------------------------------*/
//读取1302指定地址中的数据
unchar Read1302(unchar Address)
{
unchar Data;
DS1302_RST = 0;
DS1302_CLK = 0;
DS1302_RST = 1; //RST拉高,启动数据传送
DS1302_InputByte(Address|0x01); //读取指定地址数据指令
Data = DS1302_OutputByte();
DS1302_CLK = 1;
DS1302_RST = 0;
return (Data);
}
/*--------------------------------------------------------------*/
//是否写入保护
void DS1302_SetProtect(bit Flag)
{
if(Flag)
Write1302(0x8E,0x80); //0x8e控制字节地址,bit7=WP WP="1" 禁止数据写入DS1302
else
Write1302(0x8E,0x00); //WP=0 允许数据写入DS1302
}
/*--------------------------------------------------------------*/
//设置时间函数
void DS1302_SetTime(unchar Address, unchar Value)
{
DS1302_SetProtect(0);
Write1302(Address,((Value/10)<<4|(Value%10)));
DS1302_SetProtect(1);
}
/*--------------------------------------------------------------*/
//读出时间
void DS1302_GetTime(SYSTEMTIME *Time)
{
unchar ReadValue;
ReadValue = Read1302(DS1302_SECOND);
Time->Second = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
ReadValue = Read1302(DS1302_MINUTE);
Time->Minute = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
ReadValue = Read1302(DS1302_HOUR);
Time->Hour = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
ReadValue = Read1302(DS1302_DAY);
Time->Day = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
ReadValue = Read1302(DS1302_WEEK);
Time->Week = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
ReadValue = Read1302(DS1302_MONTH);
Time->Month = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
ReadValue = Read1302(DS1302_YEAR);
Time->Year = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
}
/*--------------------------------------------------------------*/
//初始化DS1302
void DS1302_Initial (void)
{
unchar Second="Read1302"(DS1302_SECOND);
if(Second&0x80)//bit7=CH CH="0" 振荡器允许工作,CH=1振荡器停止工作
DS1302_SetTime(DS1302_SECOND,0);
}
/*--------------------------------------------------------------*/
#endif
2、主程序:
/*--------------------------------------------------------------*/
//包含头文件
#include <AT89X52.H>
#include "74HC595.H"
#include "DS1302_A.H"
/*--------------------------------------------------------------*/
//键盘接口定义 (对应开发板硬件)
bit K1 = P3^2;
sbit K2 = P3^3;
sbit K3 = P3^4;
/*--------------------------------------------------------------*/
//定义相关变量
unsigned char time[8]; //时分秒拆位
/*--------------------------------------------------------------*/
//定时器初始化
void Timer_init(void)
{
TMOD = 0x11;
TH1 = 0xf8; //2000us
TL1 = 0x36;
EA= 1;
ET1=1;
TR1 = 1;
}
/*--------------------------------------------------------------*/
//延时5000+0us 函数定义
void delay5ms(void)
{
unsigned char i,j;
for(i=185;i>0;i--)
for(j=12;j>0;j--);
}
/*--------------------------------------------------------------*/
//T1定时器中断服务
void T1_intservice(void) interrupt 3 using 1
{
unsigned char i;
TH1 = 0xf8; //2000us
TL1 = 0x36;
for(i = 0; i <8 ; i++)
{
Ser_IN( pos ); //片选
Ser_IN( seg[ time ] ); //段码
Par_OUT();
if(i == 2 || i == 5) time = 10; //显示"-"
}
}
/*--------------------------------------------------------------*/
//主函数
void main(void)
{
SYSTEMTIME CurrentTime; //定义CurrentTime为结构体
Timer_init();
DS1302_Initial();
while(1)
{
DS1302_GetTime(&CurrentTime); //送到显示缓冲区
time[0] = CurrentTime.Second%10;
time[1] = CurrentTime.Second/10;
time[3] = CurrentTime.Minute%10;
time[4] = CurrentTime.Minute/10;
time[6] = CurrentTime.Hour%10;
time[7] = CurrentTime.Hour/10;
//按键调时
if(K1 == 0)
{
delay5ms();
if(K1 == 0) DS1302_SetTime(DS1302_SECOND, ++CurrentTime.Second & 0x3f);
}
if(K2 == 0)
{
delay5ms();
if(K2 == 0) DS1302_SetTime(DS1302_MINUTE, ++CurrentTime.Minute & 0x3f);
}
if(K3 == 0)
{
delay5ms();
if(K3 == 0) DS1302_SetTime(DS1302_HOUR, ++CurrentTime.Hour & 0x1f);
}
}
}
本节重点:
1、结构体的应用
2、DS1302的读写时序的理解及程序的编写
演示视频:http://v.youku.com/v_show/id_XOTIzNjQzMDQ=.html
相关程序:https://static.assets-stash.eet-china.com/album/old-resources/2009/6/5/e21046a0-4228-4d5f-8a6f-c9e67426bdc1.rar
用户1503789 2009-6-28 15:06
用户191597 2009-6-10 21:38