第八届省赛蓝桥杯解析与代码

主要考察DS1302、DS18b20、独立按键、数码管动态显示、led灯

首先我们应该明白关于DS1302与DS18B20的通讯协议分别是SPI协议与单总线协议,根据此协议与芯片进行通信,即读写操作

DS1302与SPI协议

利用SPI协议读取DS1302的数值:

  1. 首先给大家展示DS1302的底层驱动代码,所谓底层驱动,意思就是按照元件的逻辑,编写的最最基本的函数,我们通过调用这些函数,能够方便的对元件进行读写等操作;

  1. 需要注意的是,驱动代码会给出,但是有可能会挖坑,一般驱动代码的坑可能是引脚定义不对,或者给的头文件函数声明不完整,这是需要我们在使用前确定的;

/*
  
*/

#include <reg52.h>
#include <intrins.h>

sbit SCK=P1^7;        
sbit SDA=P2^3;        
sbit RST = P1^3;   // DS1302                                              

void Write_Ds1302(unsigned  char temp) //此处为写入要在DS1302中访问的地址,不是写入地址的内容
{
    unsigned char i;
    for (i=0;i<8;i++)         
    { 
        SCK=0;
        SDA=temp&0x01;
        temp>>=1; 
        SCK=1;
    }
}   

void Write_Ds1302_Byte( unsigned char address,unsigned char dat ) //往DS1302的某个地址中写一个字节    
{
     RST=0;    _nop_();
     SCK=0;    _nop_();
     RST=1;     _nop_();  
     Write_Ds1302(address);    
     Write_Ds1302(dat);        
     RST=0; 
}

unsigned char Read_Ds1302_Byte ( unsigned char address )//读取DS1302中某地址的内容,注意其返回值类型
{
     unsigned char i,temp=0x00;
     RST=0;    _nop_();
     SCK=0;    _nop_();
     RST=1;    _nop_();
     Write_Ds1302(address);
     for (i=0;i<8;i++)     
     {        
        SCK=0;
        temp>>=1;    
         if(SDA)
         temp|=0x80;    
         SCK=1;
    } 
     RST=0;    _nop_();
     SCK=0;    _nop_();
    SCK=1;    _nop_();
    SDA=0;    _nop_();
    SDA=1;    _nop_();
    return (temp);            
}
  1. 总结一下,驱动代码给出了向DS1302的某个地址写数据的函数,以及要读取其中某地址数据的函数,我们只需要知道时分秒相应读写地址,便可以准确的进行读写通信了;、

  1. 下面我们开始正确的运用吧,首先看到的是DS1302的读写地址,以及相应的读写保护(摘自小蜜蜂老师的视频哦)

我们可以看到,秒分时日月周年的读地址由0x81以2的间隔到0x8d;而秒分时日月周年的写地址由0x80以2的间隔到0x8c,当我们调用写函数要改变时间值时,我们应该先将保护控制寄存器0x8e写入0x00,解除对原始内容的保护,当我们写完所有数据时,我们应该将0x8e写入0x80,产生对所写内容的保护;

下面举个例子:实现将23时 53分,59秒,3月14日,周四,23年写入电子时钟DS1302中:

unsigned char code DS1302_waddr[]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};
unsigned char code DS1302_raddr[]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};
unsigned char time[]={0x59,0x53,0x23,0x14,0x03,0x04,0x23   };//注意一定要按秒分时日月周年的顺序,且按BCD码写入
void set_time()
{   Write_Ds1302_Byte(0x8e, 0x00) ;//解除对原始内容的保护
    unsigned char i;
    for(i=0;i<7;i++)
    {
        Write_Ds1302_Byte( DS1302_waddr[i], time[i] );//给相应寄存器修改时间的值
    
    }
    Write_Ds1302_Byte(0x8e, 0x80) ;//添加对原始内容的保护


}

那么如何读取DS1302中的函数例如秒,直接看到代码:

unsigned char time_get;
time_get=Read_Ds1302_Byte(0x81);

如果一次性要读取很多数据,可以考虑用一个数组加一个循环去接收,像这样:

unsigned char code DS1302_raddr[]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};
unsigned char time_get[]={};
 unsigned char i;
    for(i=0;i<7;i++)
    {
        Read_Ds1302_Byte( DS1302_waddr[i], time_get[i] );
    
    }

总结一下,读取比较简单,写要注意写的地址,和在写之前要进行写保护的解除,写完后要重新建立写保护;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值