标题:
请问一下,这个AVR单片机DS1302程序对不对? 求帮助
[打印本页]
作者:
1804181935
时间:
2019-7-24 16:23
标题:
请问一下,这个AVR单片机DS1302程序对不对? 求帮助
#include <iom16v.h>
#include <macros.h>
#define uchar unsigned char
#define uint unsigned int
#define SCK_CLR PORTC&=~BIT(0)
//拉低时钟线
#define SCK_SET PORTC|=BIT(0)
//拉高时钟线
#define SCK_OUT DDRC|=BIT(0)
#define RST_CLR PORTC&=~BIT(2)
//拉低RST线 复位线
#define RST_SET PORTC|=BIT(2)
//拉高RST线
#define RST_OUT DDRC|=BIT(2)
//把RST设为输出
#define IO_CLR PORTC&=~BIT(1)
//拉低IO线 数据线
#define IO_SET PORTC|=BIT(1)
//拉高IO线
#define IO_IN DDRC&=~BIT(1)
//把IO设为输入
#define IO_RD PINC&BIT(1)
//从IO中读数据
#define IO_OUT DDRC|=BIT(1)
//把IO设为输出
uchar const write_add[]={0x80,0x82,0x84}; //写地址,0x86,0x88,0x8c,0x8a
//uchar code read_add[] ={0x81,0x83,0x85}; //读地址,0x87,0x89,0x8d,0x8b
uchar const init_ds[] ={0x55,0x17,0x15,0x01,0x01,0x13,0x13};
uchar miao,fen,shi;//,ri,yue,week,nian=0x20;
uchar nfen=0;
uchar nshi=0;
/*************写一个数据到对应的地址里***************/
void write_ds1302(uchar add,uchar dat)
{
uchar i;
RST_SET;
IO_OUT; //把复位线拉高
for(i=0;i<8;i++)
{ //低位在前
SCK_CLR; //时钟线拿低开始写数据
if(add&0x01)
{
IO_SET;
}
else
{
IO_CLR;
} //把地址右移一位
SCK_SET; //时钟线拿高
add=add>>1;
}
for(i=0;i<8;i++)
{
SCK_CLR; //时钟线拿低开始读数据
if(dat&0x01)
{
IO_SET;
}
else
{
IO_CLR;
} //把数据右移一位
SCK_SET; //时钟线拿高
dat=dat>>1;
}
RST_CLR; //复位线合低
SCK_CLR;
IO_CLR;
}
/*************从对应的地址读一个数据出来***************/
uchar read_ds1302(uchar add)
{
uchar value,i;
RST_SET;
IO_IN; //把复位线拿高
for(i=0;i<8;i++)
{ //低位在前
SCK_CLR; //时钟线拿低开始写数据
if(add&0x01)
{
IO_SET;
}
else
{
IO_CLR;
}
SCK_SET; //时钟线拿高
add=add>>1; //把地址右移一位
}
for(i=0;i<8;i++)
{
SCK_CLR; //时钟线拿低开始读数据
value >>= 1;
if(IO_RD)
value |= 0x80;
SCK_SET; //时钟线拿高
}
RST_CLR; //复位线合低
SCK_CLR;
IO_CLR;
return value; //返回读出来的数据
}
/*************把要的时间年月日都读出来***************/
void read_time()
{
miao = read_ds1302(0x81); //读秒
fen = read_ds1302(0x83); //读分
shi = read_ds1302(0x85); //读时
// ri = read_ds1302(read_add[3]); //读日
// yue = read_ds1302(read_add[4]); //读月
// nian = read_ds1302(read_add[5]); //读年
// week = read_ds1302(read_add[6]); //读星期
}
/*************把要写的时间年月日都写入ds1302里***************/
void write_time()
{
write_ds1302(0x8e,0x00); //打开写保护
// write_ds1302(write_add[0],miao); //写秒
write_ds1302(0x82,fen); //写分
write_ds1302(0x84,shi); //写时
// write_ds1302(write_add[3],ri); //写日
// write_ds1302(write_add[4],yue); //写月
// write_ds1302(write_add[5],nian); //写年
// write_ds1302(write_add[6],week); //写星期
write_ds1302(0xc2,nshi); //写闹时
write_ds1302(0xc4,nfen); //写闹分
write_ds1302(0x8e,0x80); //关闭写保护
}
void read_nao()
{
nshi = read_ds1302(0xc3); //读闹钟时
nfen = read_ds1302(0xc5); //读闹钟分
}
/*************把数据保存到ds1302 RAM中**0-31***********/
void write_ds1302ram(uchar add,uchar dat)
{
add <<= 1; //地址是从第二位开始的
add &= 0xfe; //把最低位清零 是写的命令
add |= 0xc0; //地址最高两位为1
write_ds1302(0x8e,0x00);
write_ds1302(add,dat);
write_ds1302(0x8e,0x80);
}
/*************把数据从ds1302 RAM读出来**0-31***********/
uchar read_ds1302ram(uchar add)
{
add <<= 1; //地址是从第二位开始的
add |= 0x01; //把最低位清零 是读的命令
add |= 0xc0; //地址最高两位为1
return(read_ds1302(add));
}
/*************初始化ds1302时间***************/
void init_ds1302()
{
uchar i;
RST_CLR; //复位线合低
SCK_CLR;
IO_CLR;
i = read_ds1302ram(30);
if(i != 3)
{
i = 3;
write_ds1302ram(30,i);
write_ds1302(0x8e,0x00); //打开保护
for(i=0;i<3;i++)
write_ds1302(write_add[i],init_ds[i]); //把最高位值0 允许ds1302工作
write_ds1302(0x8e,0x80); //关写保护
}
}
void init_ds1302_io()
{
RST_CLR; //第一次读写数据是要把io位拿低
SCK_CLR;
IO_CLR;
}
复制代码
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1