江科大51单片机DS1302定时器学习笔记

本文是在学习江科大51单片机DS1302定时器教程后所做的笔记

所用软件 μvision4

DS1302定时器流程图

江科大51单片机DS1302定时器学习笔记_第1张图片

DS1302

是由美国DALLAS公司推出的具有涓细电流充电能力的低功耗实时时钟芯片。它可以对年、月、日、周、时、分、秒进行计时,且具有闰年补偿等多种功能

引脚定义和应用电路

江科大51单片机DS1302定时器学习笔记_第2张图片

图1

内部结构图

江科大51单片机DS1302定时器学习笔记_第3张图片

图2

寄存器的定义

江科大51单片机DS1302定时器学习笔记_第4张图片

图3

江科大51单片机DS1302定时器学习笔记_第5张图片

图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<

BCD码

DS1302里是用BCD码储存的时间,即四个字节代表一个十进制的数

因此对DS1302执行一些操作时要将BCD码转为十进制,公式如下:

江科大51单片机DS1302定时器学习笔记_第6张图片

源文件编写

以下是调用的.h文件与.c文件,是我跟着江科大的一起敲的,在共享一下:

DS1302.h源码

#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

DS1302.c源码

#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<

main.c源码

#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俱乐部

你可能感兴趣的:(c语言,51单片机)