DS1302的程序,能写进去数,读出来的不正确。不管读哪个地方的,读出的都是1,高手进。
DS1302的程序,能写进去数,读出来的不正确。不管读哪个地方的,读出的都是1,我按一次复位键,显示的数变化一次,但时分秒显示的是相同的数。我往一个指定位置写,写了再读出...
DS1302的程序,能写进去数,读出来的不正确。不管读哪个地方的,读出的都是1,
我按一次复位键,显示的数变化一次,但时分秒显示的是相同的数。我往一个指定位置写,写了再读出来,不是我写的数,好像每一位读出来都是1。问题能解决的话,可追加到100分。
#include<iom16v.h>
#include<macros.h>
//#include "initAVR1.h"
#include <eeprom.h>
#include "delay1.h"
#include "ds1302.h"
#define uchar unsigned char
#define uint unsigned int
//端口设置//////////////////////////
#define RST PD4
#define DAT PD5
#define CLK PD6
#define port PORTD
#define ddr DDRD
#define pin PIND
////////////////////////////////////
#define DAT_IN ddr &= ~BIT(DAT)
#define DAT_OUT ddr |= BIT(DAT)
#define DAT_L port &= ~BIT(DAT)
#define DAT_H port|= BIT(DAT)
#define RST_H port |= BIT(RST)
#define RST_L port &= ~BIT(RST)
#define CLK_H port |= BIT(CLK)
#define CLK_L port &= ~BIT(CLK)
#define read pin & BIT(DAT)
#define uchar unsigned char
#define uint unsigned int
unsigned char tmrbyte (void) //读一个字节
{unsigned char i,j,dat;
DDRD|=(1<<RST)|(1<<CLK);
RST_L ;
delay_nus(2);
CLK_L;
delay_nus(2);
RST_H;
delay_nus(2);
DAT_IN;
for(i=0;i<8;i++) //连续读8个二进制位数据
{ if(read) //如果读出的数据是1
dat|=0x80;
delay_nus(2); //稍微等待
CLK_H;
delay_nus(2); //稍微等待
CLK_L;; //拉低SCLK,形成脉冲下降沿
delay_nus(2); //稍微等待
}
RST_L ;
return dat;
}
void tmwbyte (unsigned char dat) //写一个字节
{unsigned char i,j;
unsigned char testb;
DDRD|=(1<<RST)|(1<<CLK);
RST_L;
delay_nus(2);
CLK_L;
delay_nus(2);
RST_H ;
delay_nus(2);
DAT_OUT;
for (j=1;j<=8;j++)
{ testb = dat & 0x01;
dat = dat >> 1;
if (testb)
DAT_H;
else
DAT_L; //写0
delay_nus(2);
CLK_H; //写1
delay_nus(2);
CLK_L;
delay_nus(2);
}
RST_L;
delay_nus(2);
DAT_IN;
}
uchar tm_r1302(uchar ucAddr)
{uchar ucDa=0X04;
DDRD|=(1<<RST)|(1<<CLK);
RST_L;
delay_nus(2);
CLK_L;
delay_nus(2);
RST_H;
delay_nus(2);
tmwbyte (ucAddr) ; //地址,命令
delay_nus(10);
ucDa =tmrbyte();//读1Byte数据
delay_nus(10);
CLK_L;
RST_L ;
return ucDa;
}
void tm_w1302(uchar ucAddr, uchar ucDa)
{DDRD|=(1<<RST)|(1<<CLK);
RST_L;
delay_nus(2);
CLK_L;
delay_nus(2);
RST_H;
delay_nus(2);
tmwbyte (ucAddr) ; //地址,命令
delay_nus(10);
tmwbyte (ucDa) ; //写1Byte数据
delay_nus(10);
CLK_L;
RST_L;
}
补充一下初始化函数
void Init_DS1302(void)
{ unsigned char flag;
flag= tm_r1302(0x81);
if(flag&0x80) //判断时钟芯片是否关闭
{ tm_w1302(0x8E,0x00); //根据写状态寄存器命令字,写入不保护指令
tm_w1302(0x80,((55/10)<<4|(55%10))); //根据写秒寄存器命令字,写入秒的初始值
tm_w1302(0x82,((59/10)<<4|(59%10))); //根据写分寄存器命令字,写入分的初始值
tm_w1302(0x84,((10/10)<<4|(10%10))); //根据写小时寄存器命令字,写入小时的初始值
tm_w1302(0x86,((26/10)<<4|(26%10))); //根据写日寄存器命令字,写入日的初始值
tm_w1302(0x88,((8/10)<<4|(8%10))); //根据写月寄存器命令字,写入月的初始值
tm_w1302(0x8c,((10/10)<<4|(10%10))); //根据写年寄存器命令字,写入年的初始值
tm_w1302(0x90,0xa5); //打开充电功能 选择2K电阻充电方式
tm_w1302(0x8E,0x80); //根据写状态寄存器命令字,写入保护指令
}
} 展开
我按一次复位键,显示的数变化一次,但时分秒显示的是相同的数。我往一个指定位置写,写了再读出来,不是我写的数,好像每一位读出来都是1。问题能解决的话,可追加到100分。
#include<iom16v.h>
#include<macros.h>
//#include "initAVR1.h"
#include <eeprom.h>
#include "delay1.h"
#include "ds1302.h"
#define uchar unsigned char
#define uint unsigned int
//端口设置//////////////////////////
#define RST PD4
#define DAT PD5
#define CLK PD6
#define port PORTD
#define ddr DDRD
#define pin PIND
////////////////////////////////////
#define DAT_IN ddr &= ~BIT(DAT)
#define DAT_OUT ddr |= BIT(DAT)
#define DAT_L port &= ~BIT(DAT)
#define DAT_H port|= BIT(DAT)
#define RST_H port |= BIT(RST)
#define RST_L port &= ~BIT(RST)
#define CLK_H port |= BIT(CLK)
#define CLK_L port &= ~BIT(CLK)
#define read pin & BIT(DAT)
#define uchar unsigned char
#define uint unsigned int
unsigned char tmrbyte (void) //读一个字节
{unsigned char i,j,dat;
DDRD|=(1<<RST)|(1<<CLK);
RST_L ;
delay_nus(2);
CLK_L;
delay_nus(2);
RST_H;
delay_nus(2);
DAT_IN;
for(i=0;i<8;i++) //连续读8个二进制位数据
{ if(read) //如果读出的数据是1
dat|=0x80;
delay_nus(2); //稍微等待
CLK_H;
delay_nus(2); //稍微等待
CLK_L;; //拉低SCLK,形成脉冲下降沿
delay_nus(2); //稍微等待
}
RST_L ;
return dat;
}
void tmwbyte (unsigned char dat) //写一个字节
{unsigned char i,j;
unsigned char testb;
DDRD|=(1<<RST)|(1<<CLK);
RST_L;
delay_nus(2);
CLK_L;
delay_nus(2);
RST_H ;
delay_nus(2);
DAT_OUT;
for (j=1;j<=8;j++)
{ testb = dat & 0x01;
dat = dat >> 1;
if (testb)
DAT_H;
else
DAT_L; //写0
delay_nus(2);
CLK_H; //写1
delay_nus(2);
CLK_L;
delay_nus(2);
}
RST_L;
delay_nus(2);
DAT_IN;
}
uchar tm_r1302(uchar ucAddr)
{uchar ucDa=0X04;
DDRD|=(1<<RST)|(1<<CLK);
RST_L;
delay_nus(2);
CLK_L;
delay_nus(2);
RST_H;
delay_nus(2);
tmwbyte (ucAddr) ; //地址,命令
delay_nus(10);
ucDa =tmrbyte();//读1Byte数据
delay_nus(10);
CLK_L;
RST_L ;
return ucDa;
}
void tm_w1302(uchar ucAddr, uchar ucDa)
{DDRD|=(1<<RST)|(1<<CLK);
RST_L;
delay_nus(2);
CLK_L;
delay_nus(2);
RST_H;
delay_nus(2);
tmwbyte (ucAddr) ; //地址,命令
delay_nus(10);
tmwbyte (ucDa) ; //写1Byte数据
delay_nus(10);
CLK_L;
RST_L;
}
补充一下初始化函数
void Init_DS1302(void)
{ unsigned char flag;
flag= tm_r1302(0x81);
if(flag&0x80) //判断时钟芯片是否关闭
{ tm_w1302(0x8E,0x00); //根据写状态寄存器命令字,写入不保护指令
tm_w1302(0x80,((55/10)<<4|(55%10))); //根据写秒寄存器命令字,写入秒的初始值
tm_w1302(0x82,((59/10)<<4|(59%10))); //根据写分寄存器命令字,写入分的初始值
tm_w1302(0x84,((10/10)<<4|(10%10))); //根据写小时寄存器命令字,写入小时的初始值
tm_w1302(0x86,((26/10)<<4|(26%10))); //根据写日寄存器命令字,写入日的初始值
tm_w1302(0x88,((8/10)<<4|(8%10))); //根据写月寄存器命令字,写入月的初始值
tm_w1302(0x8c,((10/10)<<4|(10%10))); //根据写年寄存器命令字,写入年的初始值
tm_w1302(0x90,0xa5); //打开充电功能 选择2K电阻充电方式
tm_w1302(0x8E,0x80); //根据写状态寄存器命令字,写入保护指令
}
} 展开
3个回答
展开全部
123
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
我手头上有一个程序,不过是用ym12864r串行连接的,你要的话我可以发给你。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
我来回答一下吧,我把调好的程序发你邮箱吧!
本回答被提问者采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询