一乐电子

一乐电子百科

 找回密码
 请使用微信账号登录和注册会员

QQ登录

只需一步,快速开始

快捷登录

手机号码,快捷登录

搜索
查看: 8264|回复: 65
收起左侧

[51单片机] 大尺寸万年历之收官篇

[复制链接]
发表于 2015-9-20 16:23 | 显示全部楼层 |阅读模式
得益于win10轻快多了,但也受限一些兼容问题浪费了太多时间,比如对pl2303串口的支持、截图……

GPS校时功能已昨夜加班已搞定,本想今天挂GPS连续测试两天看看有无bug,可天不开眼,从早上一直下起了雨,明天又要出差了,这下不到国庆节不会闲了。
早上起来突然想起可以加个电脑串口校时功能——不大改动程序的情况下,可以借用gps数据格式多三五行程序就OK了。
原理是这样的:
GPS标准数据如下:
$GPRMC,064350.000,A,2345.9876,N,12345.1234,E,0.25,90.45,200915,,,A*5F
把日期后面的","后加个“X”作标志尾做强制校时信号,
校时数据格式就是:
$GPRMC,064350.000,A,2345.9876,N,12345.1234,E,0.25,90.45,200915,X,,A*5F
标志头    ,时分秒(UTM) , ------中间数据可有可无,但“,”不能少--------日月年  ,标志尾

这样单片机获取到了串口数据以gps解析日期时间信息,在日期后读取到“X"就强制命令校时!方便没有gps的玩家。
程序中是这样的:
全局变量:
bit QJ;         //电脑发送强制校时信号

串口中断处理:
                case 9:                                //日期处理
                    ...............
                    break;
                case 10:                                //电脑是否发送强制校时信号          $GPRMC,024813.640,,,,,,,,150706,X
                    if(byte_count < 1)
                    {
                        QJ = tmp == 'X' ? 1 : 0;                //QJ 和 X 碰到一起了,别想歪了
                    }
                    break;



去年做的数码管万年历在gps部分遇到的一个”坑“还未抹平,今年的大数码管万年历绝不敢忽视,为了规范,晶振改为了11.0592M,研究了好几个带gps的万年历程序,发现都有或多或少的漏洞:
第一,都未加数据校验(或是仅仅做了个是否数字的校验,未使用原生异或校验),没法避免乱码情况,虽然99%的情况下数据算是”干净“的。
第二,程序本身就有bug,只不过在很多gps上不会出现问题而已。如处理数据时好多if后都未跟else,留下隐患。
举例:
     某程序采用LCD显示做成导航仪形式,在串口采集中进行数据归类:$GPRMC,$GPGGA,$GPGSA,$GPGSV,使用了4个if语句。若在这个4个标志头中出现了乱码怎么办,没else情况下程序很容易跑飞掉。

一个健壮的串口采集程序必须考虑乱码、断码、缺码,无头、无尾种种情况。总之而言是没有工业强度!
如果要考虑这么完全,那就不能在gps数据接收的过程中解析数据了,必须待整条数据($——\r\n)接收完成后再处理,这样造成的一个问题就是变量占用太多空间了。必须得定义一个unsigned char buf[80]。
另一个问题就是必须协调好中断问题:一组数据大概会有6条(3颗卫星的情况下),虽然对万年历来说有用的只有GPRMC,必须保证在处理GPRMC数据时不被其他数据”污染“。
显然把整条数据接收完整再处理会浪费时间。
我主要是因为业余时间太少,原本想按上述方法处理gps数据,包括我去年的数码管万年历就是上述方法,但又怕再次摔进同一个坑里面爬不起来,所以在尽可能地完善”校验“的情况下边接收边处理的。

其次是不知农历星期转换的原作者是谁了,那个类被太多人引用了,算是比较经典的了,我觉得其中有三点可以修正。
第一,农历转换数据数组是从1900——2099年。我们又不是算命测八字的,2000年前的数据就被我给做掉了,这一刀砍下去就能装进89C52了。本来想把2015年前的给做掉的,但DS3231的第一次启动时间是2000-1-1零时。
第二,原数据变量输入都是BCD码,我改成了10进制码。
第三,星期被我重新写了,由基姆拉尔森计算公式改编了下。
/*************************************************************************
        函数功能:输入阳历数据,输出星期数据(2000-2099年有效)
        调用函数示例:Conver_WEEK(year_sun,month_sun,day_sun)
        如:计算2015年9月16日就是 Conver_WEEK(15,9,16);
*****************************************************************************/
//使用基姆拉尔森计算公式 W= (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400) mod 7 改装
uchar Conver_WEEK(uchar year,uchar month,uchar day)
{       
    uchar iWeek=(day+2*month+3*(month+1)/5+year+year/4)%7 +1;
        return         iWeek;
}

这下农历类就被我刀劈斧削精悍多了。不要谢我,请感谢不知名的原作者

闲话少说,步入正题:
89C52RC + 11.0592M +MAX7219级联驱动
DS3231+GPS校时+语音报时+电脑授时


板子预留了DS12C887、18B20、红外、DHT11等接口,包括串口无线等说实话这些都不是我感兴趣的,只是因为板子这么大剩余IO这么大就顺便引出来了。

大数码管万年历程序:
wnl.rar (80.37 KB, 下载次数: 131, 售价: 3 人民币)


配套万年历电脑校时程序:
电脑授时.rar (223.6 KB, 下载次数: 221)

2015-09-20_160624.png



最新的GPS仿真程序也搭车重发一遍:
gps仿真V2.0.rar (225.81 KB, 下载次数: 64, 售价: 3 人民币)

2015-09-20_161318.png


欢迎技术回帖,私信一概不处理
发表于 2015-9-20 16:32 | 显示全部楼层
楼主厉害,俺抢楼慢慢学习
发表于 2015-9-20 17:39 | 显示全部楼层
时钟放窗边真的很不便。放远些又要拉长天线。
不如想想,gps模块+ESP8266/蓝牙+充电池,用来放窗边。
时钟用ESP8266/蓝牙,收gps讯号,或网上SNTP时钟,还方便得多。
发表于 2015-9-20 19:21 | 显示全部楼层
不错,这串口授时太好了。
发表于 2015-9-20 20:41 | 显示全部楼层
不错!!!
发表于 2015-9-20 20:59 来自手机 | 显示全部楼层
很好,楼主加班辛苦了。
发表于 2015-9-20 21:41 | 显示全部楼层
楼主空了还是共享一下电路图和pcb文件吧
发表于 2015-9-20 21:49 | 显示全部楼层
不错,能坚持玩真的需要毅力,我搞一段时间就烦躁了呀,我的6X7点阵还没搞好呢
发表于 2015-9-20 22:13 来自手机 | 显示全部楼层
俺也是一样,没有耐心弄,这几天给朋友弄些白光面板,都拖了,当然是不要银子的,大家玩玩
发表于 2015-9-20 22:14 来自手机 | 显示全部楼层
因为这不是我的主业,业余爱好而已。

本版积分规则

QQ|一淘宝店|手机版|商店|电子DIY套件|一乐电子 ( 粤ICP备09076165号 ) 公安备案粤公网安备 44522102000183号

GMT+8, 2024-4-19 21:47 , Processed in 0.073862 second(s), 48 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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