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

📄 ds1302.c

📁 包括力天电子MINI 16板的各项程序
💻 C
字号:
#include <avr/io.h>
#include <avr/delay.h>
#include "DS1302.h"
#include "spi.h"

//读写操作位
#define CMD_READ			0x01
#define CMD_WRITE			0x00

//时钟 命令
#define CMD_SECOND			0x80	//秒
#define CMD_MINUTE			0x82	//分
#define CMD_HOUR			0x84	//时
#define CMD_DAY				0x86	//日
#define CMD_MONTH			0x88	//月
#define CMD_WEEK			0x8A	//星期 DATE
#define CMD_YEAR			0x8C	//年
#define CMD_CONTROL			0x8E	//控制(写保护)
#define CMD_TRICKLE_CHARGE	0x90	//涓流充电
#define CMD_CLOCK_BURST		0xBE	//连续读取
//时钟配置常量
#define CFG_CLOCK_HALT		0x80	//停止时钟控制位    SECOND	bit7
#define CFG_12_24			0x80	//12/24小时值选择位 HOUR		bit7 
#define CFG_AM_PM			0x20	//AP/PM位          HOUR		bit5 
#define CFG_PROTECT			0x80	//写保护控制位      CONTROL	bit7 
#define CFG_UNPROTECT		0x00	//写保护控制位      CONTROL	bit7 
//涓流充电控制常量
#define CFG_TC_D1R2			0xA5	//high 1 Diode +2K Resistors  
#define CFG_TC_D2R8			0xAB	//low  2 Diodes+8K Resistors  
#define CFG_TC_DISABLED		0x00	//Disabled(TCS<>1010 or DS=00 or RS=00)
//RAM 命令
#define CMD_RAM_BASE		0xC0	//RAM0~RAM30<<1 地址需左移一位 
#define CMD_RAM_BURST		0xFE	//连续读取

//M16管脚定义
#define DS1302_CE			1		//PA1 必须设为输出 ----DS1302 pin5
//宏定义
#define EnDS1302 PORTA|= (1<<DS1302_CE)	// 置CE为高电平,使能SPI接口
#define DiDS1302 PORTA&=~(1<<DS1302_CE)	// 置CE为低电平,关闭SPI接口

unsigned char sWEEK[]="Wr 1 2 3 4 5 6Su";
unsigned char CURDATE[7];

/*-----------------------------------------------------------------------
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);
    spi_rw(command);		 			// 传送命令到SPI寄存器
    _delay_us(10);    rdata = spi_rw(wdata);			 	// 传送数据到SPI寄存器    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);	spi_rw(CMD);							// 传送命令到SPI寄存器
    _delay_us(10);    
    while (len--)
    {    	*prdata++=spi_rw(*pwdata++);		// 传送数据到SPI寄存器
	};
	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(char *init_data)
{
	unsigned char temp[8];
	
    DiDS1302;
	
	DDRA|= (1<<DS1302_CE);

    Single_SPI(CMD_CONTROL|CMD_WRITE,CFG_UNPROTECT);				//写允许
    Burst_SPI(CMD_CLOCK_BURST|CMD_WRITE,8,init_data,&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(char *s_cur_date)
{
	Burst_SPI(CMD_CLOCK_BURST|CMD_READ,7,0,CURDATE);	//读取当前时间
	BCDtoASCII(CURDATE[6],s_cur_date + 2);					//年 ,00~10
	BCDtoASCII(CURDATE[4],s_cur_date + 6);					//月 ,01~12
	BCDtoASCII(CURDATE[3],s_cur_date + 10);					//日 ,01~31(28/30/31)
	BCDtoASCII(CURDATE[2],s_cur_date + 14);					//时 ,00~23
	BCDtoASCII(CURDATE[1],s_cur_date + 18);					//分 ,00~59
	BCDtoASCII(CURDATE[0],s_cur_date + 22);					//秒 ,00~59
	decodeWEEK(CURDATE[5],s_cur_date + 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 + -