写时钟地址是写秒是80,读秒是81,如此类推,你读时间所有的地址都是写时钟地址是不对的。它是分开的,写是80、82.....,读时间是81、83.... |
188610329 发表于 2022-5-30 20:44 哈,成功解决我的1302用1602显示屏幕闪烁问题 |
188610329 发表于 2022-6-9 17:38 我不是在帮他,兴趣来了回一句,发现好象读写好象是用同地址,才写一句,要我仔细看他的程序我不乐意,毕竟这是个小功能通用应知的程序。 |
我的界面是这样的,说一下吧。 GPS对时,处理的是GPS模块输出的带时间的串口数据,处理时第二行会有乱码,表现为第一个空和30度这个3字处会有乱码。就象我所说的我想再水一个贴的话会写我的单片机会打游戏%,会输出%,%........,处理完串口数据就正常显示温度了。 12864一到三行显示是用一个16的数组算好后输出的。算好一行输出 ,再算下一行输出。 第四行用的是固定的字符串输出,遇空结束。 循环内还有读温度读时间的函数调用。 在串入一个输出秒的语句,打印可以大量有输出,但这时一到三行无显示了,第四行正常显示,。这也有点不解。 |
51hei图片_20220609193714.jpg (189.84 KB, 下载次数: 130)
188610329 发表于 2022-6-9 17:38 我的问题现在可能是资源方面或地址重叠问题。数据类型的不确定性已经是确认了的。现在是为什么被冲为零的问题,按说一个全局变量的值是不会变的。 |
188610329 发表于 2022-6-9 17:38 我连续打印过DS1302的数据,并没有0XFF情况发生,一个都没有。我是一下子读完时钟到一个数组的。 |
wolfinn 发表于 2022-6-9 01:43 他这个,其实和你的问题,是异曲同工,都是数据乱入问题,所以,你在解决你的问题之前,其实帮不到他……,代码来讲,虽然写的都不好,但都不是代码上的问题。 |
lkc8210 发表于 2022-6-9 10:05 哦,我没细看,我一般只看直观的。 |
wolfinn 发表于 2022-6-9 01:43 他的读函数内有先将地址最低位置一 所以形参用写时钟地址也是可以的 |
写时钟地址是写秒是80,读秒是81,如此类推,你读时间所有的地址都是写时钟地址是不对的。它是分开的,写是80、82.....,读时间是81、83.... |
尝试调整一下延时部分 |
数据和时钟线有没有加上拉电阻? |
1601791993 发表于 2022-5-31 09:17 感觉LCD显示代码有问题 |
给 0x8E 地址写 0x00 然后 再给。如取出的秒是58秒,要显示5则58这个数要除10的数加0x30才能在屏幕上显示出5,8这个数要58取10的余数即8加0x30才能显示出8.其他的同理。 |
188610329 发表于 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; } |
芯片是没有问题的…… 你的情况来看…… 可能,换条杜邦线比换芯片更靠谱…… |
小丑only 发表于 2022-5-30 22:50 准确说I5 是不是这两个1302的芯片都坏了 |
188610329 发表于 2022-5-30 22:29 亲,都写0了。变成15了。 ![]() |
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); //开启写保护 } 先不要搞得花里胡俏的, 就这样写完,然后,读看看,时间到底如何。 |
写了 0x00 至少显示 要变 00 吧? 你看看是不是写保护了, 给 0x8e 地址 写 0x00 , 然后再 给 0x80 地址 写 0x00 看看 |
你看看是不是 写保护了? 给 0x8E 地址写 0x00 然后 再给 |
STC8单片机+DS1302+DS18B20+74HC595的LED16x32点阵温度万年历源代码 http://www.51hei.com/bbs/dpj-200968-1.html 按我代码操作,如果还有问题 排查线路,尽量焊死,杜邦线十分不可靠 |
188610329 发表于 2022-5-30 21:23 写0X00了,没啥效果 ![]() |
188610329 发表于 2022-5-30 21:23 还有一个问题像大佬反馈,用串口打印的时候。1302输出两组数据后就自动停止了 |
188610329 发表于 2022-5-30 21:23 晶振问题能排除,下午用恒温晶振测试。没反应。 ![]() |
小丑only 发表于 2022-5-30 21:14 秒的数值 > 0x80 表示: 时钟停止 两个可能, 1) 没有写入 正确的秒钟时间,时钟没有启动,你尝试写入 0x00看看。 2) 晶振没有正常工作,会自动进入时钟停止模式。 检查一下晶振。 |
/*************读取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; } |
![]() ![]() |
感觉你没有处现数据:如取出的秒是58秒,要显示5则58这个数要除10的数加0x30才能在屏幕上显示出5,8这个数要58取10的余数即8加0x30才能显示出8.其他的同理。 |
#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); } |