|
本帖最后由 慕名而来 于 2022-1-15 11:38 编辑
一、说在前面的话:本帖只是一个编程不入门的玩者开源的一个函数,感兴趣或玩到这些的朋友可以楼几眼,高手就当闲篇看看就好。
二、起源与心路历程:
手里有几个12864绿色屏幕,继此前做了一个锂电池供电的闹表后就一直没用到(这里有以前的发帖:电路好做壳难弄,找块木头做闹表https://www.mydigit.cn/thread-239786-1-1.html(出处: 数码之家)) 这个屏的电路板挺不规则的,上个月借力创0元打样就画了板子从新做了LCD模块,看着坛友发的墨水屏小月历显示觉得有趣就开始琢磨用这个屏来显示月历,原本以为这都是玩烂的代码,结果百度好久只找到几个由调试软件打印输出的简单例程,都无法用到LCD的显示中来,于是决定自己写代码,先用38条显示语句实现了这个月历的排版显示,依此确定了每个数据的字符大小与显示位置,接下来就是编写函数通过循环和算法来实现输出显示了,因为编程没有真正入门并且很少编程了加之上了几岁年纪编程越来越费力了,总要经过从“精力不集中、不知所措”到“想出方案、渐入佳境”再到“豁然开朗、顺理成章”这三个过程才能实现一个想法,这次写的代码也不例外,想了好久、改了好久才实现了功能,贴在这里留底同时也供新手用到时参考。三、分享代码:
如果要实现月历显示需要知道当月的天数,于是借用了一个计算闰年判断天数的函数,另外需要知道当月的1号是星期几,于是借用了一个计算某年、月、日是星期几的函数,全部函数如下:
- //====计算当前月份的天数并返回数据======================================
- unsigned int Month_Days(unsigned int y,unsigned int m)
- {
- unsigned char r;//设一个标志
- y+=2000;//2000-2099
- if((y%400==0)||(y%4==0&&y%100!=0))//首先判断是否闰年
- {
- r=1;
- }
- else
- {
- r=0;
- }
- if(m==2)
- {
- if(r==1) return 29;
- else return 28;
- }
- else if(m==4||m==6||m==9||m==11)
- {
- return 30;
- }
- else
- {
- return 31;
- }
- }
- //====计算日期值对应的星期值并返回数据=======================
- //应用基姆拉尔森计算公式换算
- //wk=(d + 2*m + 3*(m + 1)/5 + y + y/4 - y/100 + y/400 + 1) % 7;
- //wk的取值范围是0~6,0代表星期日,1~6星期一到星期六。
- //公式的输入格式示例:21年1月1日
- unsigned char set_week(unsigned int ye,unsigned int mo,unsigned int da)
- {
- unsigned char wek=0;
- ye+=2000; //2000-2099
- if(mo==1||mo==2) //月份为1、2月时、month=13、14并且年值-1
- {
- mo+=12;
- ye--;
- }
- wek=(da+2*mo+3*(mo+1)/5+ye+ye/4-ye/100+ye/400+1)%7;
- return wek;
- }
- //====月历排版显示函数======================
- //显示星期的汉字采样12*12字模
- //显示日期的数字采用6*8字模
- //每个位置显示两个数字、单个数字时靠右侧显示
- void Calendar_display(unsigned int yy,unsigned int mm)
- {
- unsigned char x=3,n,w,da,dd=1;//设一些计算变量
- unsigned char xn[7]= {6,24,42,60,78,96,114}; //每行7个位置的列参数
- unsigned char* wn[7]= {"日","一","二","三","四","五","六" };//对应数字的汉字符
- da=Month_Days(yy,mm);//计算本月有多少天
- w=set_week(yy,mm,1);//计算本月1日是星期几
- //顺序显示星期文字、占用第0、1两行位置
- for(x=0; x<7; x++)
- {
- PutGB16(0,xn[x],wn[x]);
- }
- //对应星期排列第一行日期、占用第2行位置
- for(n=w; n<7; n++)
- {
- PutGB6_8(2,(xn[n]+6),dd);
- dd++;
- }
- //对应星期排列其他各行日期、占用第3、4、5、6、7行位置
- for(x=3; x<8; x++)
- {
- for(n=0; n<7; n++)
- {
- if(dd<10)
- {
- PutGB6_8(x,(xn[n]+6),dd);
- }
- else
- {
- PutGB6_8(x,xn[n],dd/10);
- PutGB6_8(x,(xn[n]+6),dd%10);
- }
- dd++;
- if(dd>da)
- {
- x=8;
- break;
- }
- }
- }
- }
复制代码
四、代码使用说明:
1、代码中的数组unsigned char xn[7]= {6,24,42,60,78,96,114};是12864屏确定的一行显示7个字符的起始点的x值,移植代码是需要根据自己的屏幕来修改。
2、代码中的显示输出函数(例如:PutGB16(0,xn[x],wn[x]);)底层LCD驱动函数,需要根据屏幕编写,本例中的带入参数依次为行位置数据、列位置数、待显示的数据。
3、我用的LCD12864是隔壁老王的VTM88870B屏,驱动为ST7565
五、说在最后的话:我总是觉得这个函数还能进一步优化,但我目前没能力了,如果有高手能够具体指点或帮忙优化将万分感谢。
六、显示效果如下:
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
打赏
-
查看全部打赏
|