#include<iom16v.h>
#include<macros.h>
#define uchar unsigned char
#define uint unsigned int
#define sck_clr PORTB&=~BIT(1)
#define sck_set PORTB|=BIT(1)
#define sck_out DDRB|=BIT(1)
#define rst_clr PORTB&=~BIT(2)
#define rst_set PORTB|=BIT(2)
#define rst_out DDRB|=BIT(2)
#define io_clr PORTB&=~BIT(0)
#define io_set PORTB|=BIT(0)
#define io_out DDRB|=BIT(0)
#define io_in DDRB&=~BIT(0)
#define io_r PINB&BIT(0)
#define we_0 PORTB&=~BIT(4)
#define we_1 PORTB|=BIT(4)
#define du_0 PORTB&=~BIT(5)
#define du_1 PORTB|=BIT(5)
const uchar smg_du[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
const uchar smg_we[]={~0x01,~0x02,~0x04,~0x08,~0x10,~0x20,~0x40,~0x80};
uchar CurrDateTime[7]; //所读取的日期时间数组
uchar time_dat[7]={30,41,17,17,3,7,13}; //要设定的时间(秒,分,时,日,月,周,年)
uchar time_dat1[7]; //实际写入的BCD码数组
uchar table[8]={0,0,0,0,0,0,0,0};
void init(void)
{
DDRA=0xff;
PORTA=0xff;
DDRB=0xff;
DDRB=0xff;
}
void delay(void)
{
uint a;
for(a=0;a<300;a++);
}
void display(void)
{
uchar i;
for(i=0;i<8;i++)
{
PORTA=0x00;
du_1;du_0;
PORTA=smg_du[table[i]];
du_1;du_0;
PORTA=smg_we[i];
we_1;we_0;
delay();
}
}
void WriteByte(uchar x)
{
uchar i;
sck_set;
for(i=0x01;i!=0x00;i<<=1)
{
if(x&i)
{
io_set;
}
else
{
io_clr;
}
sck_set;
asm("nop");
sck_clr;
asm("nop");
}
}
uchar ReadByte(void)
{
uchar i,dat=0x00;
for(i=0x01;i!=0x00;i<<=1)
{
if(io_r)
{
dat|=i;
}
sck_set;
asm("nop");
sck_clr;
asm("nop");
}
return dat; //返回所读取得BCD码
//将BCD码转换为十进制返回时,试用下面的语句之一
//return dat/16*10+dat%16;
//return (dat>>4)*10+(dat&0x0f);
//注意:使用不同的编码返回时,主程序中的格式化日期时间函数
//format_datetime要使用不同的语句进行分解
}
uchar Read_DS1302(uchar addr)
{
uchar dat;
rst_clr;
sck_clr;
rst_set;
WriteByte(addr);
dat=ReadByte();
sck_set;
rst_clr;
return dat;
}
void Write_DS1302(uchar addr,uchar dat)
{
rst_clr;
sck_clr;
rst_set;
WriteByte(addr);
WriteByte(dat);
sck_set;
rst_clr;
}
//-----------------------------------------------------------------
// 设置时间
//-----------------------------------------------------------------
void SetDateTime(void)
{
uchar i,tmp;
for(i=0;i<7;i++)
{
tmp=time_dat[i]/10; //分解数据十位
time_dat1[i]=time_dat[i]%10; //分解数据个位
time_dat1[i]=time_dat1[i]+(tmp*16); //把十位数变成BCD码和个位相加合并成BCD码数据
}
Write_DS1302(0x8e,0x00); //关闭写保护位
Write_DS1302(0x80,0x80); //暂停时钟走时
Write_DS1302(0x90,0xaa); //设置涓流充电双二极管4k电阻模式1010 1010
Write_DS1302(0x8c,time_dat1[6]); //年对时写入
Write_DS1302(0x8a,time_dat1[5]); //周对时写入
Write_DS1302(0x88,time_dat1[4]); //月对时写入
Write_DS1302(0x86,time_dat1[3]); //日对时写入
Write_DS1302(0x84,time_dat1[2]); //时对时写入
Write_DS1302(0x82,time_dat1[1]); //分对时写入
Write_DS1302(0x80,time_dat1[0]); //秒对时写入
Write_DS1302(0x8e,0x80); //打开写保护
}
//-----------------------------------------------------------------
// 读取当前日期时间(BCD码)
//-----------------------------------------------------------------
void GetDateTime(void)
{
// uchar i,tmp;
// uchar time_shijian[7]; //临时存放的时间数组
//uchar i,addr=0x81;
//for(i=0;i<7;i++,addr+=2)
//{
//CurrDateTime[i]=Read_DS1302(addr);
//}
/*time_shijian*/CurrDateTime[0]=Read_DS1302(0x81);
/*time_shijian*/CurrDateTime[1]=Read_DS1302(0x83);
/*time_shijian*/CurrDateTime[2]=Read_DS1302(0x85);
/*time_shijian*/CurrDateTime[3]=Read_DS1302(0x87);
/*time_shijian*/CurrDateTime[4]=Read_DS1302(0x89);
/*time_shijian*/CurrDateTime[5]=Read_DS1302(0x8b);
/*time_shijian*/CurrDateTime[6]=Read_DS1302(0x8d);
// for(i=0;i<7;i++)
// { //BCD处理
// tmp=time_shijian[i]/16;
// CurrDateTime[i]=time_shijian[i]%16;
// CurrDateTime[i]=CurrDateTime[i]+tmp*10;
// }
}
//-----------------------------------------------------------------
// DS1302初始化(设置CH=0,开点滴式充电功能)
//-----------------------------------------------------------------
void Init_DS1302(void)
{
rst_clr; //rst引脚置低电平
sck_clr; //sclk引脚置低电平
}
void time_pro(void)
{
table[0]=CurrDateTime[0]%16;
table[1]=CurrDateTime[0]/16;
table[2]=16;
table[3]=CurrDateTime[1]%16;
table[4]=CurrDateTime[1]/16;
table[5]=16;
table[6]=CurrDateTime[2]%16;
table[7]=CurrDateTime[2]/16;
}
void main(void)
{
uchar j;
Init_DS1302();
init();
sck_out;
rst_out;
// SetDateTime();
while(1)
{
GetDateTime();
time_pro();
display();
}
}
求大神们解释 |