本文是在学习江科大51单片机DS1302定时器教程后所做的笔记
所用软件 μvision4
是由美国DALLAS公司推出的具有涓细电流充电能力的低功耗实时时钟芯片。它可以对年、月、日、周、时、分、秒进行计时,且具有闰年补偿等多种功能
图1
图2
图3
图4
配置寄存器需配置8位
READ 读取所调用的地址,例如我想读取此时DS1302芯片中的时间
unsigned char DS1302_ReadByte(unsigned char Command)//读取字节
{
unsigned char i,Data=0x00;
Command |= 0x01; //将传入的Command地址第一位置为1,变成READ的地址
DS1302_CE=1;
for(i=0;i<8;i++)
{
DS1302_IO=Command&(0x01<
WRITE 写入所调用的地址
void DS1302_WriteByte(unsigned char Command,Data)//这个是根据图4的时序图写的"写入字节函数"
{
unsigned char i;
DS1302_CE=1;
for(i=0;i<8;i++)
{
DS1302_IO=Command&(0x01<
DS1302里是用BCD码储存的时间,即四个字节代表一个十进制的数
因此对DS1302执行一些操作时要将BCD码转为十进制,公式如下:
以下是调用的.h文件与.c文件,是我跟着江科大的一起敲的,在共享一下:
#ifndef _DS1302_H_
#define_DS1302_H_
extern unsigned char DS1302_Time[];
void DS1302_Init(void);
void DS1302_WriteByte(unsigned char Command,Data);
unsigned char DS1302_ReadByte(unsigned char Command);
void DS1302_ReadTime(void) ;
void DS1302_SetTime(void);
#endif
#include
sbit DS1302_SCLK = P3^6;
sbit DS1302_IO = P3^4;
sbit DS1302_CE = P3^5;
//这部分是图3时间地址的重定义,是为了后续方便操作
#define DS1302_Second 0x80
#define DS1302_Minutes 0x82
#define DS1302_Hour 0x84
#define DS1302_Date 0x86
#define DS1302_Month 0x88
#define DS1302_Day 0x8A
#define DS1302_Year 0x8C
#define DS1302_WP 0x8E
unsigned char DS1302_Time[]={23,2,23,9,16,30,1};//用一个数组存放十进制的时间
void DS1302_Init()
{
DS1302_CE=0;
DS1302_SCLK=0;
}
//以下是基于时序图编写的读取和写入DS1302芯片的代码
//DS1302_WriteByte字节写入 DS1302_ReadByte字节读取
//Command是写入时间的地址,Data是写入的时间数据(BCD码)
//DS1302_WriteByte 根据图4的时序图写的"写入字节函数"
void DS1302_WriteByte(unsigned char Command,Data)
{
unsigned char i;
DS1302_CE=1;
for(i=0;i<8;i++)
{
DS1302_IO=Command&(0x01<
#include
#include "DS1302.h"
#include "LCD1602.h"
#include "Timer0.h"
#include "MatrixKey.h"
#include "Key.h"
unsigned char KeyNum,Mode=0,TimeSetSelect=0,TimeSetFlashFlag;
void Time_Show()
{
DS1302_ReadTime();
LCD_ShowNum(1,1,DS1302_Time[0],2);
LCD_ShowNum(1,4,DS1302_Time[1],2);
LCD_ShowNum(1,7,DS1302_Time[2],2);
LCD_ShowNum(2,1,DS1302_Time[3],2);
LCD_ShowNum(2,4,DS1302_Time[4],2);
LCD_ShowNum(2,7,DS1302_Time[5],2);
}
void Time_Set()
{
//判断模式选择按钮是否按下
if(KeyNum==2)
{
TimeSetSelect++;
TimeSetSelect%=6;
}
//加减年月日判断
if(KeyNum==3)
{
DS1302_Time[TimeSetSelect]++;
if(DS1302_Time[0]>99){DS1302_Time[0]=0;}
if(DS1302_Time[1]>12){DS1302_Time[1]=1;}
//日
if(DS1302_Time[1]==1 || DS1302_Time[1]==3 || DS1302_Time[1]==5 || DS1302_Time[1]==7
|| DS1302_Time[1]==8 || DS1302_Time[1]==10 || DS1302_Time[1]==12)
{
if(DS1302_Time[2]>31){DS1302_Time[2]=1;}
}
else if(DS1302_Time[1]==4 || DS1302_Time[1]==6 || DS1302_Time[1]==9 || DS1302_Time[1]==11)
{
if(DS1302_Time[2]>30){DS1302_Time[2]=1;}
}
else if(DS1302_Time[1]==2)
{
if(DS1302_Time[0]%4==0)
{
if(DS1302_Time[2]>29){DS1302_Time[2]=1;}
}
else
{
if(DS1302_Time[2]>28){DS1302_Time[2]=1;}
}
}
if(DS1302_Time[3]>23){DS1302_Time[3]=0;}
if(DS1302_Time[4]>59){DS1302_Time[4]=0;}
if(DS1302_Time[5]>59){DS1302_Time[5]=0;}
}
//减年月日判断
if(KeyNum==4)
{
DS1302_Time[TimeSetSelect]--;
if(DS1302_Time[0]<0){DS1302_Time[0]=99;}
if(DS1302_Time[1]<1){DS1302_Time[1]=12;}
//日
if(DS1302_Time[1]==1 || DS1302_Time[1]==3 || DS1302_Time[1]==5 || DS1302_Time[1]==7
|| DS1302_Time[1]==8 || DS1302_Time[1]==10 || DS1302_Time[1]==12)
{
if(DS1302_Time[2]<1){DS1302_Time[2]=31;}
if(DS1302_Time[2]>31){DS1302_Time[2]=1;}
}
else if(DS1302_Time[1]==4 || DS1302_Time[1]==6 || DS1302_Time[1]==9 || DS1302_Time[1]==11)
{
if(DS1302_Time[2]<1){DS1302_Time[2]=30;}
if(DS1302_Time[2]>30){DS1302_Time[2]=1;}
}
else if(DS1302_Time[1]==2)
{
if(DS1302_Time[0]%4==0)
{
if(DS1302_Time[2]<1){DS1302_Time[2]=29;}
if(DS1302_Time[2]>29){DS1302_Time[2]=1;}
}
else
{
if(DS1302_Time[2]<1){DS1302_Time[2]=28;}
if(DS1302_Time[2]>28){DS1302_Time[2]=1;}
}
}
if(DS1302_Time[3]<0){DS1302_Time[3]=23;}
if(DS1302_Time[4]<0){DS1302_Time[4]=59;}
if(DS1302_Time[5]<0){DS1302_Time[5]=59;}
}
if(TimeSetSelect==0 && TimeSetFlashFlag==1){LCD_ShowString(1,1," ");}
else{LCD_ShowNum(1,1,DS1302_Time[0],2);}
if(TimeSetSelect==1 && TimeSetFlashFlag==1){LCD_ShowString(1,4," ");}
else{LCD_ShowNum(1,4,DS1302_Time[1],2);}
if(TimeSetSelect==2 && TimeSetFlashFlag==1){LCD_ShowString(1,7," ");}
else{LCD_ShowNum(1,7,DS1302_Time[2],2);}
if(TimeSetSelect==3 && TimeSetFlashFlag==1){LCD_ShowString(2,1," ");}
else{LCD_ShowNum(2,1,DS1302_Time[3],2);}
if(TimeSetSelect==4 && TimeSetFlashFlag==1){LCD_ShowString(2,4," ");}
else{LCD_ShowNum(2,4,DS1302_Time[4],2);}
if(TimeSetSelect==5 && TimeSetFlashFlag==1){LCD_ShowString(2,7," ");}
else{LCD_ShowNum(2,7,DS1302_Time[5],2);}
//LCD_ShowNum(2,10,TimeSetSelect,2);
//LCD_ShowNum(2,13,TimeSetFlashFlag,2);
}
void main()
{
LCD_Init();
DS1302_Init();
Timer0_Init();
LCD_ShowString(1,1," - - ");
LCD_ShowString(2,1," : : ");
DS1302_SetTime();
while(1)
{
KeyNum=Key();
if(KeyNum==1)
{
if(Mode==0){Mode=1;TimeSetSelect=0;}
else if (Mode==1){Mode=0;DS1302_SetTime();}
}
switch(Mode)
{
case 0:Time_Show();break;
case 1:Time_Set();break;
}
}
}
void Timer0_Routine() interrupt 1
{
static unsigned int T0Count;
TL0 = 0x18; //设置定时初值
TH0 = 0xFC; //设置定时初值
T0Count++;
if(T0Count>=500)//ms
{
T0Count=0;
TimeSetFlashFlag=!TimeSetFlashFlag;
}
}
如有不太懂的同学可以观看视频:江科大51单片机DS1302定时可调时钟
受码龄6年的大佬大一同学口头训话,说学这一块一定要写博客
因此,作者这是作者的第二篇博客,也逐渐了解到,写博客不仅仅是对所学知识作的笔记,更是一种思考、归纳与提高。
2023.2.24
21:51
于深圳大学机电与控制工程学院ROS俱乐部