[求助] AVR上的DS1302程序读出来在液晶上显示错误

南方孩子   2014-4-4 18:30 楼主
为什么我的AVR上的DS1302程序读出来在液晶上显示全部都是55555

回复评论 (7)

2推荐 youluo 

读不出来肯定是1302没操作对。参考别人正确的例子吧。
点赞  2014-4-6 10:41
void display()
{
        c=DS1302Read(DS1302_HOUR_READ);
        write_data(table[c/10]);
        delayus(5);
        write_data(table[c%10]);
        write_data(' ');
        delayus(5);
        while(1);

        c=DS1302Read(DS1302_MINUTE_READ);
        write_data(table[c/10]);
        delayus(5);
        write_data(table[c%10]);
        write_data(' ');
        delayus(5);

        c=DS1302Read(DS1302_SECOND_READ);
        write_data(table[c/10]);
        delayus(5);
        write_data(table[c%10]);
        write_data(' ');
        delayus(5);

        write_com(0x80+0x40);

        c=DS1302Read(DS1302_DAY_READ);
        write_data(table[c/10]);
        delayus(5);
        write_data(table[c%10]);
        write_data(' ');
        delayus(5);

        c=DS1302Read(DS1302_MONTH_READ);
        write_data(table[c/10]);
        delayus(5);
        write_data(table[c%10]);
        write_data(' ');
        delayus(5);

        c=DS1302Read(DS1302_YEAR_READ);
        write_data(table[c/10]);
        delayus(5);
        write_data(table[c%10]);
        write_data(' ');
        delayus(5);
        write_com(0x01);
        delayus(5);

}
点赞  2014-4-4 18:37
这是我的显示程序。是不是延时太短了。。急救啊  我是一名单片机菜鸟,这个已经做了好多天了
点赞  2014-4-4 18:38
第一段程序有个while(1);程序岂不是一直在这里死循环?
点赞  2014-4-4 20:07
引用: oyueyueniao 发表于 2014-4-4 20:07
第一段程序有个while(1);程序岂不是一直在这里死循环?

哦,谢谢,但是我改了还是不行,刚刚一直在想,发现是BCD码转换没有注意到。。。uchar BcdToBin(uchar val)
  {
  val = (val >> 4) *10+(val &0x0f); ///将BCD码转换为10进制数
  return val; ///返回10进制数
  }
但是改了以后还是不行,这次不显示全是5了,液晶上显示3 1 7 。。。数字还是不对,完全不对。而且数字中间有空格,而我的程序里没有加空格。。。
#include
#include
#include
#define uchar unsigned char
#define uint unsigned int
#define delayms(x) _delay_ms(x)
#define delayus(x) _delay_us(x)


#define rsddr        DDRD
#define rsport         PORTD
#define rspin         PIND


#define rwddr         DDRD
#define rwport         PORTD
#define rwpin         PIND


#define enddr         DDRD
#define enport         PORTD
#define enpin         PIND


#define DS1302_SECOND_WRITE 0x80
#define DS1302_MINUTE_WRITE 0x82
#define DS1302_HOUR_WRITE 0x84
#define DS1302_DAY_WRITE 0x86
#define DS1302_MONTH_WRITE 0x88
#define DS1302_WEEK_WRITE 0x8a
#define DS1302_YEAR_WRITE 0x8c


#define DS1302_YEAR_READ 0x8d
#define DS1302_MONTH_READ 0x89
#define DS1302_DAY_READ 0x87
#define DS1302_HOUR_READ 0x85
#define DS1302_MINUTE_READ 0x83
#define DS1302_SECOND_READ 0x81


#define RST PORTB
#define SCLK PORTB
#define SDA PORTC


uchar c,shi,ge;
uchar year1=0x88;
uchar year0=0x88;
uchar month1=0x88;
uchar month0=0x88;
uchar date1=0x88;
uchar date0=0x88;
uchar day1=0x88;
uchar day0=0x88;
uchar hour1=0x88;
uchar hour0=0x88;
uchar minute1=0x88;
uchar minute0=0x88;
uchar second1=0x88;
uchar second0=0x88;
uchar table[]={'0','1','2','3','4','5','6','7','8','9','0'};




void DS1302WriteByte(uchar dat)
{
        uchar i;
        SCLK &=~(1<<7);//初始时钟线置为0
        delayus(2);
        for(i=0;i<8;i++)//开始传输8字节的数据
        {
                if(dat&0x01)
                {
                        SDA|=(1<<1);
                }
                else
                {
                        SDA &=~(1<<1);
                }
        //取最低位,注意DS1302的数据和地址都是从最低位开始传输的
                delayus(2);
                SCLK|=(1<<7);//时钟线拉高,制造上升沿,SDA的数据被传输
                delayus(2);
                SCLK &=~(1<<7);//时钟线拉低,为下一个上升沿做准备
                dat>>=1;//数据右移一位,准备传输下一位数据
        }
}


uchar DS1302Write(uchar cmd,uchar dat)
{
        RST &=~(1<<4);//初始CE线置为0
        SCLK &=~(1<<7);//初始时钟线置为0
        RST|=(1<<4);//初始化CE置为1,传输开始


        DS1302WriteByte(cmd);//传输命令字,要写入的时间/日历地址
        DS1302WriteByte(dat);//写入要修改的时间/日期


        SCLK|=(1<<7);//时钟线拉高,一个上升沿写入数据
        RST &=~(1<<4);//读取结束,CE置为0,结束数据的传输
}










int DS1302ReadByte()
{       
        DDRC=0x00;////////IO口设为输入
        PORTC=0x00;//IO脚要设为高阻状态
        RST|=(1<<4);
        uchar i,dat;
        delayus(2);
        for(i=0;i<8;i++)
        {
                dat>>=1;//要返回的数据右移一位
                if(PINA|0x02)//当数据线为高时,证明该位数据为1
                {
                        dat|=0x80;//要传输数据的当前值置为1,若不是,则为0
                }
                SCLK|=(1<<7);//拉高时钟线
                delayus(2);
                SCLK &=~(1<<7);//制造下降沿,时钟下降沿才能读取数据
                delayus(2);


        }
        return dat;//返回读取出的数据
}


uchar DS1302Read(uchar cmd)
{
        DDRC=0x00;
        uchar dat;
        RST &=~(1<<4);//初始化CE线置为0
        SCLK &=~(1<<7);//初始化时钟线置为0,而且只有sclk为0时才能置rst为1
        RST|=(1<<4);//初始化CE置为1,传输开始




        DS1302WriteByte(cmd);//传输命令字,要读取的时间/日历地址




        dat=DS1302ReadByte();//读取要得到的时间/日期






        SCLK|=(1<<7);//时钟线拉高
        RST &=~(1<<4);//读取结束,CE置为0,结束数据的传输
        return dat;//返回得到的时间/日期
}






void initDS1302(void)
{
        DDRA=0xff;
        DS1302Write(0x8e,0x00);//写保护关
        DS1302Write(DS1302_SECOND_WRITE,0x00);//初始化秒值为0
        DS1302Write(DS1302_MINUTE_WRITE,0x20);//初始化分钟值为0
        DS1302Write(DS1302_HOUR_WRITE,0x09);//初始化为24小时模式 初始化时间为9点
        DS1302Write(DS1302_DAY_WRITE,0x23);//2010年1月1日 星期6   25
        DS1302Write(DS1302_MONTH_WRITE,0x04);//12月
        DS1302Write(DS1302_YEAR_WRITE,0x95);//10年
//        DS1302Write(DS1302_WEEK_WRITE,0x00);
//        DS1302Write(DS1302_SECOND_WRITE,0x06);
        DS1302Write(0x90,0x01);//充电
        DS1302Write(0xc0,0xf0);//初始化一次标示
        DS1302Write(0x8e,0x80);//写保护开
}




////液晶显示程
void write_com(uchar com)
{       
        rsddr|=(1<<0);
        rsport &=~(1<<0);
        DDRA=0xff;//液晶端口
        PORTA=com;
        delayms(3);


        enddr|=(1<<2);
        enport|=(1<<2);
        delayms(3);
        enport &=~(1<<2);       
}
void init()
{
        rwddr|=(1<<1);
        rwport &=~(1<<1);       
        enddr|=(1<<2);
        enport &=~(1<<2);
        write_com(0x38);//显示模式
        write_com(0x0e);//开显示 显示光标
        write_com(0x06);//当读或写一个字符后地址指针加一
        write_com(0x01);//数据指针清零
        write_com(0x80);//数据指针初始化       
}


void write_data(uchar date)
{
        rsddr|=(1<<0);
        rsport|=(1<<0);
        DDRA=0xff;//液晶端口
        PORTA=date;//液晶端口
        delayms(3);


        enddr|=(1<<2);
        enport|=(1<<2);
        delayms(3);
        enport &=~(1<<2);       
}


///////液晶显示程

void display()
{
        c=DS1302Read(DS1302_HOUR_READ);
        hour0=c&0x0f;
        hour1=(c>>4)&0x03;
        delayms(10);
        write_data(table[hour1]);
        delayms(5);
        write_data(table[hour0]);
//        write_data(' ');
        delayms(5);


        c=DS1302Read(DS1302_MINUTE_READ);//分
        minute0=c&0x0f;
        minute1=(c>>4)&0x07;
        delayms(10);
        write_data(table[minute1]);
        delayms(5);
        write_data(table[minute0]);
//        write_data(' ');
        delayms(5);


        c=DS1302Read(DS1302_SECOND_READ);//秒
        second0=c&0x0f;
        second1=(c>>4)&0x07;
        delayms(10);
        write_data(table[second1]);
        delayms(5);
        write_data(table[second0]);
//        write_data(' ');
        delayms(5);


        write_com(0x80+0x40);


        c=DS1302Read(DS1302_DAY_READ);//日
        date0=c&0x0f;
        date1=(c>>4)&0x03;//只可能是1-3
        delayms(10);
        write_data(table[date1]);
        delayms(5);
        write_data(table[date0]);
//        write_data(' ');
        delayms(5);


        c=DS1302Read(DS1302_MONTH_READ);//月
        month0=c&0x0f;//个位
        month1=(c>>4)&0x01;//十位只可能是1
        delayms(10);
        write_data(table[month1]);
        delayms(5);
        write_data(table[month0]);
//        write_data(' ');
        delayms(5);


        c=DS1302Read(DS1302_YEAR_READ);//年
        year0=c&0x0f;//!!!!读到的数的前四位是十位,后四位是个位
        year1=c>>4;
        delayms(10);
        write_data(table[year1]);
        delayms(50);
        write_data(table[year0]);
//        write_data(' ');
        delayms(5);


        write_com(0x01);//清屏!!!
        delayms(50);


}
int  main()
{
       
        DDRB=0xff;
        rsddr|=(1<<0);
        rwddr|=(1<<1);
        enddr|=(1<<2);
        DDRA=0xff;       
        init();//初始化液晶1602
        sei();//开总中断
        initDS1302();
        while(1)
        {
                display();
                delayms(500);
        }       


}


点赞  2014-4-4 20:59
#include
#include
#include
#define uchar unsigned char
#define uint unsigned int
#define delayms(x) _delay_ms(x)
#define delayus(x) _delay_us(x)

#define rsddr        DDRD
#define rsport         PORTD
#define rspin         PIND

#define rwddr         DDRD
#define rwport         PORTD
#define rwpin         PIND

#define enddr         DDRD
#define enport         PORTD
#define enpin         PIND

#define DS1302_SECOND_WRITE 0x80
#define DS1302_MINUTE_WRITE 0x82
#define DS1302_HOUR_WRITE 0x84
#define DS1302_DAY_WRITE 0x86
#define DS1302_MONTH_WRITE 0x88
#define DS1302_WEEK_WRITE 0x8a
#define DS1302_YEAR_WRITE 0x8c

#define DS1302_YEAR_READ 0x8d
#define DS1302_MONTH_READ 0x89
#define DS1302_DAY_READ 0x87
#define DS1302_HOUR_READ 0x85
#define DS1302_MINUTE_READ 0x83
#define DS1302_SECOND_READ 0x81

#define RST PORTB
#define SCLK PORTB
#define SDA PORTC

uchar c,shi,ge;
uchar year1=0x88;
uchar year0=0x88;
uchar month1=0x88;
uchar month0=0x88;
uchar date1=0x88;
uchar date0=0x88;
uchar day1=0x88;
uchar day0=0x88;
uchar hour1=0x88;
uchar hour0=0x88;
uchar minute1=0x88;
uchar minute0=0x88;
uchar second1=0x88;
uchar second0=0x88;
uchar table[]={'0','1','2','3','4','5','6','7','8','9','0'};


void DS1302WriteByte(uchar dat)
{
        uchar i;
        SCLK &=~(1<<7);//初始时钟线置为0
        delayus(2);
        for(i=0;i<8;i++)//开始传输8字节的数据
        {
                if(dat&0x01)
                {
                        SDA|=(1<<1);
                }
                else
                {
                        SDA &=~(1<<1);
                }
        //取最低位,注意DS1302的数据和地址都是从最低位开始传输的
                delayus(2);
                SCLK|=(1<<7);//时钟线拉高,制造上升沿,SDA的数据被传输
                delayus(2);
                SCLK &=~(1<<7);//时钟线拉低,为下一个上升沿做准备
                dat>>=1;//数据右移一位,准备传输下一位数据
        }
}

uchar DS1302Write(uchar cmd,uchar dat)
{
        RST &=~(1<<4);//初始CE线置为0
        SCLK &=~(1<<7);//初始时钟线置为0
        RST|=(1<<4);//初始化CE置为1,传输开始

        DS1302WriteByte(cmd);//传输命令字,要写入的时间/日历地址
        DS1302WriteByte(dat);//写入要修改的时间/日期

        SCLK|=(1<<7);//时钟线拉高,一个上升沿写入数据
        RST &=~(1<<4);//读取结束,CE置为0,结束数据的传输
}





int DS1302ReadByte()
{       
        DDRC=0x00;////////IO口设为输入
        PORTC=0x00;//IO脚要设为高阻状态
        RST|=(1<<4);
        uchar i,dat;
        delayus(2);
        for(i=0;i<8;i++)
        {
                dat>>=1;//要返回的数据右移一位
                if(PINA|0x02)//当数据线为高时,证明该位数据为1
                {
                        dat|=0x80;//要传输数据的当前值置为1,若不是,则为0
                }
                SCLK|=(1<<7);//拉高时钟线
                delayus(2);
                SCLK &=~(1<<7);//制造下降沿,时钟下降沿才能读取数据
                delayus(2);

        }
        return dat;//返回读取出的数据
}

uchar DS1302Read(uchar cmd)
{
        DDRC=0x00;
        uchar dat;
        RST &=~(1<<4);//初始化CE线置为0
        SCLK &=~(1<<7);//初始化时钟线置为0,而且只有sclk为0时才能置rst为1
        RST|=(1<<4);//初始化CE置为1,传输开始


        DS1302WriteByte(cmd);//传输命令字,要读取的时间/日历地址


        dat=DS1302ReadByte();//读取要得到的时间/日期



        SCLK|=(1<<7);//时钟线拉高
        RST &=~(1<<4);//读取结束,CE置为0,结束数据的传输
        return dat;//返回得到的时间/日期
}



void initDS1302(void)
{
        DDRA=0xff;
        DS1302Write(0x8e,0x00);//写保护关
        DS1302Write(DS1302_SECOND_WRITE,0x00);//初始化秒值为0
        DS1302Write(DS1302_MINUTE_WRITE,0x20);//初始化分钟值为0
        DS1302Write(DS1302_HOUR_WRITE,0x09);//初始化为24小时模式 初始化时间为9点
        DS1302Write(DS1302_DAY_WRITE,0x23);//2010年1月1日 星期6   25
        DS1302Write(DS1302_MONTH_WRITE,0x04);//12月
        DS1302Write(DS1302_YEAR_WRITE,0x95);//10年
//        DS1302Write(DS1302_WEEK_WRITE,0x00);
//        DS1302Write(DS1302_SECOND_WRITE,0x06);
        DS1302Write(0x90,0x01);//充电
        DS1302Write(0xc0,0xf0);//初始化一次标示
        DS1302Write(0x8e,0x80);//写保护开
}


////液晶显示程序
void write_com(uchar com)
{       
        rsddr|=(1<<0);
        rsport &=~(1<<0);
        DDRA=0xff;//液晶端口
        PORTA=com;
        delayms(3);

        enddr|=(1<<2);
        enport|=(1<<2);
        delayms(3);
        enport &=~(1<<2);       
}
void init()
{
        rwddr|=(1<<1);
        rwport &=~(1<<1);       
        enddr|=(1<<2);
        enport &=~(1<<2);
        write_com(0x38);//显示模式
        write_com(0x0e);//开显示 显示光标
        write_com(0x06);//当读或写一个字符后地址指针加一
        write_com(0x01);//数据指针清零
        write_com(0x80);//数据指针初始化       
}

void write_data(uchar date)
{
        rsddr|=(1<<0);
        rsport|=(1<<0);
        DDRA=0xff;//液晶端口
        PORTA=date;//液晶端口
        delayms(3);

        enddr|=(1<<2);
        enport|=(1<<2);
        delayms(3);
        enport &=~(1<<2);       
}

///////液晶显示程序


void display()
{
        c=DS1302Read(DS1302_HOUR_READ);
        hour0=c&0x0f;
        hour1=(c>>4)&0x03;
        delayms(10);
        write_data(table[hour1]);
        delayms(5);
        write_data(table[hour0]);
//        write_data(' ');
        delayms(5);

        c=DS1302Read(DS1302_MINUTE_READ);//分
        minute0=c&0x0f;
        minute1=(c>>4)&0x07;
        delayms(10);
        write_data(table[minute1]);
        delayms(5);
        write_data(table[minute0]);
//        write_data(' ');
        delayms(5);

        c=DS1302Read(DS1302_SECOND_READ);//秒
        second0=c&0x0f;
        second1=(c>>4)&0x07;
        delayms(10);
        write_data(table[second1]);
        delayms(5);
        write_data(table[second0]);
//        write_data(' ');
        delayms(5);

        write_com(0x80+0x40);

        c=DS1302Read(DS1302_DAY_READ);//日
        date0=c&0x0f;
        date1=(c>>4)&0x03;//只可能是1-3
        delayms(10);
        write_data(table[date1]);
        delayms(5);
        write_data(table[date0]);
//        write_data(' ');
        delayms(5);

        c=DS1302Read(DS1302_MONTH_READ);//月
        month0=c&0x0f;//个位
        month1=(c>>4)&0x01;//十位只可能是1
        delayms(10);
        write_data(table[month1]);
        delayms(5);
        write_data(table[month0]);
//        write_data(' ');
        delayms(5);

        c=DS1302Read(DS1302_YEAR_READ);//年
        year0=c&0x0f;//!!!!读到的数的前四位是十位,后四位是个位
        year1=c>>4;
        delayms(10);
        write_data(table[year1]);
        delayms(50);
        write_data(table[year0]);
//        write_data(' ');
        delayms(5);

        write_com(0x01);//清屏!!!
        delayms(50);

}


int  main()
{
       
        DDRB=0xff;
        rsddr|=(1<<0);
        rwddr|=(1<<1);
        enddr|=(1<<2);
        DDRA=0xff;       
        init();//初始化液晶1602
        sei();//开总中断
        initDS1302();
        while(1)
        {
                display();
                delayms(500);
        }       

}
点赞  2014-4-4 21:00
上面是我的程序。。就是不行 。。求大神帮助。。。
点赞  2014-4-4 21:01
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复