51单片机——SPI、DS1302时钟 C语言入门编程

目录

SPI:

写时序:

读时序:

DS1302:

1.DS1302时钟:数码管上显示电子时钟时分秒,格式为“XX XX XX”


SPI:

写时序:

        在控制指令字输入后的下一个SCLK时钟的上升沿时,数据被写入DS1302, 数据输入从低位(位0)开始。(先写低位)

读时序:

        在紧跟8位的控制指令字后的下一个SCLK脉冲的下降沿读出DS1302的数据,读出数据时从低位0位到高位7。(先读低位,读取后将IO设置为0,否则读出的数据会出错)

DS1302:

        DS1302是DALLAS公司推出的涓流充电时钟芯片,内含有一个实时时钟/日历和31字节静态 RAM,通过简单的串行接口与单片机进行通信。实时时钟/日历电路提供秒、分、时、日、周、月、年的信息,每月的天数和闰年的天数可自动调整。时钟操作可通过AM/PM指示决定采用24或12小时格式。

        DS1302与单片机之间能简单地采用同步串行的方式进行通信,仅需用到三根通信线:①RES复位②I/O数据线③SCLK串行时钟。

        时钟/RAM的读/写数据以一个字节或多达 31个字节的字符组方式通信。DS1302工作时功耗很低保持数据和时钟信息时功率小于1mW。DS1302由 DS1202改进而来增加了以下的特性:双电源管脚用于主电源和备份电源供应,Vcc1为可编程涓流充电电源,附加七个字节存储器。实时时钟具有能计算2100年之前的秒、分、时、日、星期、月、年的能力,还有闰年调整的能力;31个8位暂存数据存储RAM宽范围;工作电压2.0~5.5V;可选工业级温度范围-40~+85℃;读/写时钟或RAM数据时有两种传送方式单字节传送和多字节传送字符组方式。

        从DS1302中读取写入的时钟数据均为BCD码格式,使用时需转换为我们习惯转换为10进制。在处理DS1302读取的数据时,取高低位使用除16和取余16,并非之前的除10和取余10。这是因为写入进DS1302时是BCD码, 读取出的数据也是BCD码,而BCD码即是4位表示一个十进制数,类似于一个字节的十六进制数据的高4位和低4位一样,所以这里是除16和取余16。

/*
2位DEC/BCD相互转化:
DEC=BCD/16*10+BCD%16;  
BCD=DEC/10*16+DEC%10;
*/

当该寄存器最高位WP为1时,DS1302只能读不能写,所以要在往DS1302写数据前确保WP为0。

        写保护的控制寄存器的位7是写保护位,前7位(位0至位6)被强制为0且读取时总是读0. 在任 何对时钟或RAM的写操作以前,位7必须为 0。当为高时,写保护位禁止任何寄存器的写操作。初始加电状态未定义.。因此,在试图写器件之前应该清除WP位。

1.DS1302时钟:数码管上显示电子时钟时分秒,格式为“XX XX XX”

        DS1302函数

#include <REGX52.H>

sbit DS1302_IO=P3^4;
sbit CE=P3^5;
sbit SCLK=P3^6;

//.h文件需将时间数组设置为外部全局变量
unsigned char DS1302_Time[]={22,10,15,17,18,30};//时间数组,索引0~5分别为年、月、日、时、分、秒 需要在.h文件extern声明外部可调用数组

void DS1302_Init(void)//DS1302初始化
{
    CE=0;
    SCLK=0;
}

void DS1302_WriteByte(unsigned char Command,Byte)//DS1302写一个字节,命令地址,数据
{
    unsigned char i;
    CE=1;
    for(i=0;i<8;i++)
    {
        DS1302_IO=Command&(0x01<<i);//先写低位
        SCLK=1;
        SCLK=0;
    }
    for(i=0;i<8;i++)
    {
        DS1302_IO=Byte&(0x01<<i);
        SCLK=1;
        SCLK=0;
    }
    CE=0;
}

unsigned char DS1302_ReadByte(unsigned char Command)//DS1302读一个字节,命令地址 返回数据值
{
    unsigned char i,Byte=0x00;
    CE=1;
    for(i=0;i<8;i++)
    {
        SCLK=0;
        DS1302_IO=Command&(0x01<<i);
        SCLK=1;
    }
    for(i=0;i<8;i++)
    {
        SCLK=0;
        if(DS1302_IO)Byte|=(0x01<<i);
        SCLK=1;
    }
    CE=0;
    SCLK=0;
    DS1302_IO=0;//读取后将IO设置为0,否则读出的数据会出错
    return Byte;
}

void DS1302_SetTime(void)//DS1302设置时间,调用之后,DS1302_Time数组的数字会被设置到DS1302中
{
    DS1302_WriteByte(0x8e,0x00);//关闭写保护
    DS1302_WriteByte(0x8c,DS1302_Time[0]/10*16+DS1302_Time[0]%10);//DEC转BCD
    DS1302_WriteByte(0x88,DS1302_Time[1]/10*16+DS1302_Time[1]%10);
    DS1302_WriteByte(0x86,DS1302_Time[2]/10*16+DS1302_Time[2]%10);
    DS1302_WriteByte(0x84,DS1302_Time[3]/10*16+DS1302_Time[3]%10);
    DS1302_WriteByte(0x82,DS1302_Time[4]/10*16+DS1302_Time[4]%10);
    DS1302_WriteByte(0x80,DS1302_Time[5]/10*16+DS1302_Time[5]%10);
    DS1302_WriteByte(0x8e,0x80);//打开写保护,打开后无法重新写入,根据实况可以注释掉
}

void DS1302_ReadTime(void)// DS1302读取时间,调用之后,DS1302中的数据会被读取到DS1302_Time数组中
{
    unsigned char temp;
    temp=DS1302_ReadByte(0x8d);
    DS1302_Time[0]=temp/16*10+temp%16;//BCD转DEC
    temp=DS1302_ReadByte(0x89);
    DS1302_Time[1]=temp/16*10+temp%16;
    temp=DS1302_ReadByte(0x87);
    DS1302_Time[2]=temp/16*10+temp%16;
    temp=DS1302_ReadByte(0x85);
    DS1302_Time[3]=temp/16*10+temp%16;
    temp=DS1302_ReadByte(0x83);
    DS1302_Time[4]=temp/16*10+temp%16;
    temp=DS1302_ReadByte(0x81);
    DS1302_Time[5]=temp/16*10+temp%16;
}

        主函数

#include <REGX52.H>
#include "DS1302.h"
#include "shumaguan.h"

void main()
{
    DS1302_Init();
    DS1302_SetTime();
    while(1)
    {
        DS1302_ReadTime(); 
        shumaguan(1,DS1302_Time[3]/10);
        shumaguan(2,DS1302_Time[3]%10);
        shumaguan(4,DS1302_Time[4]/10);
        shumaguan(5,DS1302_Time[4]%10);
        shumaguan(7,DS1302_Time[5]/10);
        shumaguan(8,DS1302_Time[5]%10);
    }
}

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值