|
/***************************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); //单字节写入DS1302
uc DS_read(void); //单字节读DS1302
void DS_register_write(uc addr,uc dat); //向DS1302的寄存器中写入一个字节
uc DS_register_read(uc addr); //读取指定寄存器中的一个字节并返回那个字节
void init_DS(void); //初始化DS1302
void DS_BURST_WRITE(uc *dat); //连续写8个字节
void DS_BURST_READ(uc *dat); //连续读8个字节
void DS_write(uc dat) //DS1302在SCK上升沿时读取单片机发送的数据,单片机在SCK下降沿发送数据相当于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; //释放数据引脚
}
uc DS_read() //单片机在SCK上升沿读取DS1302发送的数据,DS1302在SCK下降沿发送数据相当于SPI中MISO变化
{
uc dat=0,mask;
for (mask=0x01; mask!=0; mask<<=1)
{
if (SDA !=0 )
{
dat |= mask; //读取到的数据是1
}
SCK = 1;
SCK = 0;
}
SDA = 0; //加了这个后就不会出现两个竖杆跳动地情况
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) //无错
{
/*用数组实现初始化*/
// 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); //撤销写保护以允许写入数据
// 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) //给要写入的时分秒数组
{
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) //给数组
{
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; //数码管段选,位选显示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; //只保留了整数
tmp = 65536 - tmp;
T0RH = (unsigned char)(tmp >> 8); //优先级问题,当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); //单字节写入DS1302
unsigned char DS_read(void); //单字节读DS1302
void DS_register_write(uc addr,uc dat); //向DS1302的寄存器中写入一个字节
uc DS_register_read(uc addr); //读取指定寄存器中的一个字节并返回那个字节
void init_DS(void); //初始化DS1302
void DS_BURST_WRITE(uc *dat); //连续写8个字节
void DS_BURST_READ(uc *dat); //连续读8个字节
void set_sfm(unsigned char shi,unsigned char fen,unsigned char miao);
#endif
QQ3401224322,欢迎一起讨论工程
|
|