原创 第三十课 DS1302之一 数码管显示时钟

2009-6-5 21:46 5431 10 10 分类: MCU/ 嵌入式

第三十课 DS1302之一 数码管显示时钟


器件手册:1、中文版:pdf     2、英文版:pdf


程序讲解:


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


 


 

PARTNER CONTENT

文章评论2条评论)

登录后参与讨论

用户1503789 2009-6-28 15:06

谢谢

用户191597 2009-6-10 21:38

学习了
相关推荐阅读
用户222124 2010-12-08 22:18
台达PLC监控
台达PLC监控网上有很多例子,自己也照着弄了个,挺方便的,分享下串口数据格式:COM1,9600,8,N,1  ...
用户222124 2010-06-27 16:36
基于NIOS II和FPGA无线小车控制系统的设计
   主控制台以Cyclone II系列的EP2C8Q208C8为核心,通过nRF24L01进行无线通讯,来控制以ATmega8为微处理器的两轮小车,可以实现小车按控制平台发送的控制信息来准确运动。所...
用户222124 2009-11-13 15:58
51开发板已经销售完了,谢谢大家的支持!
51开发板已经销售完了,谢谢大家的支持!...
用户222124 2009-09-28 16:13
51开发板十一大放送!!!赶快行动吧!!!
  51开发板十一大放送!  赶快行动吧!!!   开发板硬件介绍: http://group.ednchina.com/2031/24972.aspx  开发板实物图片总汇: http://grou...
用户222124 2009-09-13 19:02
nios II 实验五 数码管显示数字钟(定时器实现 外部中断调节)
#include "system.h"                      //包含基本的硬件描述信息#include "altera_avalon_timer_regs.h"    //定义内...
用户222124 2009-09-13 18:57
nios II 实验四 PIO外部中断
#include "system.h"                      //包含基本的硬件描述信息#include "altera_avalon_timer_regs.h"    //定义内...
我要评论
2
10
关闭 站长推荐上一条 /3 下一条