查看: 21053
回复: 17
参赛作品《STM32桌面万年历》

主题

回复
发表于2017-06-17 12:09:21 | 显示全部楼层
1# 电梯直达

【报名阶段需要填写的内容】


1. 参赛者姓名(必填项):戴旭文


2. 单位或学校名称(必填项):沈阳航空航天大学


3. 当前职务或职称(必填项):学生


4. 参赛作品的名字(必填项):STM32桌面万年历


5. 简要陈述您的idea和作品(必填项):

使用48脚STM32F103C8T6和12864液晶屏,设计一款桌面万年历,可实现年、月、日、时、分、秒、周、农历、温度的显示,可通过卫星授时校准时间。

使用STM32内置的RTC可得到时间,然后通过一套复杂的算法得到农历和周历。STM32的AD转换脚外接NTC热敏电阻,通过二分法查表的方式可得到准确度0.1℃的温度值。

系统可连接GPS模块(选配),每隔24小时自动获取卫星授时,校准当前时间。


6. 拟用到的立创商城在售物料(必填项):

STM32F103C8T6


7. 拟用到的非立创商城物料或其它补充(必填项):

LCD12864液晶屏


【作品正式发表(报名成功后进入设计阶段)需要填写的内容】


一、作品简介


1.作品的整机外观图片或焊接组装好的PCBA图片;


 点击查看大图 


点击查看大图


2.作品在创新性、趣味性、实用性甚至公益性方面,有哪些亮点可体现?


创新点1:实现了低速度低容量MCU产品公历转农历的算法。

STM32在功能上能满足大部份对速度要求不高的应用场合的要求,且价格低廉,开发工具普及程度高,是目前应用最多的MCU之一。本作品使用STM32实现从1901年到2099年199年公历日到农历日及星期的转换方法,并向读者提供完整的C语言程序。

农历与公历不同农历把月亮绕地球一周作为一月。因为月亮绕地球一周不是一整天,所以农历把月分为大月和小月,大月30天,小月29天。通过设置大小月,使农历日始终与月亮与地球的位置相对应。为了使农历的年份与公历年相对应,农历通过设置闰月的办法使它的平均年长度与公历年相等。农历是中国传统文化的代表之一,并与农业生产联系密切,中国人民特别是广大农民十分熟悉并喜爱农历。
公历与农历是我国目前并存的两种历法,各有其固有的规律。农历与月球的运行相对应,其影响因素多,它的大小月和闰月与天体运行有关,计算十分复杂,且每年都不一致。因此要用单片机实现公历与农历的转换,用查表法是最方便实用的办法。


创新点2:实现了一种高准确度NTC温度转换算法。


NTC热敏电阻是利用半导体材料制成的温度敏感元件,其电阻值会随着温度的升高而变小,又称负温度系数热敏电阻器。NTC系列热敏电阻已广泛应用于家用电器产品中,以达到自动增益调整、过负荷保护、温度控制、温度补偿、稳压稳幅等作用。这种具有负温度系数特性的热敏电阻稳定性好、响应快、寿命长、成本低,广泛应用于温度控制系统。

相比于单总线的18B20来说,NTC不但价格便宜,准确度也高。


趣味性:使用单片机做万年历已经数见不鲜了,每年很多在校学生课程设计、毕业设计都有做的,都很粗糙,理论性欠佳。作者我想从专业性角度,给大家做个示范,完美完成从单片机爱好者到单片机工程师的角色转换。对于一款电子产品,每一个细节都值得深入探究。


二、系统构架图

用流程图或思维导图等形式,描述您的作品的组成构架,即方案图。


1、公历转农历的算法实现。


实现公历与农历的转换,一般采用查表法,按日查表是速度最快的方法,单片机寻址能力有限,不可能采用按日查表的方法。除按日查外,我们可以通过按月查表和按年查表的方法,再通过适当的计算,来确定公历日所对应的农历日期。本文采用的是按年查表法,最大限度地减少表格所占的程序空间。
对于农历月来说,大月为30天,小月为29天,这是固定不变的,这样我们就可用1个BIT位来表示大小月信息。农历一年,如有闰月为13个月,否则是12个月,所以一年需要用13个BIT,闰月在农历年中所在的月份并不固定,大部分闰月分布在农历2-8月,但也有少量年份在9月以后,所以要表示闰月的信息,至少要4BIT,在这里我们用4BIT的值来表示闰月的月份值,为0表示本年没有闰月。有了以上信息,还不足以判断公历日对应的农历日,因为还需要一个参照日,我们选用农历正月初一所对应的公历日期作参照日,公历日最大为31日,需要5BIT来表示,而春节所在的月份不是1月就是2月,用1BIT就够了,考虑到表达方便,我们用2BIT来表示春节月,2BIT的值直接表示月份。这样一年的农历信息只用3个字节就全部包括了。
计算公历日对应的农历日期的方法:先计算出公历日离当年元旦的天数然,后查表取得当年的春节日期,计算出春节离元旦的天数,二者相减即可算出公历日离春节的天数,以后只要根据大小月和闰月信息,减一月天数,调整一月农历月份,即可推算出公历日所对应的农历日期。如公历日不到春节日期,农历年要比公历年小一年,农历大小月取前一年的信息。农历月从12月向前推算。
公历日是非常有规律的,所以公历日所对应的星期天可以通过计算直接得到,理论上公元0年1月1日为星期日,只要求得公历日离公元0年1月1日的日子数,除7后的余数就是星期天,为了简化计算,采用月校正法,根据公历的年月日可直接计算出星期天。其算法是:日期+年份+所过闰年数+月校正数之和除7的余数就是星期天,但如果是在闰年又不到3月份,上述之和要减一天再除7。其1-12月的校正数据为:6、2、2、5、0、3、5、1、4、6、2、4。在本程序中采用1个字节表示年份,闰年数也只计算1900年以后的闰年数,所以实际校正数据也和上述数据不同。


 点击查看大图



2、公历转星期算法实现


星期制度是一种有古老传统的制度。据说因为《圣经·创世纪》中规定上帝用了六 天时间创世纪,第七天休息,所以人们也就以七天为一个周期来安排自己的工作和生 活,而星期日是休息日。从实际的角度来讲,以七天为一个周期,长短也比较合适。所 以尽管中国的传统工作周期是十天(比如王勃《滕王阁序》中说的“十旬休暇”,即是 指官员的工作每十日为一个周期,第十日休假),但后来也采取了西方的星期制度。

基姆拉尔森计算公式
W= (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400) mod 7
在公式中d表示日期中的日数,m表示月份数,y表示年数。
注意:在公式中有个与其他公式不同的地方:
把一月和二月看成是上一年的十三月和十四月,例:如果是2004-1-10则换算成:2003-13-10来代入公式计算。
以公元元年为参考,公元元年1月1日为星期一。


3、使用二分法精确获得NTC采集的温度值。


购买NTC热敏电阻的时候,厂家会给一份表格,每隔1摄氏度会给出一个标准阻值。

NTC分度表.rar 

由生产厂家给的标准数据表可以看出,NTC热敏电阻阻值会随着温度的升高而变小,如下图所示:

 

通过折线图可以看出,随着被测温度升高,热敏电阻阻值减小,线性度不好。

问题一:如何解决线性度不好的问题?

热敏电阻通常的使用方法,是串联一个定值电阻1.5K,与热敏电阻进行分压,将分压之后的电压值送入AD转换,通过数学算法求得真实温度值。

 
如图所示,热敏电阻R_NTC与定值电阻R_FIXED进行分压,分压之后经过电压跟随器送入AD转换,这里的电压跟随器可保护AD转换芯片不受突然的静电、强电干扰。
表1的第三列为热敏电阻与定值电阻分压之后的比率,其换算公式为:
ADC=(R_NTC)/(R_NTC+R_FIXED)*4096

注:对于12位的AD转换来说,输入电压值最高为3.3V,最低为0V,当输入3.3V时,ADC转换后的值212=4095,当输入0V时,ADC转换后的值为0。如下图所示,热敏电阻与1.5K定值电阻分压之后曲线(下图浅绿色),在常温环境下,线性度已经好了许多。


 


由热敏电阻与定值电阻分压的比率公式:
ADC=(R_NTC)/(R_NTC+R_FIXED)*4096
可以看出,热敏电阻阻值在0.2918K(130℃)和151.24K(-30℃)范围之间变化,分压电阻R_FIXED如果取值过大,那么在低温的时候不准;如果取值过小,那么在高温的时候不准。常用电阻分压之后的曲线图如下所示:


 

从上图可以看出,如果需要测常温的话,10K的分压电阻比较合适;如果需要测量高温的话,1K的分压电阻比较合适。我做的系统需要测量常温,所以选取10K分压电阻。没有一种恰到好处的阻值能够适用于所有的温度区间,只能说在不同阻值的分压电阻适合不同的温度区间段。


做实际项目要求的精度更高,怎样才能将误差降到最低?答案是尽可能的提高分段数量。论文作者将曲线分成了10段,每小段近似为曲线。我将曲线分为160段,每一摄氏度分一段,然后每小段近似为直线,这样一来精度大大提高。
例如,ADC转换得到的值为3077,经过查表,温度43℃时ADC值为3102,温度44℃时ADC值为3072,所以,此时的温度值介于43℃和44℃之间,且更偏向于44摄氏度。
令温度值Temp为自变量,ADC值为因变量。
ADC=k*Temp+b
代入(43,3102) (44,3072)得k=-30,b=4392.此时代入测得的ADC值3077,得真实温度值为:43.8摄氏度。


问题二:计算机程序如何查表,速度最快?

二分法,又称分半法,是一种方程式根的近似值求法。对于区间[a,b]上连续不断且f(a) ?f(b)<0的函数y=f(x),通过不断地把函数f(x)的零点所在的区间一分为二,使区间的两个端点逐步逼近零点,进而得到零点近似值的方法叫做二分法(bisection)。


 


1)如果要求已知函数 f(x) = 0 的根 (x 的解),那么

2)先要找出一个区间 [a, b],使得f(a)与f(b)异号。根据介值定理,这个区间内一定包含着方程式的根。
3)求该区间的中点m=(a+b)/2,并找出 f(m) 的值。
4)若 f(m) 与 f(a) 正负号相同,则取 [m, b] 为新的区间, 否则取 [a, m]。
5)重复第3步和第4步,直到得到理想的精确度为止。


三、硬件部分的描述


作品分为底板和STM32核心板。核心板为DIP40封装,引脚兼容传统3.3V的51单片机。

STM32的PB0~PB7连接LCD12864的D0~D7,剩下的RS、RW、EN也接到STM32普通IO口上。

温度采集部分,默认连接NTC,同时预留DS18B20位置和红外接收头的位置。

STM32的串口2(PA2、PA3)预留,可连接GPS模块,实现卫星授时功能(预留)。


第1版程序:实现了万年历的功能部分,包括12864显示年、月、日、时、分、秒、农历、周历,温度从18B20获取。

未实现功能:调整时间、ADC转换、二分法转换NTC温度、GPS模块卫星授时

STM32F103C8T6万年历(第1版).rar 


第2版程序:增加了串口2调整时间、ADC转换、二分法转换NTC温度功能。

STM32F103C8T6万年历(第2版).rar 

串口调整时间软件如下图:

 

串口更新时间上位机程序.rar 




四、材料清单(BOM列表)


STM32F103C8T6:http://www.szlcsc.com/product/details_9243.html

32.768K晶振:http://www.szlcsc.com/product/details_94423.html

8M晶振:http://www.szlcsc.com/product/details_113035.html


五、作品演示

作品的功能展示视频已经上传,地址为https://v.qq.com/x/page/c0540qry6wi.html


六、总结

首先,感谢立创商城能够提供我们这么好的一个展示平台,嵌入式的学习向来不是纸上谈兵,只有实践才能出真知,对于像我们这样,刚刚踏入嵌入式领域学习大门的新手来说,任何一次实际的操作、设计,都是我们学习的过程,在本次设计中,遇到了很多问题,比如开机上电复位时热敏电阻未就绪,导致度数错误等等,在老师和师兄们的帮助下,总算是踩点完成了制作。

最后,衷心祝愿嘉立创越办越好!


主题

回复
发表于2017-07-01 22:37:09   |  显示全部楼层
4#
我此前就用过,该版本万年历!

主题

回复
  • 温馨提示: 标题不合格、重复发帖、发布广告贴,将会被删除帖子或禁止发言。 详情请参考: 社区发帖规则
  • 您当前输入了 0 个文字。还可以输入 8000 个文字。 已添加复制上传图片功能,该功能目前仅支持chrome和火狐

禁言/删除

X
请选择禁言时长:
是否清除头像:
禁言/删除备注:
昵 称:
 
温馨提示:昵称只能设置一次,设置后无法修改。
只支持中文、英文和数字。

举报

X
请选择举报类型:
请输入详细内容:

顶部