📄 ds1302.c
字号:
#include <avr/io.h>
#include <avr/delay.h>
#include "main.h"
#include "DS1302.h"
//初始化SPI接口
void init_SPI(void)
{
SPCR = (1<<SPE)|(1<<MSTR)|(1<<DORD)|(1<<SPR0);
// 使能SPI接口,主机模式,LSB低位在先,模式0,16分频,SPI时钟约460KHz
}
/*-----------------------------------------------------------------------
Single_SPI : 使用SPI接口读写数据到DS1302
输入参数: command: 命令选择;
wdata: 写入的数据;
返回值 rdata: 读回的数据;
(SPI的收发是同时进行的)
-----------------------------------------------------------------------*/
unsigned char Single_SPI(unsigned char command,unsigned char wdata)
{
unsigned char rdata;
EnDS1302; // 使能LCD
_delay_us(10);
SPDR = command; // 传送命令到SPI寄存器
loop_until_bit_is_set(SPSR,SPIF); // 等待数据传送完?
_delay_us(10); SPDR = wdata; // 传送数据到SPI寄存器
loop_until_bit_is_set(SPSR,SPIF); // 等待数据传送完?
rdata=SPDR; // 读取数据 DiDS1302; // 关断LCD SPI通讯
_delay_us(10);
return rdata;
}
/*-----------------------------------------------------------------------
Burst_SPI : 使用SPI接口读写一批数据到DS1302
输入参数: CMD: 选择Clock/RAM,选择读写
lenth: 数据长度
pwdata: 写入数据的缓冲区;
prdata: 读回数据的缓冲区;
(SPI的收发是同时进行的)
读CLOCK的数据从SECOND寄存器开始,到CONTROL寄存器,最大8字节
写CLOCK的数据必须一次写完8个字节
读写RAM的数据从 RAM0地址开始,到RAM30地址,最大31字节
-----------------------------------------------------------------------*/
void Burst_SPI(unsigned char CMD,unsigned char len,
unsigned char *pwdata,unsigned char *prdata)
{
EnDS1302; // 使能SPI通讯
_delay_us(10); SPDR=CMD; // 传送命令到SPI寄存器
loop_until_bit_is_set(SPSR,SPIF); // 等待数据传送完?
_delay_us(10);
while (len--)
{ SPDR = *pwdata++; // 传送数据到SPI寄存器
loop_until_bit_is_set(SPSR,SPIF); // 等待数据传送完?
*prdata++=SPDR; // 读取数据
};
DiDS1302; // 关断SPI通讯
_delay_us(10);}
//检测DS1302
unsigned char check_RTC(void)
{
unsigned char i;
Single_SPI(CMD_CONTROL|CMD_WRITE,CFG_UNPROTECT);//写允许
Single_SPI(CMD_RAM_BASE|CMD_WRITE,0xA5); //写RAM0
Single_SPI(CMD_CONTROL|CMD_WRITE,CFG_PROTECT); //写保护
i=Single_SPI(CMD_RAM_BASE|CMD_READ,0); //读取RAM0
if(i==0xA5) return 1;
else return 0;
}
//初始化DS1302
void init_RTC(void)
{
unsigned char temp[8];
Single_SPI(CMD_CONTROL|CMD_WRITE,CFG_UNPROTECT); //写允许
Burst_SPI(CMD_CLOCK_BURST|CMD_WRITE,8,&INITDATE[0],&temp[0]); //初始化时间
Single_SPI(CMD_TRICKLE_CHARGE,CFG_TC_D1R2); //涓流充电选择
Single_SPI(CMD_CONTROL|CMD_WRITE,CFG_PROTECT); //写保护
}
//压缩BCD码转换成ASCII码
void BCDtoASCII(unsigned char cBCD,unsigned char *pstr)
{
unsigned char i,j;
i=cBCD>>4;
j=cBCD&0x0F;
*pstr++=i+0x30;
*pstr=j+0x30;
}
//BCD码0~7转换成汉字'一'~'日'
void decodeWEEK(unsigned char WEEK,unsigned char *pstr)
{
unsigned char i;
i=WEEK;
i&=0x07;
i=i<<1;
*pstr++=sWEEK[i++];
*pstr=sWEEK[i];
}
//读取当前时间并解释
void read_date(void)
{
Burst_SPI(CMD_CLOCK_BURST|CMD_READ,7,0,&CURDATE[0]); //读取当前时间
BCDtoASCII(CURDATE[6],&sCURDATE[2]); //年 ,00~10
BCDtoASCII(CURDATE[4],&sCURDATE[6]); //月 ,01~12
BCDtoASCII(CURDATE[3],&sCURDATE[10]); //日 ,01~31(28/30/31)
BCDtoASCII(CURDATE[2],&sCURDATE[14]); //时 ,00~23
BCDtoASCII(CURDATE[1],&sCURDATE[18]); //分 ,00~59
BCDtoASCII(CURDATE[0],&sCURDATE[22]); //秒 ,00~59
decodeWEEK(CURDATE[5],&sCURDATE[31]); //星期 ,1~7 一~日
}
/*-----------------------------------------------------------------------
delay_nms :长延时函数(GCC内部延时函数的延时过短)
输入参数: t :延时时间 ms
-----------------------------------------------------------------------*/
void delay_nms(unsigned int t)
{
while (t--)
_delay_ms(1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -