⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ds1302.c

📁 AVR例子程序和protues仿真
💻 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 + -