DS1302时钟+单片机+普中+江科大自化协

发布时间:2024-08-08  

1、现象:

2、参考程序


2.1 主程序


#include

#include "LCD1602.H"

#include "DS1302.H"


void main()

{

    LCD1602_Init();

    DS1302_Init();

    LCD1602_ShowString(1,1,"  -  -  ");    //静态字符初始化显示

    LCD1602_ShowString(2,1,"  :  :  ");

    

    DS1302_SetTime( );                    //设置时间

    

    while(1)

    {

        DS1302_ReadTime( );                //读取时间

        LCD1602_ShowNum(1,1,DS1302_Time[0],2);    //显示年

        LCD1602_ShowNum(1,4,DS1302_Time[1],2);    //显示月

        LCD1602_ShowNum(1,7,DS1302_Time[2],2);    //显示日

        LCD1602_ShowNum(2,1,DS1302_Time[3],2);    //显示时

        LCD1602_ShowNum(2,4,DS1302_Time[4],2);    //显示分

        LCD1602_ShowNum(2,7,DS1302_Time[5],2);    //显示秒

    }

}


2.2 DS1302源程序及头文件


#include


//引脚定义,与硬件原理图有关

sbit DS1302_SCLK    = P3^6;

sbit DS1302_IO        = P3^4;

sbit DS1302_CE        = P3^5;


#define DS1302_SECOND_ADDR    0x80    //DS1302秒寄存器写地址

#define DS1302_MINUTE_ADDR    0x82    //DS1302分寄存器写地址

#define DS1302_HOUR_ADDR    0x84    //DS1302时寄存器写地址

#define DS1302_DATE_ADDR    0x86    //DS1302日寄存器写地址

#define DS1302_MONTH_ADDR    0x88    //DS1302月寄存器写地址

#define DS1302_DAY_ADDR        0x8A    //DS1302星期寄存器写地址

#define DS1302_YEAR_ADDR    0x8C    //DS1302年寄存器写地址

#define DS1302_WP_ADDR        0x8E    //DS1302控制寄存器写地址


unsigned char DS1302_Time[]={22,8,7,20,8,55,7};

//时间数字,索引0-6分别为年、月、日、时、分、秒、星期


/**

  * @brief  DS1302初始化

  * @param  无

  * @retval 无

  */

void DS1302_Init(void)

{

    DS1302_CE = 0;

    DS1302_SCLK = 0;

}


/**

  * @brief  DS1302写一个字节

  * @param  Command 命令字/地址

  * @param  Data 要写入的数据

  * @retval 无

  */

void DS1302_WriteByte(unsigned char Command,Data)

{

    unsigned char i;

    DS1302_CE = 1;

    

    for(i=0;i<8;i++)        //写地址/命令

    {

        DS1302_IO = Command & (0x01<        DS1302_SCLK = 1;    //SCLK上升沿,MCU向DS1302写入数据

        DS1302_SCLK = 0;    //一个完整的脉冲

    }

    

    for(i=0;i<8;i++)        //写数据

    {

        DS1302_IO = Data & (0x01<        DS1302_SCLK = 1;    //SCLK上升沿,MCU向DS1302写入数据

        DS1302_SCLK = 0;    //一个完整的脉冲

    }

    

    DS1302_CE = 0;

}


/**

  * @brief  DS1302读一个字节

  * @param  Command 命令字/地址

  * @retval 读出的数据

  */

unsigned char DS1302_ReadByte(unsigned char Command)

{

    unsigned char i;

    unsigned char Data = 0x00;

    

    Command = Command | 0x01;    //将读地址指令转换为相应的读地址指令

    

    DS1302_CE = 1;

    

    for(i=0;i<8;i++)        //写地址/命令

    {

        DS1302_IO = Command & (0x01<        DS1302_SCLK = 0;    //一个完整的脉冲,与写地址写数据相反

        DS1302_SCLK = 1;    //SCLK上升沿,MCU向DS1302写入数据        

    }

    

    for(i=0;i<8;i++)

    {

        DS1302_SCLK = 1;    //写地址读数据

        DS1302_SCLK = 0;    //SCLK下降沿,MUC读取DS1302的数据

        if(DS1302_IO) {Data = Data | (0x01<    }

    

    DS1302_CE = 0;

    DS1302_IO = 0;            //读取后将IO设置为0,否则读出的数据会出错

    return Data;

}


/**

  * @brief  DS1302设置时间,调用之后,DS1302_Time数组的数字会被设置到DS1302中

  * @param  无

  * @retval 无

  */

void DS1302_SetTime(void)

{

    DS1302_WriteByte(DS1302_WP_ADDR,0x00);    //解除芯片写保护

    DS1302_WriteByte(DS1302_YEAR_ADDR,        DS1302_Time[0]/10*16+DS1302_Time[0]%10);    //写入年数据,十进制转为十六进制

    DS1302_WriteByte(DS1302_MONTH_ADDR,        DS1302_Time[1]/10*16+DS1302_Time[1]%10);    //写入月数据

    DS1302_WriteByte(DS1302_DATE_ADDR,        DS1302_Time[2]/10*16+DS1302_Time[2]%10);    //写入日数据

    DS1302_WriteByte(DS1302_HOUR_ADDR,        DS1302_Time[3]/10*16+DS1302_Time[3]%10);    //写入小时数据

    DS1302_WriteByte(DS1302_MINUTE_ADDR,    DS1302_Time[4]/10*16+DS1302_Time[4]%10);    //写入分钟数据

    DS1302_WriteByte(DS1302_SECOND_ADDR,    DS1302_Time[5]/10*16+DS1302_Time[5]%10);    //写入秒钟数据

    DS1302_WriteByte(DS1302_DAY_ADDR,        DS1302_Time[6]/10*16+DS1302_Time[6]%10);    //写入星期数据

    DS1302_WriteByte(DS1302_WP_ADDR,0x80);    //开启芯片写保护

}


/**

  * @brief  DS1302读取时间,调用之后,DS1302中的数据会被读取到DS1302_Time数组中

  * @param  无

  * @retval 无

  */

void DS1302_ReadTime(void)

{

    unsigned char Temp;

    Temp = DS1302_ReadByte(DS1302_YEAR_ADDR);     DS1302_Time[0]=Temp/16*10+Temp%16;

    Temp = DS1302_ReadByte(DS1302_MONTH_ADDR);     DS1302_Time[1]=Temp/16*10+Temp%16;

    Temp = DS1302_ReadByte(DS1302_DATE_ADDR);     DS1302_Time[2]=Temp/16*10+Temp%16;

    Temp = DS1302_ReadByte(DS1302_HOUR_ADDR);     DS1302_Time[3]=Temp/16*10+Temp%16;

    Temp = DS1302_ReadByte(DS1302_MINUTE_ADDR); DS1302_Time[4]=Temp/16*10+Temp%16;

    Temp = DS1302_ReadByte(DS1302_SECOND_ADDR);    DS1302_Time[5]=Temp/16*10+Temp%16;

    Temp = DS1302_ReadByte(DS1302_DAY_ADDR);     DS1302_Time[6]=Temp/16*10+Temp%16;

}


#ifndef __DS1302_H__

#define __DS1302_H__


//外部可调用时间数组,索引0~6分别为年、月、日、时、分、秒、星期    

    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_SetTime(void);

    void DS1302_ReadTime(void);

    

#endif


2.3 LCD1602源程序及头文件


#include

#include "intrins.h"


//引脚配置,硬件原理图,普中A2

sbit LCD1602_RS = P2^6;

sbit LCD1602_RW = P2^5;

sbit LCD1602_E  = P2^7;

#define LCD1602_DATAPORT P0



/**

  * @brief  LCD1602延时函数

  * @param  xms=1, 延时1ms

  * @retval 无

  */

void LCD1602_Delayms(unsigned char xms)        //@11.0592MHz

{

    unsigned char i, j,k;


    for(k=0;k    {

        _nop_();

        i = 2;

        j = 199;

        do

        {

            while (--j);

        } while (--i);

    }


}


/**

  * @brief  LCD1602写命令,时序图

  * @param  Command 要写入的命令

  * @retval 无

  */

void LCD1602_WriteCommand(unsigned char Command)

{

    LCD1602_RS = 0;

    LCD1602_RW = 0;

    LCD1602_DATAPORT  = Command;

    LCD1602_E  = 1;

    LCD1602_Delayms(1);    //延时1ms

    LCD1602_E  = 0;

    LCD1602_Delayms(1);    //延时1ms

}


/**

  * @brief  LCD1602写数据,时序图

  * @param  Data 要写入的数据

  * @retval 无

  */

void LCD1602_WriteData(unsigned char Data)

{

    LCD1602_RS = 1;

    LCD1602_RW = 0;

    LCD1602_DATAPORT  = Data;

    LCD1602_E  = 1;

    LCD1602_Delayms(1);    //延时1ms

    LCD1602_E  = 0;

    LCD1602_Delayms(1);    //延时1ms

}


/**

  * @brief  LCD1602初始化函数

  * @param  无

  * @retval 无

  */

void LCD1602_Init(void)

{

    LCD1602_WriteCommand(0x38);    //0011_1000 功能设置,设置16x2显示,5x7点阵,8位数据接口

    LCD1602_WriteCommand(0x0C);    //0000_1100 显示开关控制,显示开,光标关,闪烁关    

    LCD1602_WriteCommand(0x06);    //0000_0110 输入方式设置,数据写后,AC自动加一,画面不动

    LCD1602_WriteCommand(0x01);    //0000_0001 清屏,数据指针清零、所有显示清零

}

/**

  * @brief  LCD1602设置光标位置

  * @param  Line 行位置,范围:1~2

  * @param  Column 列位置,范围:1~16

  * @retval 无

  */

void LCD1602_SetCursor(unsigned char Line,unsigned char Column)

{

    if(Line == 1)

    {

        LCD1602_WriteCommand(0x80|(Column-1)); //设置要存入数据的DDROM地址,第一行地址

    }

    else

    {

        LCD1602_WriteCommand(0x80|(Column-1)+0x40); //设置要存入数据的DDROM地,第二行地址

    }

}

    


/**

  * @brief  在LCD1602指定位置上显示一个字符

  * @param  Line 行位置,范围:1~2

  * @param  Column 列位置,范围:1~16

  * @param  Char 要显示的字符

  * @retval 无

  */

void LCD1602_ShowChar(unsigned char Line,unsigned char Column,unsigned char Char)

{

    LCD1602_SetCursor(Line,Column);

    LCD1602_WriteData(Char);

}


/**

  * @brief  在LCD1602指定位置上显示所给字符串

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>