10 51单片机之DS1302实时时钟
文章目录
- 1、前言
- 2、DS1302
- 2-1、芯片简介
- 2-2、RTC
- 3、DS1302 Datasheet
- 3-1、引脚定义及应用电路
- 3-2、硬件电路
- 3-3、内部结构框图
- 3-4、寄存器定义
- 3-5、地址命令字
- 3-6、时序定义
- 3-6-1、CE与时钟控制
- 3-6-2、数据输入
- 3-6-3、数据输出
- 3-6-4、脉冲串模式
- 3-6-5、时钟/日历
- 3-6-6、时钟暂停标志
- 3-6-7、写保护位
- 4、工程编码
- 4-1、基础功能
- 4-2、按键操作
- 4-3、实验结果
- 参考资料
1、前言
在前面的文章中介绍了51单片机之LED点阵屏,今天介绍单片机的LED点阵屏。
2、DS1302
2-1、芯片简介
DS1302是美国DALLAS公司推出的实时时钟电路。DS1302具有高性能、低功耗的特点,其芯片采用SPI三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号和RAM数据。实时时钟可提供秒、分、时、日、星期、月和年,一个月小与31天时可以自动调整,且具有闰年补偿功能,工作电压宽达2.5~5.5V。
2-2、RTC
RTC(Real Time Clock):实时时钟,是一种集成电路,通常称为时钟芯片。
3、DS1302 Datasheet
3-1、引脚定义及应用电路
引脚名 | 作用 |
---|---|
VCC2 | 主电源 |
VCC1 | 备用电源 |
GND | 电源地 |
X1、X2 | 32.768KHz晶振 |
CE | 芯片使能 |
IO | 数据输入/输出 |
SCLK | 串行时钟 |
3-2、硬件电路
从下图可知 ,没有连接VCC1,则表示没有备用电源使用。下电后就不能计时。
3-3、内部结构框图
3-4、寄存器定义
3-5、地址命令字
命令字启动每一次数据传输。MSB((位7)必须是逻辑1。如果是0,则禁止对DS1302写入。位6在逻辑0时规定为时钟/日历数据,逻辑1时为RAM数据。位1至位5表示了输入输出的指定寄存器。LSB(位0)在逻辑0时为写操作(输出),逻辑1时为读操作(输入)。命令字以LSB(位0)开始总是输入。
3-6、时序定义
3-6-1、CE与时钟控制
所有数据传输开始驱动CE输入高电平。CE输入实现两个功能:第一,CE开启允许对地址/命令序列的移位寄存器进行读写的控制逻辑。第二,CE信号为单字节和多字节CE数据传输提供了终止的方法。
一个时钟周期是一系列的上升沿伴随随下降沿。要写入数据在时钟的上升沿数据必须有效,而且在下降沿要输出数据位。如果CE输入为低电平,则所有数据传输终止,并且I/O口成高阻抗状态。在上电时, CE必须为逻辑0直到VCC大于 2.0V时才变为逻辑1。同样,SCLK必须为逻辑0当CE变成逻辑1状态。
3-6-2、数据输入
输入写命令字的8个SCLK周期后,接下来的8个SCLK周期的上升沿数据字节被输入,如不慎发生,多余的SCLK周期将被忽略,数据输入以位0开始。
3-6-3、数据输出
输入读命令字的8个SCLK周期后,随后的8个SCLK周期的下降沿,一个数据字节被输出。注意第一个数据位的传送发生在命令字节被写完后的第一个下降沿。只要CE保持高电平,若不慎发生,多余的 SCLK周期会重新发送数据字节。此操作允许连续不断的脉冲串模式读取能力。并且I/O管脚在SCLK的每个上升沿被置为三态。数据输出从位 0开始。
3-6-4、脉冲串模式
通过寻址31(十进制)存储单元(地址/命令位1到位5为逻辑1),脉冲串模式可以指定时钟/日历或者RAM寄存器。如前所述,位6指定时钟或者RAM,位0指定读写。时钟/日历寄存器的存储单元9至31和RAM寄存器的存储单元31无数技据存储能力。脉冲串模式下的读写从地址0的位0开始。在脉冲串模式下写时钟寄存器时,前8个寄存器必须按顺序写要发送的数据。然而,在脉冲串模式下写RAM时,不必写入要发送数据的所有31个字节。不管是否所有31个字节都被写入,每个写入字节都会被发送到RAM。
3-6-5、时钟/日历
读取适当的寄存器字节可以得到时间和日历信息。Figure6. 寄存器地址/定义说明了RTC寄存器。写入适当的寄存器字节可以设置或初始化时间和日历。时间和日历寄存器的内容是二进制编码的十进制(BCD)格式的。周中的天寄存器在午夜12点增加。周中的天相应的值可以由用户定义,但是必须是连续的(例如,如果1代表周日,那么2代表周一,等等。)。非法的时间和日期输入导致未定义操作。当读写时钟和日期寄存器时,第二(用户)缓存用来防1上内部寄存器更新时出错。读时钟和日期寄存器时,在CE上升沿用户缓存与内部寄存器同步。
每当秒寄存器被写入,递减计数电路被复位。写传输发生在CE的下降沿。为了避免翻转问题,一旦递减计数电路复位,剩下的时间和日期寄存器必须不在一秒内被写入,DS1302可以工作在12小时制和24小时制两种模式下。小时寄存器的位7定义为小时模式选择位。为高时是12小时制,12小时制模式下,位5是上午/下午位且高电平是下午。24小时制模式下,位5是第二10-小时位(20点-23点)。一旦12/24改变,小时数据必须被重新初始化。
3-6-6、时钟暂停标志
秒寄存器的位7被定义为时钟暂停标志。当此为置1时,时钟振荡器暂停,DS1302进入漏电流小于100nA的低功耗备用模式。当此为置0时,时钟开始。初始加电状态未定义。
3-6-7、写保护位
控制寄存器的位7是写保护位,前7位(位0至位6)被强制为0且读取时总是读0。在任何对时钟或RAM的写操作以前,位7必须为0。当为高时,写保护位禁止任何寄存器的写操作。初始加电状态未定义,因此,在试图写器件之前应该清WP位。
4、工程编码
4-1、基础功能
#ifndef __LCD1602_H__
#define __LCD1602_H__//用户调用函数:
void LCD_Init();
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char);
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String);
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length);
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);#endif
#include <REGX52.H>
#include "LCD1602.h"//引脚配置:
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_EN=P2^7;
#define LCD_DataPort P0//函数定义:
/*** @brief LCD1602延时函数,12MHz调用可延时1ms* @param 无* @retval 无*/
void LCD_Delay()
{unsigned char i, j;i = 2;j = 239;do{while (--j);} while (--i);
}/*** @brief LCD1602写命令* @param Command 要写入的命令* @retval 无*/
void LCD_WriteCommand(unsigned char Command)
{LCD_RS=0;LCD_RW=0;LCD_DataPort=Command;LCD_EN=1;LCD_Delay();LCD_EN=0;LCD_Delay();
}/*** @brief LCD1602写数据* @param Data 要写入的数据* @retval 无*/
void LCD_WriteData(unsigned char Data)
{LCD_RS=1;LCD_RW=0;LCD_DataPort=Data;LCD_EN=1;LCD_Delay();LCD_EN=0;LCD_Delay();
}/*** @brief LCD1602设置光标位置* @param Line 行位置,范围:1~2* @param Column 列位置,范围:1~16* @retval 无*/
void LCD_SetCursor(unsigned char Line,unsigned char Column)
{if(Line==1){LCD_WriteCommand(0x80|(Column-1));}else if(Line==2){LCD_WriteCommand(0x80|(Column-1+0x40));}
}/*** @brief LCD1602初始化函数* @param 无* @retval 无*/
void LCD_Init()
{LCD_WriteCommand(0x38);//八位数据接口,两行显示,5*7点阵LCD_WriteCommand(0x0c);//显示开,光标关,闪烁关LCD_WriteCommand(0x06);//数据读写操作后,光标自动加一,画面不动LCD_WriteCommand(0x01);//光标复位,清屏
}/*** @brief 在LCD1602指定位置上显示一个字符* @param Line 行位置,范围:1~2* @param Column 列位置,范围:1~16* @param Char 要显示的字符* @retval 无*/
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char)
{LCD_SetCursor(Line,Column);LCD_WriteData(Char);
}/*** @brief 在LCD1602指定位置开始显示所给字符串* @param Line 起始行位置,范围:1~2* @param Column 起始列位置,范围:1~16* @param String 要显示的字符串* @retval 无*/
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String)
{unsigned char i;LCD_SetCursor(Line,Column);for(i=0;String[i]!='\0';i++){LCD_WriteData(String[i]);}
}/*** @brief 返回值=X的Y次方*/
int LCD_Pow(int X,int Y)
{unsigned char i;int Result=1;for(i=0;i<Y;i++){Result*=X;}return Result;
}/*** @brief 在LCD1602指定位置开始显示所给数字* @param Line 起始行位置,范围:1~2* @param Column 起始列位置,范围:1~16* @param Number 要显示的数字,范围:0~65535* @param Length 要显示数字的长度,范围:1~5* @retval 无*/
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{unsigned char i;LCD_SetCursor(Line,Column);for(i=Length;i>0;i--){LCD_WriteData(Number/LCD_Pow(10,i-1)%10+'0');}
}/*** @brief 在LCD1602指定位置开始以有符号十进制显示所给数字* @param Line 起始行位置,范围:1~2* @param Column 起始列位置,范围:1~16* @param Number 要显示的数字,范围:-32768~32767* @param Length 要显示数字的长度,范围:1~5* @retval 无*/
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length)
{unsigned char i;unsigned int Number1;LCD_SetCursor(Line,Column);if(Number>=0){LCD_WriteData('+');Number1=Number;}else{LCD_WriteData('-');Number1=-Number;}for(i=Length;i>0;i--){LCD_WriteData(Number1/LCD_Pow(10,i-1)%10+'0');}
}/*** @brief 在LCD1602指定位置开始以十六进制显示所给数字* @param Line 起始行位置,范围:1~2* @param Column 起始列位置,范围:1~16* @param Number 要显示的数字,范围:0~0xFFFF* @param Length 要显示数字的长度,范围:1~4* @retval 无*/
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{unsigned char i,SingleNumber;LCD_SetCursor(Line,Column);for(i=Length;i>0;i--){SingleNumber=Number/LCD_Pow(16,i-1)%16;if(SingleNumber<10){LCD_WriteData(SingleNumber+'0');}else{LCD_WriteData(SingleNumber-10+'A');}}
}/*** @brief 在LCD1602指定位置开始以二进制显示所给数字* @param Line 起始行位置,范围:1~2* @param Column 起始列位置,范围:1~16* @param Number 要显示的数字,范围:0~1111 1111 1111 1111* @param Length 要显示数字的长度,范围:1~16* @retval 无*/
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{unsigned char i;LCD_SetCursor(Line,Column);for(i=Length;i>0;i--){LCD_WriteData(Number/LCD_Pow(2,i-1)%2+'0');}
}
#ifndef __DS1302_H__
#define __DS1302_H__#define DS1302_SECONDS_ADDR 0x80
#define DS1302_MINUTES_ADDR 0x82
#define DS1302_HOUR_ADDR 0x84
#define DS1302_DATE_ADDR 0x86
#define DS1302_MONTH_ADDR 0x88
#define DS1302_DAY_ADDR 0x8A
#define DS1302_YEAR_ADDR 0x8C
#define DS1302_WP_ADDR 0x8E#define DS1302_WP_DISABLE 0x00
#define DS1302_WP_ENABLE 0x01#define DS1302_CURRENTTIME_LENGTH 7Uextern unsigned char DS1302_CurrentTime[DS1302_CURRENTTIME_LENGTH];extern void DS1302_Init(void);
extern void DS1302_WriteByte(unsigned char WriteAddr, unsigned char Data);
extern unsigned char DS1302_ReadByte(unsigned char ReadAddr);
extern void DS1302_SetTime(void);
extern void DS1302_GetTime(void);
extern unsigned char DS1302_BCD2HEX(unsigned char InputData);
extern unsigned char DS1302_HEX2BCD(unsigned char InputData);#endif
#include <REGX52.H>
#include "DS1302.h"sbit DS1302_IO = P3^4;
sbit DS1302_CE = P3^5;
sbit DS1302_SCLK = P3^6;unsigned char DS1302_CurrentTime[DS1302_CURRENTTIME_LENGTH] = {25,8,20,23,24,25,6};void DS1302_Init(void)
{DS1302_CE = 0;DS1302_SCLK = 0;
}void DS1302_WriteByte(unsigned char WriteAddr, unsigned char Data) /* 16 pulses */
{unsigned char i;DS1302_CE = 1; /* enable DS1302 *//* address command order */for(i = 0; i < 8; i++){DS1302_IO = WriteAddr & (0x01 << i); /* Set bit0 */DS1302_SCLK = 1; /* set rising edge to wirte bit */DS1302_SCLK = 0; /* back to low level for next bit writing. */}for(i = 0; i < 8; i++){DS1302_IO = Data & (0x01 << i); /* Set bit0 */DS1302_SCLK = 1; /* set rising edge to wirte bit */DS1302_SCLK = 0; /* back to low level for next bit writing. */}DS1302_CE = 0; /* disable DS1302 */
}unsigned char DS1302_ReadByte(unsigned char ReadAddr) /* 15 pulses */
{unsigned char i;unsigned char Data = 0x00;ReadAddr |= 0x01; /* read ReadAddr lowest bit is 1. */DS1302_CE = 1; /* enable DS1302 *//* address command order */for(i = 0; i < 8; i++){DS1302_IO = ReadAddr & (0x01 << i); /* Set bit0 */DS1302_SCLK = 0; /* back to low level for next bit writing. */DS1302_SCLK = 1; /* set rising edge to wirte bit */}for(i = 0; i < 8; i++){DS1302_SCLK = 1; /* set rising edge to read bit starting */DS1302_SCLK = 0; /* back to low level for bit reading. */if(DS1302_IO != 0){Data |= (0x01 << i);}}DS1302_IO = 0;return Data;
}void DS1302_SetTime(void)
{DS1302_WriteByte(DS1302_WP_ADDR, DS1302_WP_DISABLE); /* disable write protection */DS1302_WriteByte(DS1302_YEAR_ADDR, DS1302_BCD2HEX(DS1302_CurrentTime[0]));DS1302_WriteByte(DS1302_MONTH_ADDR, DS1302_BCD2HEX(DS1302_CurrentTime[1]));DS1302_WriteByte(DS1302_DATE_ADDR, DS1302_BCD2HEX(DS1302_CurrentTime[2]));DS1302_WriteByte(DS1302_HOUR_ADDR, DS1302_BCD2HEX(DS1302_CurrentTime[3]));DS1302_WriteByte(DS1302_MINUTES_ADDR, DS1302_BCD2HEX(DS1302_CurrentTime[4]));DS1302_WriteByte(DS1302_SECONDS_ADDR, DS1302_BCD2HEX(DS1302_CurrentTime[5]));DS1302_WriteByte(DS1302_DAY_ADDR, DS1302_BCD2HEX(DS1302_CurrentTime[6]));DS1302_WriteByte(DS1302_WP_ADDR, DS1302_WP_ENABLE); /* enable write protection */
}void DS1302_GetTime(void)
{DS1302_CurrentTime[0] = DS1302_HEX2BCD(DS1302_ReadByte(DS1302_YEAR_ADDR));DS1302_CurrentTime[1] = DS1302_HEX2BCD(DS1302_ReadByte(DS1302_MONTH_ADDR));DS1302_CurrentTime[2] = DS1302_HEX2BCD(DS1302_ReadByte(DS1302_DATE_ADDR));DS1302_CurrentTime[3] = DS1302_HEX2BCD(DS1302_ReadByte(DS1302_HOUR_ADDR));DS1302_CurrentTime[4] = DS1302_HEX2BCD(DS1302_ReadByte(DS1302_MINUTES_ADDR));DS1302_CurrentTime[5] = DS1302_HEX2BCD(DS1302_ReadByte(DS1302_SECONDS_ADDR));DS1302_CurrentTime[6] = DS1302_HEX2BCD(DS1302_ReadByte(DS1302_DAY_ADDR));
}unsigned char DS1302_BCD2HEX(unsigned char InputData)
{return (InputData / 10 * 16 + InputData % 10);
}unsigned char DS1302_HEX2BCD(unsigned char InputData)
{return (InputData / 16 * 10 + InputData % 16);
}
#include <REGX52.H>
#include "LCD1602.h"
#include "DS1302.h"void main()
{LCD_Init();DS1302_Init();DS1302_SetTime();LCD_ShowString(1,1," - - ");LCD_ShowString(2,1," : : "); while(1){DS1302_GetTime();LCD_ShowNum(1,1,DS1302_CurrentTime[0],2);LCD_ShowNum(1,4,DS1302_CurrentTime[1],2);LCD_ShowNum(1,7,DS1302_CurrentTime[2],2);LCD_ShowNum(2,1,DS1302_CurrentTime[3],2);LCD_ShowNum(2,4,DS1302_CurrentTime[4],2);LCD_ShowNum(2,7,DS1302_CurrentTime[5],2); }
}
4-2、按键操作
#include <REGX52.H>
#include "LCD1602.h"
#include "DS1302.h"
#include "Key.h"
#include "Timer0.h"unsigned char KeyNum;
unsigned char Mode;
unsigned char TimeSetSelect;
unsigned char TimeFlashFlag;void TimeShow(void)
{DS1302_GetTime();LCD_ShowNum(1,1,DS1302_CurrentTime[0],2);LCD_ShowNum(1,4,DS1302_CurrentTime[1],2);LCD_ShowNum(1,7,DS1302_CurrentTime[2],2);LCD_ShowNum(2,1,DS1302_CurrentTime[3],2);LCD_ShowNum(2,4,DS1302_CurrentTime[4],2);LCD_ShowNum(2,7,DS1302_CurrentTime[5],2);
}void TimeSet(void)
{if(KeyNum == 2){TimeSetSelect++; TimeSetSelect %= 6; /* Out of range to clear. */}if(KeyNum == 3){DS1302_CurrentTime[TimeSetSelect]++;if(DS1302_CurrentTime[0] > 99) /* Year */{DS1302_CurrentTime[0] == 0;}if(DS1302_CurrentTime[1] > 12) /* Month */{DS1302_CurrentTime[1] == 1;}if((DS1302_CurrentTime[1] == 1) || (DS1302_CurrentTime[1] == 3) || (DS1302_CurrentTime[1] == 5) || (DS1302_CurrentTime[1] == 7)|| (DS1302_CurrentTime[1] == 8) || (DS1302_CurrentTime[1] == 10) || (DS1302_CurrentTime[1] == 12)){if(DS1302_CurrentTime[1] > 31) /* Day */{DS1302_CurrentTime[2] == 1;}}else if ((DS1302_CurrentTime[1] == 4) || (DS1302_CurrentTime[1] == 6) || (DS1302_CurrentTime[1] == 9) || (DS1302_CurrentTime[1] == 11)){if(DS1302_CurrentTime[1] > 30) /* Day */{DS1302_CurrentTime[2] == 1;}}else if(DS1302_CurrentTime[1] == 2){if(DS1302_CurrentTime[0] % 4 ==0 ){if(DS1302_CurrentTime[1] > 29) /* Day */{DS1302_CurrentTime[2] == 1;}}else{if(DS1302_CurrentTime[1] > 28) /* Day */{DS1302_CurrentTime[2] == 1;}} }if(DS1302_CurrentTime[3] > 23) /* Hour */{DS1302_CurrentTime[3] == 0;}if(DS1302_CurrentTime[4] > 59) /* Mins */{DS1302_CurrentTime[4] == 0;}if(DS1302_CurrentTime[5] > 59) /* Seconds */{DS1302_CurrentTime[5] == 0;}}if(KeyNum == 4){DS1302_CurrentTime[TimeSetSelect]--;if(DS1302_CurrentTime[0] < 0) /* Year */{DS1302_CurrentTime[0] == 99;}if(DS1302_CurrentTime[1] < 1) /* Month */{DS1302_CurrentTime[1] == 12;}if((DS1302_CurrentTime[1] == 1) || (DS1302_CurrentTime[1] == 3) || (DS1302_CurrentTime[1] == 5) || (DS1302_CurrentTime[1] == 7)|| (DS1302_CurrentTime[1] == 8) || (DS1302_CurrentTime[1] == 10) || (DS1302_CurrentTime[1] == 12)){if(DS1302_CurrentTime[1] < 1) /* Day */{DS1302_CurrentTime[2] == 31;}else if(DS1302_CurrentTime[1] > 31) /* Day */{DS1302_CurrentTime[2] == 1;}}else if ((DS1302_CurrentTime[1] == 4) || (DS1302_CurrentTime[1] == 6) || (DS1302_CurrentTime[1] == 9) || (DS1302_CurrentTime[1] == 11)){if(DS1302_CurrentTime[1] < 1) /* Day */{DS1302_CurrentTime[2] == 30;}else if(DS1302_CurrentTime[1] > 30) /* Day */{DS1302_CurrentTime[2] == 1;}}else if(DS1302_CurrentTime[1] == 2){if(DS1302_CurrentTime[0] % 4 ==0 ){if(DS1302_CurrentTime[1] < 1) /* Day */{DS1302_CurrentTime[2] == 29;}else if(DS1302_CurrentTime[1] > 29) /* Day */{DS1302_CurrentTime[2] == 1;}}else{if(DS1302_CurrentTime[1] < 1) /* Day */{DS1302_CurrentTime[2] == 28;}else if(DS1302_CurrentTime[1] > 28) /* Day */{DS1302_CurrentTime[2] == 1;}} }if(DS1302_CurrentTime[3] < 0) /* Hour */{DS1302_CurrentTime[3] == 23;}if(DS1302_CurrentTime[4] < 0) /* Mins */{DS1302_CurrentTime[4] == 59;}if(DS1302_CurrentTime[5] < 0) /* Seconds */{DS1302_CurrentTime[5] == 59;}}if((TimeSetSelect == 0) && (TimeFlashFlag == 1)){LCD_ShowString(1,1," ");}else{LCD_ShowNum(1,1,DS1302_CurrentTime[0],2);}if((TimeSetSelect == 1) && (TimeFlashFlag == 1)){LCD_ShowString(1,4," ");}else{LCD_ShowNum(1,4,DS1302_CurrentTime[1],2);}if((TimeSetSelect == 2) && (TimeFlashFlag == 1)){LCD_ShowString(1,7," ");}else{LCD_ShowNum(1,7,DS1302_CurrentTime[2],2);}if((TimeSetSelect == 3) && (TimeFlashFlag == 1)){LCD_ShowString(2,1," ");}else{LCD_ShowNum(2,1,DS1302_CurrentTime[3],2);}if((TimeSetSelect == 4) && (TimeFlashFlag == 1)){LCD_ShowString(2,4," ");}else{LCD_ShowNum(2,4,DS1302_CurrentTime[4],2);}if((TimeSetSelect == 5) && (TimeFlashFlag == 1)){LCD_ShowString(2,7," ");}else{LCD_ShowNum(2,7,DS1302_CurrentTime[5],2);}LCD_ShowNum(2,10,TimeSetSelect,2);LCD_ShowNum(2,13,TimeFlashFlag,2);
}void main(void)
{LCD_Init();DS1302_Init();Timer0_Init();DS1302_SetTime();LCD_ShowString(1,1," - - ");LCD_ShowString(2,1," : : "); while(1){ KeyNum = Key();if(KeyNum){if(Mode == 0){Mode = 1;}else if(Mode == 1){Mode = 0;DS1302_SetTime();}}switch(Mode){case 0:TimeShow();break;case 1:TimeSet();break;}}
}void Timer0_Isr(void) interrupt 1
{static unsigned int T0Cnt;/* Inhibit timer0 count overflow. */TL0 = 0x18; //设置定时初始值TH0 = 0xFC; //设置定时初始值T0Cnt++;if(T0Cnt >= 500) //1s = 1000ms{T0Cnt = 0;TimeFlashFlag = !TimeFlashFlag; /* 0 or 1 */}
}
4-3、实验结果
参考资料
- DS1302实时时钟
- 51单片机入门教程-2020版 程序全程纯手打 从零开始入门