1、删减《51单片机——DS1302实时时钟驱动-SPI模拟通讯(下)1.0》里不常用的代码,只保留突发模式下读写DS1302
#ifndef __DS1302_1_H__
#define __DS1302_1_H__
extern unsigned char DS1302[7];//年 星期 月 日 时 分 秒,读取和写入的数据均会保存在数组里面
extern unsigned char DS1302_RAM[31];
//时钟工作在突发模式下24小时制
extern void write_RTC(unsigned char year, unsigned char day, unsigned char month, unsigned char date, unsigned char hour_24, unsigned char min, unsigned char sec);
//时钟工作在突发模式下读
extern void read_RTC(void);//读取的数据会存放在DS1302[7]数组里
#endif // !__DS1302_1_H__
#include "SPI.h"
//0写保护 1年 2月 3星期 4日 5时 6分 7秒
static unsigned char code write_data_DS1302[8] = { 0x8e ,0x8c ,0x88 ,0x8a ,0x86 ,0x84 ,0x82 ,0x80 };
static unsigned char code read_data_DS1302[8] = { 0x8f ,0x8d ,0x89 ,0x8b ,0x87 ,0x85 ,0x83 ,0x81 };
unsigned char DS1302[7] = { 0,0,0,0,0,0,0 };//秒 分 时 日 月 星期 年
//数据转换为BCD码(dat不能大于2位数)
static unsigned char data_BCD(unsigned char dat)
{
unsigned char dat1, dat2;
dat1 = dat / 10;//结果为十六进制的高位
dat2 = dat % 10;//结果为十六进制的低位
// dat2 = dat1 * 16 + dat2;
dat2 = (dat1 << 4) + dat2;//新算法,速度快(没有加小括号,优先级问题)
return dat2;
}
//BCD码转换为数据
static unsigned char BCD_data(unsigned char dat)
{
unsigned char dat1, dat2;
dat1 = dat / 16;//结果为十进制数高位
dat2 = dat % 16;//结果为十进制数低位
// dat2 = dat1 * 10 + dat2;
dat2 = (dat1 << 3) + (dat1 << 1) + dat2;//新算法,速度快
return dat2;
}
//关闭写保护
static void stop_WP(void)
{
STATR_SPI();//启动SPI通讯
write_1_byte_SPI(write_data_DS1302[0]);//准备向0x8e这个地方写数据
write_1_byte_SPI(0x00);//关闭DS1302的写保护
STOP_SPI();//结束SPI通讯
}
//打开写保护
static void open_WP(void)
{
STATR_SPI();//启动SPI通讯
write_1_byte_SPI(write_data_DS1302[0]);//准备向0x8e这个地方写数据
write_1_byte_SPI(0x80);//打开DS1302的写保护
STOP_SPI();//结束SPI通讯
}
//时钟工作在突发模式下24小时制 突发指令0xbe 写数据
void write_RTC(unsigned char year, unsigned char day, unsigned char month, unsigned char date, unsigned char hour_24, unsigned char min, unsigned char sec)
{
unsigned char i;
DS1302[6] = data_BCD(year);//年
DS1302[5] = data_BCD(day);//周
DS1302[4] = data_BCD(month);//月
DS1302[3] = data_BCD(date);//日
DS1302[2] = data_BCD(hour_24);// & 0x3f;//防止hour_24写入的数据不是24小时格式(好像没有什么用)
DS1302[1] = data_BCD(min);//分钟
DS1302[0] = data_BCD(sec) & 0x7f;//DS1302开始计时,防止sec写入的数据动到bit7位时钟暂停启动位
stop_WP();//关闭写保护
STATR_SPI();//启动SPI通讯
write_1_byte_SPI(0xbe);//让芯片工作在突发模式下
for (i = 0; i < 7; i++)//时钟突发模式下应该先传送秒,最后是年
{
write_1_byte_SPI(DS1302[i]);
}
write_1_byte_SPI(0);//网上说的是时钟突发模式传送8个字节,好像只传送7个字节就可以
STOP_SPI();//结束SPI通讯
open_WP();//打开写保护
}
//时钟工作在突发模式下读 0xbf
void read_RTC(void)
{
unsigned char i = 0;
unsigned char x = 0;
STATR_SPI();//启动SPI通讯
write_1_byte_SPI(0xbf);//让芯片工作在突发模式下
for (i = 0; i < 7; i++)//应该先读秒,最后读年
{
DS1302[i] = BCD_data(read_1_byte_SPI());// 读取一个字节(BCD)并转换为数据,并存放到数组里
}
STOP_SPI();//结束SPI通讯
}