|
/***************************DS1302.c**************************************************/
#include "DS1302.h"
#define uc unsigned char
sbit CE = P1^3;
sbit SCK = P1^7;
sbit SDA = P2^3;
void DS_write(uc dat); //單字節(jié)寫入DS1302
uc DS_read(void); //單字節(jié)讀DS1302
void DS_register_write(uc addr,uc dat); //向DS1302的寄存器中寫入一個字節(jié)
uc DS_register_read(uc addr); //讀取指定寄存器中的一個字節(jié)并返回那個字節(jié)
void init_DS(void); //初始化DS1302
void DS_BURST_WRITE(uc *dat); //連續(xù)寫8個字節(jié)
void DS_BURST_READ(uc *dat); //連續(xù)讀8個字節(jié)
void DS_write(uc dat) //DS1302在SCK上升沿時讀取單片機發(fā)送的數(shù)據(jù),單片機在SCK下降沿發(fā)送數(shù)據(jù)相當于SPI中MOSI變化
{
uc mask;
for (mask=0x01; mask!=0; mask<<=1)
{
if ((dat & mask) != 0) //如果是==1,只顯示秒鐘
SDA = 1;
else
SDA =0;
SCK = 1;
SCK = 0;
}
//SDA = 1; //釋放數(shù)據(jù)引腳
}
uc DS_read() //單片機在SCK上升沿讀取DS1302發(fā)送的數(shù)據(jù),DS1302在SCK下降沿發(fā)送數(shù)據(jù)相當于SPI中MISO變化
{
uc dat=0,mask;
for (mask=0x01; mask!=0; mask<<=1)
{
if (SDA !=0 )
{
dat |= mask; //讀取到的數(shù)據(jù)是1
}
SCK = 1;
SCK = 0;
}
SDA = 0; //加了這個后就不會出現(xiàn)兩個豎桿跳動地情況
return dat;
}
void DS_register_write(uc addr,uc dat)
{
CE = 0;
SCK = 0;
CE = 1;
addr &= 0xFE;
DS_write(addr);
DS_write(dat);
CE = 0;
}
uc DS_register_read(uc addr)
{
uc dat;
CE = 0;
SCK = 0;
CE = 1;
addr |= 0x01;
DS_write(addr);
dat = DS_read();
CE = 0;
return dat;
}
void init_DS(void) //無錯
{
/*用數(shù)組實現(xiàn)初始化*/
// uc code init_time[] = {0x00,0x40,0x15,0x14,0x02,0x2019};
// uc i;
CE = 0; //初始化通信引腳
SCK = 0;
// i = DS_register_read(0); //讀取秒寄存器 CT107D沒有備用電源,可以不判斷這一位
// if ((i & 0x80) != 0) //由秒寄存器最高位 CH 的值判斷 DS1302 是否已停止
// {
// DS_register_write(7, 0x00); //撤銷寫保護以允許寫入數(shù)據(jù)
// for (i=0; i<7; i++) //設置 DS1302 為默認的初始時間
// {
// DS1302SingleWrite(i, init_time[i]);
// }
// }
DS_register_write(0x8E,0x00); //撤銷寫保護
/*初始化年份2019*/
//DS_register_write(0x8C,0x19);
/*初始化月份2*/
//DS_register_write(0x88,0x02);
/*初始化日14*/
//DS_register_write(0x86,0x14);
/*初始化時15*/
DS_register_write(0x84,0x23);
/*初始化分40*/
DS_register_write(0x82,0x59);
/*初始化秒00*/
DS_register_write(0x80,0x55);
DS_register_write(0x8E,0x80);
}
void set_sfm(unsigned char shi,unsigned char fen,unsigned char miao)
{
DS_register_write(0x8e,0);
DS_register_write(0x80,(miao/10)*16+miao%10);
DS_register_write(0x82,(fen/10)*16+fen%10);
DS_register_write(0x84,(shi/10)*16+shi%10);
DS_register_write(0x8e,0x80);
}
void DS_BURST_WRITE(uc *dat) //給要寫入的時分秒數(shù)組
{
uc i;
CE = 1;
DS_register_write(0x8E,0x00); //撤銷寫保護
DS_write(0xBE);
for (i=0; i<8; i++)
{
DS_write(dat[i]);
}
CE = 0;
}
void DS_BURST_READ(uc *dat) //給數(shù)組
{
uc i;
CE = 1;
DS_register_write(0x8E,0x00);
DS_write(0xBF);
for (i=0; i<8; i++)
{
dat[i] = DS_read();
}
CE = 0;
}
/**************************************************DS1302.h***********************************/
#include <reg52.h>
#include <intrins.h>
#include "DS1302.h"
unsigned char time[8];
unsigned char code T_display[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00}; //段選
unsigned char code T_COM[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; //位選
#define FOSC 11059200L
#define T1MS (65536-FOSC/12/1000) //1ms timer calculation method in 12T mode
void configureT0(unsigned int ms);
bit flag200ms;
unsigned char shi,fen,miao;
unsigned char count = 0;
unsigned char T0RH = 0;
unsigned char T0RL = 0;
void interruptTime0(void) interrupt 1
{
static unsigned char i;
static unsigned char tmr200ms;
TH0 = T0RH;
TL0 = T0RL;
tmr200ms++;
if (count-- == 0)
{
count = 1;
P2 = 0xE0; //數(shù)碼管段選,位選顯示1ms掃描
P0 = ~T_display[time[i]];
P2 = 0x00;
P2=0xc0;P0=T_COM[i];P2=0;
i++;
if(i == 8)
i = 0;
}
if (tmr200ms >= 200)
{
flag200ms = 1;
tmr200ms = 0;
}
}
void configureT0(unsigned int ms) //T0RL,T0RH有錯
{
unsigned long tmp;
tmp = 11059200 / 12;
tmp = (tmp * ms) / 1000; //只保留了整數(shù)
tmp = 65536 - tmp;
T0RH = (unsigned char)(tmp >> 8); //優(yōu)先級問題,當tmp>>8不加括號就會閃爍.用仿真這個表達式和打括號的表達式一樣.但是顯示的效果是跑馬燈一樣的.
T0RL = (unsigned char)tmp;
TMOD &= 0xF0;
TMOD = 0x01;
TH0 = T0RH;
TL0 = T0RL;
ET0 = 1;
TR0 = 1;
}
void main() //burst模式
{
unsigned char dat[8] = {0x23,0x55,0x55,0x23,0x23,0x23,0x23,0x23};
EA = 1;
configureT0(1);
DS_BURST_WRITE(dat);
while (1)
{
if (flag200ms)
DS_BURST_READ(dat);
time[0] = dat[0]>>4;
time[1] = dat[0]&0x0F;
time[2] = 10;
time[3] = dat[1]>>4;
time[4] = dat[1]&0x0f;
time[5] = 10;
time[6] = dat[2]/16;
time[7] = dat[2]%16;
}
}
/*******************************************DS1302.h************************************/
#ifndef _DS1302_h_
#define _DS1302_h_
#include<reg52.h>
#include<intrins.h>
#define uc unsigned char
void DS_write(uc dat); //單字節(jié)寫入DS1302
unsigned char DS_read(void); //單字節(jié)讀DS1302
void DS_register_write(uc addr,uc dat); //向DS1302的寄存器中寫入一個字節(jié)
uc DS_register_read(uc addr); //讀取指定寄存器中的一個字節(jié)并返回那個字節(jié)
void init_DS(void); //初始化DS1302
void DS_BURST_WRITE(uc *dat); //連續(xù)寫8個字節(jié)
void DS_BURST_READ(uc *dat); //連續(xù)讀8個字節(jié)
void set_sfm(unsigned char shi,unsigned char fen,unsigned char miao);
#endif
QQ3401224322,歡迎一起討論工程
|
-
-
DS1302.zip
2019-2-17 18:27 上傳
點擊文件名下載附件
42.62 KB, 下載次數(shù): 2
上電那一刻會顯示初始值,但立馬會跳變
|