主要考察DS1302、DS18b20、独立按键、数码管动态显示、led灯
首先我们应该明白关于DS1302与DS18B20的通讯协议分别是SPI协议与单总线协议,根据此协议与芯片进行通信,即读写操作
DS1302与SPI协议
利用SPI协议读取DS1302的数值:
首先给大家展示DS1302的底层驱动代码,所谓底层驱动,意思就是按照元件的逻辑,编写的最最基本的函数,我们通过调用这些函数,能够方便的对元件进行读写等操作;
需要注意的是,驱动代码会给出,但是有可能会挖坑,一般驱动代码的坑可能是引脚定义不对,或者给的头文件函数声明不完整,这是需要我们在使用前确定的;
/*
*/
#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);
}
总结一下,驱动代码给出了向DS1302的某个地址写数据的函数,以及要读取其中某地址数据的函数,我们只需要知道时分秒相应读写地址,便可以准确的进行读写通信了;、
下面我们开始正确的运用吧,首先看到的是DS1302的读写地址,以及相应的读写保护(摘自小蜜蜂老师的视频哦)
![](https://img-blog.csdnimg.cn/img_convert/a1598c6ecdba5d9d4025e2858776eb3f.png)
我们可以看到,秒分时日月周年的读地址由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] );
}
总结一下,读取比较简单,写要注意写的地址,和在写之前要进行写保护的解除,写完后要重新建立写保护;