找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2511|回复: 33
打印 上一主题 下一主题
收起左侧

单片机+DS1302程序 显示乱码,走时跳动?

  [复制链接]
跳转到指定楼层
楼主
不知道芯片怎么了,两个型号都这个问题。不走时或时间秒乱跳5-85-99-83等。。。乱码。

两次重启串口打印的信息

单片机源程序如下:
#include "DS1302.h"

u8 DS1302sec=1,DS1302min=1,DS1302hour=8;
u8 DS1302day=26,DS1302month=4,DS1302week,DS1302year=20;

/**********向1302写某一地址和数据(指令)**************/
void Write_Byte_1302(u8 add,u8 dat)
{
        u8 i;
        DS1302SCL = 0;
        DS1302RST = 1;
        add = add & 0xfe;                //将控制指令的最低位清零,数据能够输入
        for(i=0;i<8;i++)
        {
                DS1302SDA = add &0X01;
                DS1302SCL = 1;                        //上升沿输入数据
                DS1302SCL = 0;
                add >>= 1;
        }
        for(i=0;i<8;i++)
        {
                DS1302SDA = dat &0X01;
                DS1302SCL=1;                        //上升沿输入数据
                DS1302SCL=0;
                dat>>=1;
        }
      
        DS1302RST = 0;                        //写完数据后将rst清零,终止数传输
}

/*************读取1302的数据**********/
u8 Read_Byte_1302(u8 add)
{
        u8 i,dat;
        DS1302SCL = 0;
        DS1302RST = 1;                //开启数据传输
        add = add |0x01;                //将最低位置一,保证数据是输出
        for(i=0;i<8;i++)
        {
                DS1302SDA = add &0X01;
                DS1302SCL=1;
                DS1302SCL=0;
                add >>=1;
        }
        for(i=0;i<8;i++)
        {
                dat >>=1;
                if(DS1302SDA)        dat = dat | 0x80;
                else        dat = dat & 0x7f;
                DS1302SCL=1;
                DS1302SCL=0;
        }
        DS1302RST = 0;                        //终止数据传输
        dat=dat/16*10+dat%16;
        return        dat;
}

void Write_1302()
{
        Write_Byte_1302(0x8e,0x00);                //关闭写保护
        Write_Byte_1302(0x80,0x80);
        Write_Byte_1302(0x80,DS1302sec/10*16+DS1302sec%10);
        Write_Byte_1302(0x82,DS1302min/10*16+DS1302min%10);
        Write_Byte_1302(0x84,DS1302hour/10*16+DS1302hour%10);
        Write_Byte_1302(0x86,DS1302day/10*16+DS1302day%10);
        Write_Byte_1302(0x88,DS1302month/10*16+DS1302month%10);
        Write_Byte_1302(0x8c,DS1302year/10*16+DS1302year%10);
        Write_Byte_1302(0x8e,0x80);                //开启写保护
}


/***********************显示周*********************/
//=====计算2000~2099年任一天星期几
//                year:00-99
//                month:01-12
//                day:01-31
u8          GetWeekFromDay(u8 y,u8 m,u8 d)
{
        u8 value;
        if(m==1||m==2)
        {
                m+=12;
                if(y>0)        y--;
                else y=4;
        }
        value=(d+2*m+3*(m+1)/5+y+y/4)%7;
        return value;
}

void Read_1302()
{
        DS1302sec =Read_Byte_1302(0x80);
        DS1302min =Read_Byte_1302(0x82);
        DS1302hour =Read_Byte_1302(0x84);
        DS1302day =Read_Byte_1302(0x86);
        DS1302month =Read_Byte_1302(0x88);
        DS1302year =Read_Byte_1302(0x8c);
      
        DS1302week = GetWeekFromDay(DS1302year,DS1302month,DS1302day);
}

芯片.jpg (802.61 KB, 下载次数: 90)

芯片.jpg
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:447439 发表于 2022-5-30 19:07 | 只看该作者
#include "DS1302.h"

u8 DS1302sec=1,DS1302min=1,DS1302hour=8;
u8 DS1302day=26,DS1302month=4,DS1302week,DS1302year=20;

/**********向1302写某一地址和数据(指令)**************/
void Write_Byte_1302(u8 add,u8 dat)
{
        u8 i;
        DS1302SCL = 0;
        DS1302RST = 1;
        add = add & 0xfe;                //将控制指令的最低位清零,数据能够输入
        for(i=0;i<8;i++)
        {
                DS1302SDA = add &0X01;
                DS1302SCL = 1;                        //上升沿输入数据
                DS1302SCL = 0;
                add >>= 1;
        }
        for(i=0;i<8;i++)
        {
                DS1302SDA = dat &0X01;
                DS1302SCL=1;                        //上升沿输入数据
                DS1302SCL=0;
                dat>>=1;
        }
        
        DS1302RST = 0;                        //写完数据后将rst清零,终止数传输
}

/*************读取1302的数据**********/
u8 Read_Byte_1302(u8 add)
{
        u8 i,dat;
        DS1302SCL = 0;
        DS1302RST = 1;                //开启数据传输
        add = add |0x01;                //将最低位置一,保证数据是输出
        for(i=0;i<8;i++)
        {
                DS1302SDA = add &0X01;
                DS1302SCL=1;
                DS1302SCL=0;
                add >>=1;
        }
        for(i=0;i<8;i++)
        {
                dat >>=1;
                if(DS1302SDA)        dat = dat | 0x80;
                else        dat = dat & 0x7f;
                DS1302SCL=1;
                DS1302SCL=0;
        }
        DS1302RST = 0;                        //终止数据传输
        dat=dat/16*10+dat%16;
        return        dat;
}

void Write_1302()
{
        Write_Byte_1302(0x8e,0x00);                //关闭写保护
        Write_Byte_1302(0x80,0x80);
        Write_Byte_1302(0x80,DS1302sec/10*16+DS1302sec%10);
        Write_Byte_1302(0x82,DS1302min/10*16+DS1302min%10);
        Write_Byte_1302(0x84,DS1302hour/10*16+DS1302hour%10);
        Write_Byte_1302(0x86,DS1302day/10*16+DS1302day%10);
        Write_Byte_1302(0x88,DS1302month/10*16+DS1302month%10);
        Write_Byte_1302(0x8c,DS1302year/10*16+DS1302year%10);
        Write_Byte_1302(0x8e,0x80);                //开启写保护
}


/***********************显示周*********************/
//=====计算2000~2099年任一天星期几
//                year:00-99
//                month:01-12
//                day:01-31
u8          GetWeekFromDay(u8 y,u8 m,u8 d)
{
        u8 value;
        if(m==1||m==2)
        {
                m+=12;
                if(y>0)        y--;
                else y=4;
        }
        value=(d+2*m+3*(m+1)/5+y+y/4)%7;
        return value;
}

void Read_1302()
{
        DS1302sec =Read_Byte_1302(0x80);
        DS1302min =Read_Byte_1302(0x82);
        DS1302hour =Read_Byte_1302(0x84);
        DS1302day =Read_Byte_1302(0x86);
        DS1302month =Read_Byte_1302(0x88);
        DS1302year =Read_Byte_1302(0x8c);
        
        DS1302week = GetWeekFromDay(DS1302year,DS1302month,DS1302day);
}
回复

使用道具 举报

板凳
ID:776619 发表于 2022-5-30 20:22 | 只看该作者
感觉你没有处现数据:如取出的秒是58秒,要显示5则58这个数要除10的数加0x30才能在屏幕上显示出5,8这个数要58取10的余数即8加0x30才能显示出8.其他的同理。
回复

使用道具 举报

地板
ID:447439 发表于 2022-5-30 20:41 | 只看该作者
麻烦具体说说,我有点没反应过来。
回复

使用道具 举报

5#
ID:624769 发表于 2022-5-30 20:44 | 只看该作者
/*************读取1302的数据**********/
u8 Read_Byte_1302(u8 add)
{
        u8 i,dat;        DS1302SDA = 0;          //  << 这里加一句 这个  很多乱跳时间的问题就解决了
        DS1302SCL = 0;
        DS1302RST = 1;                //开启数据传输
        add = add |0x01;                //将最低位置一,保证数据是输出
        for(i=0;i<8;i++)
        {
                DS1302SDA = add &0X01;
                DS1302SCL=1;
                DS1302SCL=0;
                add >>=1;
        }
回复

使用道具 举报

6#
ID:447439 发表于 2022-5-30 21:14 | 只看该作者
188610329 发表于 2022-5-30 20:44
/*************读取1302的数据**********/
u8 Read_Byte_1302(u8 add)
{

谢谢亲,经测试解决乱码的问题了。但是还是显示87,83,>7等字................

无乱码.jpg (424.35 KB, 下载次数: 91)

无乱码.jpg
回复

使用道具 举报

7#
ID:624769 发表于 2022-5-30 21:23 | 只看该作者
小丑only 发表于 2022-5-30 21:14
谢谢亲,经测试解决乱码的问题了。但是还是显示87,83,>7等字................

秒的数值  >  0x80  表示:
时钟停止
两个可能,
1) 没有写入 正确的秒钟时间,时钟没有启动,你尝试写入 0x00看看。
2) 晶振没有正常工作,会自动进入时钟停止模式。 检查一下晶振。
回复

使用道具 举报

8#
ID:447439 发表于 2022-5-30 21:27 | 只看该作者
188610329 发表于 2022-5-30 21:23
秒的数值  >  0x80  表示:
时钟停止
两个可能,

晶振问题能排除,下午用恒温晶振测试。没反应。
回复

使用道具 举报

9#
ID:447439 发表于 2022-5-30 21:28 | 只看该作者
188610329 发表于 2022-5-30 21:23
秒的数值  >  0x80  表示:
时钟停止
两个可能,

还有一个问题像大佬反馈,用串口打印的时候。1302输出两组数据后就自动停止了
回复

使用道具 举报

10#
ID:447439 发表于 2022-5-30 21:43 | 只看该作者
188610329 发表于 2022-5-30 21:23
秒的数值  >  0x80  表示:
时钟停止
两个可能,

写0X00了,没啥效果
回复

使用道具 举报

11#
ID:390416 发表于 2022-5-30 21:45 | 只看该作者
STC8单片机+DS1302+DS18B20+74HC595的LED16x32点阵温度万年历源代码 http://www.51hei.com/bbs/dpj-200968-1.html

按我代码操作,如果还有问题 排查线路,尽量焊死,杜邦线十分不可靠
回复

使用道具 举报

12#
ID:624769 发表于 2022-5-30 22:28 | 只看该作者
你看看是不是 写保护了? 给 0x8E 地址写 0x00 然后 再给
回复

使用道具 举报

13#
ID:624769 发表于 2022-5-30 22:29 | 只看该作者
写了 0x00 至少显示 要变 00 吧?
你看看是不是写保护了, 给 0x8e 地址 写 0x00 , 然后再 给 0x80 地址 写 0x00 看看
回复

使用道具 举报

14#
ID:624769 发表于 2022-5-30 22:43 | 只看该作者
void Write_1302()
{
        Write_Byte_1302(0x8e,0x00);                //关闭写保护
        Write_Byte_1302(0x80,0x00);
//        Write_Byte_1302(0x80,DS1302sec/10*16+DS1302sec%10);
//        Write_Byte_1302(0x82,DS1302min/10*16+DS1302min%10);
//        Write_Byte_1302(0x84,DS1302hour/10*16+DS1302hour%10);
//        Write_Byte_1302(0x86,DS1302day/10*16+DS1302day%10);
//        Write_Byte_1302(0x88,DS1302month/10*16+DS1302month%10);
//        Write_Byte_1302(0x8c,DS1302year/10*16+DS1302year%10);
        Write_Byte_1302(0x8e,0x80);                //开启写保护
}


先不要搞得花里胡俏的, 就这样写完,然后,读看看,时间到底如何。
回复

使用道具 举报

15#
ID:447439 发表于 2022-5-30 22:48 | 只看该作者
188610329 发表于 2022-5-30 22:29
写了 0x00 至少显示 要变 00 吧?
你看看是不是写保护了, 给 0x8e 地址 写 0x00 , 然后再 给 0x80 地址  ...

亲,都写0了。变成15了。
回复

使用道具 举报

16#
ID:447439 发表于 2022-5-30 22:50 | 只看该作者
188610329 发表于 2022-5-30 22:43
void Write_1302()
{
        Write_Byte_1302(0x8e,0x00);                //关闭写保护

亲,0没变成,变成15了

写0.jpg (419.54 KB, 下载次数: 81)

写0.jpg
回复

使用道具 举报

17#
ID:447439 发表于 2022-5-30 22:52 | 只看该作者
小丑only 发表于 2022-5-30 22:50
亲,0没变成,变成15了

准确说I5


是不是这两个1302的芯片都坏了
回复

使用道具 举报

18#
ID:624769 发表于 2022-5-30 23:06 | 只看该作者

芯片是没有问题的……
你的情况来看…… 可能,换条杜邦线比换芯片更靠谱……
回复

使用道具 举报

19#
ID:624769 发表于 2022-5-30 23:16 | 只看该作者

I5    对应  0x49  0x35
基于你 串口通信   还原出 0x19  0x05     那么原值应该是 0xc3  即头尾 1  中间 0,

首先要确定,是写错还是读错, 你先给 DS1302 断电, 拿掉电池,1分钟后 再上电池, 再连接单片机, 然后看看时间恢复  成 全 01   秒 80 没有?

然后,读 / 写程序 加一些 NOP 延时, 看看效果, 最后,杜邦线 最好短些 好一些的。

       for(i=0;i<8;i++)
        {
                DS1302SDA = add &0X01;
                _nop_();                DS1302SCL=1;
                _nop_();
                _nop_();                DS1302SCL=0;
                add >>=1;
        }
        for(i=0;i<8;i++)
        {
                dat >>=1;
                if(DS1302SDA)        dat = dat | 0x80;
                else        dat = dat & 0x7f;
                _nop_();
                DS1302SCL=1;
                _nop_();
                _nop_();
                DS1302SCL=0;
        }

回复

使用道具 举报

20#
ID:447439 发表于 2022-5-30 23:18 | 只看该作者
188610329 发表于 2022-5-30 23:16
I5    对应  0x49  0x35
基于你 串口通信   还原出 0x19  0x05     那么原值应该是 0xc3  即头尾 1  中 ...

收到,谢谢。我再试试
回复

使用道具 举报

21#
ID:1031072 发表于 2022-5-31 09:17 来自手机 | 只看该作者
给 0x8E 地址写 0x00 然后 再给。如取出的秒是58秒,要显示5则58这个数要除10的数加0x30才能在屏幕上显示出5,8这个数要58取10的余数即8加0x30才能显示出8.其他的同理。
回复

使用道具 举报

22#
ID:1012735 发表于 2022-5-31 13:03 | 只看该作者
1601791993 发表于 2022-5-31 09:17
给 0x8E 地址写 0x00 然后 再给。如取出的秒是58秒,要显示5则58这个数要除10的数加0x30才能在屏幕上显示出 ...

感觉LCD显示代码有问题
回复

使用道具 举报

23#
ID:401564 发表于 2022-5-31 20:41 | 只看该作者
数据和时钟线有没有加上拉电阻?
回复

使用道具 举报

24#
ID:329625 发表于 2022-6-8 20:17 | 只看该作者
尝试调整一下延时部分
回复

使用道具 举报

25#
ID:776619 发表于 2022-6-9 01:43 | 只看该作者
写时钟地址是写秒是80,读秒是81,如此类推,你读时间所有的地址都是写时钟地址是不对的。它是分开的,写是80、82.....,读时间是81、83....
回复

使用道具 举报

26#
ID:161164 发表于 2022-6-9 10:05 | 只看该作者
wolfinn 发表于 2022-6-9 01:43
写时钟地址是写秒是80,读秒是81,如此类推,你读时间所有的地址都是写时钟地址是不对的。它是分开的,写是 ...

他的读函数内有先将地址最低位置一
所以形参用写时钟地址也是可以的
回复

使用道具 举报

27#
ID:776619 发表于 2022-6-9 14:28 | 只看该作者
lkc8210 发表于 2022-6-9 10:05
他的读函数内有先将地址最低位置一
所以形参用写时钟地址也是可以的

哦,我没细看,我一般只看直观的。
回复

使用道具 举报

28#
ID:624769 发表于 2022-6-9 17:38 来自手机 | 只看该作者
wolfinn 发表于 2022-6-9 01:43
写时钟地址是写秒是80,读秒是81,如此类推,你读时间所有的地址都是写时钟地址是不对的。它是分开的,写是 ...

他这个,其实和你的问题,是异曲同工,都是数据乱入问题,所以,你在解决你的问题之前,其实帮不到他……,代码来讲,虽然写的都不好,但都不是代码上的问题。
回复

使用道具 举报

29#
ID:776619 发表于 2022-6-9 19:18 | 只看该作者
188610329 发表于 2022-6-9 17:38
他这个,其实和你的问题,是异曲同工,都是数据乱入问题,所以,你在解决你的问题之前,其实帮不到他…… ...

我连续打印过DS1302的数据,并没有0XFF情况发生,一个都没有。我是一下子读完时钟到一个数组的。
回复

使用道具 举报

30#
ID:776619 发表于 2022-6-9 19:22 | 只看该作者
188610329 发表于 2022-6-9 17:38
他这个,其实和你的问题,是异曲同工,都是数据乱入问题,所以,你在解决你的问题之前,其实帮不到他…… ...

我的问题现在可能是资源方面或地址重叠问题。数据类型的不确定性已经是确认了的。现在是为什么被冲为零的问题,按说一个全局变量的值是不会变的。
回复

使用道具 举报

31#
ID:776619 发表于 2022-6-9 19:38 | 只看该作者
我的界面是这样的,说一下吧。
GPS对时,处理的是GPS模块输出的带时间的串口数据,处理时第二行会有乱码,表现为第一个空和30度这个3字处会有乱码。就象我所说的我想再水一个贴的话会写我的单片机会打游戏%,会输出%,%........,处理完串口数据就正常显示温度了。


12864一到三行显示是用一个16的数组算好后输出的。算好一行输出 ,再算下一行输出。
第四行用的是固定的字符串输出,遇空结束。
循环内还有读温度读时间的函数调用。
在串入一个输出秒的语句,打印可以大量有输出,但这时一到三行无显示了,第四行正常显示,。这也有点不解。

51hei图片_20220609193714.jpg (189.84 KB, 下载次数: 80)

51hei图片_20220609193714.jpg
回复

使用道具 举报

32#
ID:776619 发表于 2022-6-9 19:47 | 只看该作者
188610329 发表于 2022-6-9 17:38
他这个,其实和你的问题,是异曲同工,都是数据乱入问题,所以,你在解决你的问题之前,其实帮不到他…… ...

我不是在帮他,兴趣来了回一句,发现好象读写好象是用同地址,才写一句,要我仔细看他的程序我不乐意,毕竟这是个小功能通用应知的程序。
回复

使用道具 举报

33#
ID:100982 发表于 2022-8-26 16:40 | 只看该作者
188610329 发表于 2022-5-30 20:44
/*************读取1302的数据**********/
u8 Read_Byte_1302(u8 add)
{

哈,成功解决我的1302用1602显示屏幕闪烁问题
回复

使用道具 举报

34#
ID:979469 发表于 2022-8-29 08:27 | 只看该作者
写时钟地址是写秒是80,读秒是81,如此类推,你读时间所有的地址都是写时钟地址是不对的。它是分开的,写是80、82.....,读时间是81、83....
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表