?? ds1302.c
字號:
#include <avr/io.h>
#include <avr/delay.h>
#include "DS1302.h"
#include "spi.h"
//讀寫操作位
#define CMD_READ 0x01
#define CMD_WRITE 0x00
//時(shí)鐘 命令
#define CMD_SECOND 0x80 //秒
#define CMD_MINUTE 0x82 //分
#define CMD_HOUR 0x84 //時(shí)
#define CMD_DAY 0x86 //日
#define CMD_MONTH 0x88 //月
#define CMD_WEEK 0x8A //星期 DATE
#define CMD_YEAR 0x8C //年
#define CMD_CONTROL 0x8E //控制(寫保護(hù))
#define CMD_TRICKLE_CHARGE 0x90 //涓流充電
#define CMD_CLOCK_BURST 0xBE //連續(xù)讀取
//時(shí)鐘配置常量
#define CFG_CLOCK_HALT 0x80 //停止時(shí)鐘控制位 SECOND bit7
#define CFG_12_24 0x80 //12/24小時(shí)值選擇位 HOUR bit7
#define CFG_AM_PM 0x20 //AP/PM位 HOUR bit5
#define CFG_PROTECT 0x80 //寫保護(hù)控制位 CONTROL bit7
#define CFG_UNPROTECT 0x00 //寫保護(hù)控制位 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 //連續(xù)讀取
//M16管腳定義
#define DS1302_CE 1 //PA1 必須設(shè)為輸出 ----DS1302 pin5
//宏定義
#define EnDS1302 PORTA|= (1<<DS1302_CE) // 置CE為高電平,使能SPI接口
#define DiDS1302 PORTA&=~(1<<DS1302_CE) // 置CE為低電平,關(guān)閉SPI接口
unsigned char sWEEK[]="Wr 1 2 3 4 5 6Su";
unsigned char CURDATE[7];
/*-----------------------------------------------------------------------
Single_SPI : 使用SPI接口讀寫數(shù)據(jù)到DS1302
輸入?yún)?shù): command: 命令選擇;
wdata: 寫入的數(shù)據(jù);
返回值 rdata: 讀回的數(shù)據(jù);
(SPI的收發(fā)是同時(shí)進(jìn)行的)
-----------------------------------------------------------------------*/
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); // 傳送數(shù)據(jù)到SPI寄存器 DiDS1302; // 關(guān)斷LCD SPI通訊
_delay_us(10);
return rdata;
}
/*-----------------------------------------------------------------------
Burst_SPI : 使用SPI接口讀寫一批數(shù)據(jù)到DS1302
輸入?yún)?shù): CMD: 選擇Clock/RAM,選擇讀寫
lenth: 數(shù)據(jù)長度
pwdata: 寫入數(shù)據(jù)的緩沖區(qū);
prdata: 讀回?cái)?shù)據(jù)的緩沖區(qū);
(SPI的收發(fā)是同時(shí)進(jìn)行的)
讀CLOCK的數(shù)據(jù)從SECOND寄存器開始,到CONTROL寄存器,最大8字節(jié)
寫CLOCK的數(shù)據(jù)必須一次寫完8個字節(jié)
讀寫RAM的數(shù)據(jù)從 RAM0地址開始,到RAM30地址,最大31字節(jié)
-----------------------------------------------------------------------*/
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++); // 傳送數(shù)據(jù)到SPI寄存器
};
DiDS1302; // 關(guān)斷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); //寫保護(hù)
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]); //初始化時(shí)間
Single_SPI(CMD_TRICKLE_CHARGE,CFG_TC_D1R2); //涓流充電選擇
Single_SPI(CMD_CONTROL|CMD_WRITE,CFG_PROTECT); //寫保護(hù)
}
//壓縮BCD碼轉(zhuǎn)換成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轉(zhuǎn)換成漢字'一'~'日'
void decodeWEEK(unsigned char WEEK,unsigned char *pstr)
{
unsigned char i;
i=WEEK;
i&=0x07;
i=i<<1;
*pstr++=sWEEK[i++];
*pstr=sWEEK[i];
}
//讀取當(dāng)前時(shí)間并解釋
void read_date(char *s_cur_date)
{
Burst_SPI(CMD_CLOCK_BURST|CMD_READ,7,0,CURDATE); //讀取當(dāng)前時(shí)間
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); //時(shí) ,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 :長延時(shí)函數(shù)(GCC內(nèi)部延時(shí)函數(shù)的延時(shí)過短)
輸入?yún)?shù): t :延時(shí)時(shí)間 ms
-----------------------------------------------------------------------*/
void delay_nms(unsigned int t)
{
while (t--)
_delay_ms(1);
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -