1302根本写不进去数据怎么办了,芯片本身应该是没什么毛病的,本人新手一个 不知该如何解决,求助各大神帮帮忙,程序如下:
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
/*DS1302内部寄存器定义*/
#define AM(X) X
#define PM(X) (X+12)/*转成24小时制*/
#define DS1302_SECOND 0x80
#define DS1302_MINUTE 0x82
#define DS1302_HOUR 0x84
#define DS1302_WEEK 0x8A
#define DS1302_DAY 0x86
#define DS1302_MONTH 0x88
#define DS1302_YEAR 0x8C
#define DS1302_RAM(X) (0xC0+(X)*2)/*用于计算 DS1302_RAM 地址的宏*/
#define DS1302_tricklecharger 0x90
#define DS1302_controler 0x8e
/*DS1302引脚定义*/
sbit DS1302_CLK = P1^7;/*实时时钟时钟线引脚*/
sbit DS1302_IO = P1^6;/*实时时钟数据线引脚*/
sbit DS1302_RST = P1^5;/*实时时钟复位线引脚*/
sbit ACC0 = ACC^0;
sbit ACC7 = ACC^7;
/*74HC595 引脚定义*/
sbit STB=P1^0; /*HC595并行打入脉冲控制*/
sbit ds1820=P3^7; /*温度传感器接收输入*/
sbit sm3800=P3^2; /*红外线接收输入*/
bit flag;
uchar code tab[12]={0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x09,0x91,0xe3};/*12个端段码*/
uchar i,j;
uchar ledbuf[12];/*显示输出缓冲区,[0]为秒个位,[1]为秒十位。。。。。。。。[11]为年十位*/
uchar timebuf[7];
uchar *point;
uchar second,counter;
void displed(void)
{
for(i=0;i<12;i++)
{
SBUF=ledbuf[i]; /*按序将12个数字段码送HC595,RXD为数据输出,TXD为串行同步脉冲*/
}
STB=0; /*在连续送完12个段码后,将其一起打入到595后级锁存器输出*/
STB=1;
}
/*内部定时器定时T0 0。1秒中断函数*/
void t0(void) interrupt 1
{
TH0=(15536)/256; /*T0定时50MS,重新赋初值*/
TL0=(15535)%256;
counter++; /*知道中断次数加1*/
if(counter>1) /*如果两次中断*/
{
counter=0;
flag=1; /*则设置消息变量向主函数传递*/
}
}
void InputByte(uchar d) /*实时时钟写入一字节(内部函数),调用之前应该使RST=1*/
{
uchar i,j;
DS1302_CLK = 0;
ACC=d;
for(i=8; i>0; i--)
{
DS1302_IO=ACC0;/*相当于汇编中的 RRC;if((d&1)=1) DS1302_IO =1;else DS1302_IO =0;*/
for(j=0;j<5;j++);
DS1302_CLK = 1;
for(j=0;j<5;j++);
DS1302_CLK = 0;
ACC =ACC>> 1;
}
}
uchar OutputByte(void) /*实时时钟读取一字节(内部函数)调用之前应该使RST=1*/
{
uchar i,j;
for(i=8; i>0; i--)
{
ACC = ACC >>1;/*相当于汇编中的 RRC */
ACC7 = DS1302_IO;
for(j=0;j<5;j++);
DS1302_CLK = 1;
for(j=0;j<5;j++);
DS1302_CLK = 0;
}
return(ACC);
}
void Write1302(uchar ucAddr, uchar ucDa)/*ucAddr: DS1302地址, ucData: 要写的数据*/
{
DS1302_RST = 0;
DS1302_CLK = 0;
DS1302_RST = 1;
InputByte(ucAddr);/*地址,命令*/
InputByte(ucDa);/*写1Byte数据*/
DS1302_CLK = 1;
DS1302_RST = 0;
}
uchar Read1302(uchar ucAddr)/*读取DS1302某地址的数据*/
{
uchar ucData;
DS1302_RST = 0;
DS1302_CLK = 0;
DS1302_RST = 1;
InputByte(ucAddr|0x01); /*地址,命令 */
ucData = OutputByte(); /*读1Byte数据*/
DS1302_CLK = 1;
DS1302_RST = 0;
return(ucData);
}
/*读取时间日期函数*/
void readtime(uchar *p)
{
*p++=Read1302(DS1302_YEAR); /*读年值*/
*p++=Read1302(DS1302_MONTH); /*读月值*/
*p++=Read1302(DS1302_DAY); /*读日值*/
*p++=Read1302(DS1302_WEEK); /*读周值*/
*p++=Read1302(DS1302_HOUR); /*读时值*/
*p++=Read1302(DS1302_MINUTE); /*读分值*/
*p=Read1302(DS1302_SECOND); /*读秒值*/
}
void Initial_DS1302(void)
{ Write1302(DS1302_controler,0);
Write1302(DS1302_SECOND,0);
Write1302(DS1302_MONTH,9);
Write1302(DS1302_DAY,0x14);
Write1302(DS1302_WEEK,1);
Write1302(DS1302_HOUR,0x16);
Write1302(DS1302_MINUTE,0);
Write1302(DS1302_tricklecharger,0xa5);
Write1302(DS1302_controler,0x80);
}
main()
{
DS1302_RST=0;
DS1302_CLK=0;
DS1302_IO=0;
Initial_DS1302();
TMOD=0x01; /*T0工作在方式1,16位定时模式*/
TH0=(15536)/256; /*T0定时50MS,赋初值*/
TL0=(15535)%256;
IE=0x82; /*开放T0中断*/
TR0=1; /*T0开始运行*/
for(i=0;i<12;i++)
{
ledbuf[i]=tab[i];
}
displed();
while(1) /*循环体开始*/
{
if(flag) /*如果0。1秒时间到,则读取当前秒值*/
{
flag=0;
point=&timebuf; /*为读取时间值做准备,指针指向缓冲区首址*/
readtime(point);
// if(second!=timebuf[6]) /*如果秒已经更新,则处理所有参数*/
// {
second=timebuf[6]; /*拷贝秒副本,为下次循环做判断依据*/
ledbuf[11]=tab[(timebuf[0]&0xf0)>>4]; /*处理年高位*/
ledbuf[10]=tab[timebuf[0]&0x0f]; /*处理年低位*/
ledbuf[9]=tab[(timebuf[1]&0x10)>>4]; /*处理月高位*/
ledbuf[8]=tab[timebuf[1]&0x0f]; /*处理月低位*/
ledbuf[7]=tab[(timebuf[2]&0x30)>>4]; /*处理日高位*/
ledbuf[6]=tab[timebuf[2]&0x0f]; /*处理日低位*/
ledbuf[5]=tab[(timebuf[4]&0x30)>>4]; /*处理时高位*/
ledbuf[4]=tab[timebuf[4]&0x0f]; /*处理时低位*/
ledbuf[3]=tab[(timebuf[5]&0x70)>>4]; /*处理分高位*/
ledbuf[2]=tab[timebuf[5]&0x0f]; /*处理分低位*/
ledbuf[1]=tab[(timebuf[6]&0x70)>>4]; /*处理秒高位*/
ledbuf[0]=tab[timebuf[6]&0x0f]; /*处理秒低位*/
displed(); /*显示更新*/
// }
}
}
}
|