前言
暑假快要过完了,研电赛也终于结束了,值此新旧学期交替之际,打算把比赛了有将近小半年的研电赛的过程简单地总结一下,人说有总结才能有进步嘛。
依稀记得正式开始准备比赛的时间是2018年4月18日,那天下午,俩老板叫开会,说要报名参加研电赛,参加研电赛也一直是我们实验室的老传统,分两个队,有点喜剧的是,我们都想要跟着Y师兄,因为他的作品比较完整,也比较简单;而另外的作品呢,还没做完,还需进一步完善,而且我感觉巨复杂,后面也证实了我的直觉,但我没想到的是,Y师兄的作品,我也做的很痛苦= =,因为我们都瞧上了Y师兄,但人多了不行,Z老板就打算把我提出来跟着做那个难的,我可不干,死活不肯,最后就派给了小郭,还是要坚持一下,不然过程会很难受,在后来,看着他们一直讨论作品的解决方案,我就很庆幸自己的坚持有多机智。
回到技术正题,好歹这是一篇技术博客啊= =,虽然有点菜哈。
STemwin的学习
H老板给我们这组定下的任务是,技术上,用STemwin做个界面,用控件做界面,界面上要有动态曲线的绘制以及学校的开机图标,力求比现在师兄做的要美观;学习上,就要我们跟着Y师兄,把作品的原理、硬件PCB设计、软件设计这些搞懂,另外希望把作品里涉及到的遗传算法换一下,因为遗传算法太老了,看换成其他的算法。当时,连控件是啥都不知道,更别说STemwin了╮(╯▽╰)╭,就下来自己看了。
准备比赛期间,课比较多,而且要各种讲课什么的,就主要准备PPT了,4月份,也就在课余时间看看之前老板下的任务。
5月中的时候,大部分课都差不多讲完了,就开始做老板说的STemwin界面,去网上下了点这方面的资料,比较了下,安富莱的资料在这方面是最全的,包括论坛、STemwin工程文件、PDF、视频教程等很详细。
首先,要将STemwin移植到主控芯片F407VGT6、2.4寸TFT的屏幕上,因为当时师兄给的是作品很简易的第一版,而且教程是主控芯片是F429IGT6的,正好我之前学的就是F429IGT6,所以我就打算先在F429上试试,成功以后再换到F407上,因为是第一次“做开发”吧在这里拐了不少弯路,其实没必要在F429上试的,因为F429用的5寸屏,而且好像是叫什么RGB屏幕(忘了 = =),407用的好像是MCU屏,反正跟作品F407用的屏幕是两种屏幕,屏幕驱动都不一样,这里可耗了不少时间,当我在F429上移植成功后,再换到407上却费了不少时间,因为很不相同,如果一开始就直接移植到407上可能会移植的更快些。
简单回顾一些STemwin移植过程碰到的问题,参考的资料室是安富莱_STM32-V5开发板_STemWin教程(V1.0)第二章,以及相应的移植的工程文件。
1》给STemwin分配内存的问题。移植前首先要把2.4寸屏的驱动搞好,这个有中景园的资料,所以没什么大问题,只是有个读点函数readpoint()没有,不知道是怎么实现的,后来千辛万苦才在网上找到,先调试一下,能用,然后就用了,但读的颜 {MOD}的RGB值有点不对,找了很久就是没有找到原因,不过也没太大问题,我就把错误的颜 {MOD}读写备注在旁边,比如你要读出红 {MOD},你就给蓝 {MOD}的值,还是能用,就跳过这节了;还有就是给屏幕分配的动态显存那块也遇到过问题,我一直以为分配的内存大小是越大越好,但后来出问题编译的时候ram不够了,最后还是X师兄看出来,改小点,不然其他程序就没内存可用了,改完后就好了,就是下面的这一段代码:
#ifdef USB_EXTMEMHEAP
#define GUI_NUMBYTES (500 * 1024 ) // x KByte, (500 * 1024 )
#define GUI_EXTBUFADD 0x807D000 //0x807D000
#else
#define GUI_NUMBYTES (1024 * 50) // x KByte,1024 * 110
#endif
出问题之前分配的是110k,407用的好像是140几k的ram,我之前有算过的,打算把110分配给STemwin,应该是可行的,但其实不行,分配的太多了,而且2.4寸的屏幕,STemwin也用不了这么多,后面改成50k就好了,这里是夏师兄看出来的,我在这儿卡了4、5天,愣是不知道是哪儿出了问题,还想着外扩sram呢,╮(╯▽╰)╭。
(2018.08.31,暂时先写到这儿吧,后面再慢慢补上)
(接着写,之前的一个礼拜在忙着移植LwIP)
通过解决这个问题,使我对Stm32的内存管理有了一定的了解,另外还特意去查了下RAM、ROM、SRAM、FLASH等内存以及堆栈的知识。 简单说来就是,RAM是动态内存(掉电会丢失)、运行处理速度快,一般做cpu的运行读取内存,可分为SRAM、DRAM,SRAM运行速度最快也最贵,DRAM次之也较之便宜但比其他的都快;ROM是静态内存(掉电后可保存数据),读取速度较慢,一般做程序数据存储,典型的有PROM(可编程只读存储器)、EEPROM(可擦除存储器);FLASH,个人理解是性价比高的可擦除ROM;堆栈的话,堆是一块动态存储区,申请内存(malloc)、释放内存(free)的时候会涉及到;栈是用来存放局部变量的区域,程序执行完后会回收,另外在keil编译完成后,下方的RO-DATA等数据也与RAM、堆栈这块的知识有关。
关于RAM、ROM、FLASH的知识,参考网址:
https://blog.csdn.net/xiaofei0859/article/details/49662633。
2》也算是内存的问题吧。就等我照着安富莱的移植例程,把移植的全部工作都做完以后,弄了一段测试代码,却是黑屏的时候,我内心毫无波澜,因为已经有心里准备了,怎么可能一遍就成功,有位名人说过;“如果你真想把某件事做好,那你一定得做好再来第二次的准备。”,但是,在我回过头去检查的时候,一步一步的检查,都没做错啊,但就是黑屏,各种试都不行,我甚至还怀疑显示屏坏了,但是下个其他的不带emwin的程序就能显示,这里来来回回耗了4、5天,就是光查问题,最后真没办法了,只好请教X师兄,我们实验室公认的大佬,俩老板都承认的那种。但X师兄也没做过emwin这方面的,我只好一行一行的代码解释给他听,这行代码是起什么作用、那行代码是起什么作用,不亏是大佬级别的,很快就进入氛围,当检查到主程序下面这段代码的时候,师兄就说不要这行会怎样:WM_SetCreateFlags(WM_CF_MEMDEV);然后我们就把那行屏蔽了试下,结果就显示出来了!!!!!卧槽,终于能显示了,当时是真的高兴,搞了很久的东西终于有点头绪了。
........
WM_SetCreateFlags(WM_CF_MEMDEV);//建立缓冲区,防止闪变效应 (1)
GUI_Init(); (2)
后来,才在其他的资料上看到,提示有说,(1)一定要在(2)后面,也就是一定要在emwin初始化后才能建立缓冲区,这个由于当时没在意,只是我没想到竟然影响到不能显示了。这件事后,师兄的怀疑精神给了我很大的影响,不要有固定思维,敢于怀疑。
接下来,能显示了就好办了,我就把不带控件的数字、英文、线、图形、汉字、图片等通通都测试了一遍,除了在汉字显示那块遇到点问题,因为涉及到字库的制作,这和Stm的汉字的显示有点不太一样。其他的都没问题,只要是数字、英文、线、图形、汉字、图片的显示,我都能做出来。由于汉字显示这块,一开始做的确是有点难,下面我再稍微说一下,附上参考的资料,详细步骤我就不写了,隔的时间太久了,不太想再做一遍,= =。
参考资料:安富莱_STM32_V6开发板emwin教程(V2.0)22.2 使用FontCvt生成C文件格式小字库的方法
+ https://blog.csdn.net/efm32/article/details/8496835
两者的综合
注意一定要结合两者来看,因为我当时是照着安富莱的例程走,但没成功,后面在网上搜,就搜到了下面的那个网址的例程,两者结合一下就好了。
再粘贴一下当时X师兄劝我写下的步骤吧,找到了原先胡乱写的,仅供参考啊。(当时X师兄跟我说,“”你既然做出来了,而且是很复杂的东西,为什么不把步骤再简单写一下呢,要是下次再移植你忘了怎么办??” 我当时不以为然,觉得这有什么好写的,后来追悔莫及,╮(╯▽╰)╭,这样的心得要早写,我现在就不会这么痛苦了。。。)
————————————————步骤分割线——————————————————————
第一步:双击打开Font converter for emWin,在弹出来的窗口中,选择Standard, Encoding 选择16 Bit UNICODE。点击OK。
第二步:在字体窗口,选择合适的字体,这里选择常用的宋体。字形选择常规,大小一般选择16。最常用的汉字大小就是16*16像素的。
第三步: 点击Edit -> Disable all characters。 失能所有的字符.
第四步:因为要显示英文,因此点击Edit -> Enable range of characters, 在弹出来的窗口中,选择范围0 ~ 7F。(至此,英文字符文库弄好了)
第五步:开始创建自己要显示的文字字库,
创建了txt文档后,输入“自己要定义的字”
然后点击菜单选项文件->另存为:编码类型为UTF-8格式
文件名要注意不要有中文。
第六步:回到第三步,点击 Edit ->Read pattern file
选择刚才另存为的文档
第七步:另存为.c文件,注意文件名不要为中文,保存。
最后要注意:可能要将Maintask.c的文件转成即另存为UTF-8编码的格式。
总之,最后应该要生成两个.c文件,一个是由字库生成的UTF-8的一串数字,另外一个就是几千行的看不懂的代码。(上面步骤有错,暂未更改,)
正确的步骤更新如下:
①、新建TXT文件,输入要自定义的文本(还包括一些特殊的符号,如果要自定义的话),另存为Uncode类型。
②、打开Font converter for emWin,常规设置,然后Disable all characters, 失能所有的字符,然后Enable range of characters, 在弹出来的窗口中,选择范围0 ~ 7F。至此,英文字符文库大概弄好了,再挑选一些对应的特殊符号,然后点击 Edit ->Read pattern file,添加①中的TXT文件,最后另存为.c文件,文件名不要为中文,这里就生成了第一个需要的.c文件了,内容是几千行看不懂的代码。
③、将①中的TET文本再另存为UTF-8的格式,最好换成另外一个名字, 打开U2C.exe, 载入UTF-8格式的TXT文件,然后点击Convert,产生相应的.c文档,可以看到里面是类似这种:"xe6x8cxaaxe5xa8x81xe8x83xbdxe5xbexaexe5x85xacxe5x8fxb8xe4xb8x8axe6xb5xb7xe5x8ax9exe4xbax8bxe5xa4x84",这个.c文件不用加到工程中去,我们只要这个代表自定义文本的数组即可。
—————————————————————————————————————————————————:)
最后,就是涉及到控件这块了,就是用GUIBuilder先用控件做好一个界面,然后自动生成代码,然后在代码中进行修改,改成自己想要的,在这块的学习一直持续到最后,因为我们的任务就是要用控件做,这里也着实花了不少时间,原因很简单,因为没做过,我连GUI中最重要的回调函数是什么意思都不知道,更别说其他的了。
(先写到这儿,得回宿舍了╮(╯▽╰)╭,后面再把控件这块稍微写完,2018.09.08)
唉,好久没接着写了,也不知道在忙些什么,(# ̄~ ̄#),看寒假能不能补完吧,(´ο`*))) 2019.01.23
做好了前面部分的准备,现在才真开始接触界面了(不带操作系统)。不建议非要先通过模拟器在windows上模拟熟悉界面,最好应该直接上硬件,直接上板子或具体的硬件,边学边做。
但是!!可以参考伴随模拟器一起的源代码,很有用!
STemwin界面是用控件的形式实现的,就是提供你多种不同的小模块,你自己设计组成你想要的界面。比如按键、图形控件等。如下:
这部分的东西,详细看官方的STemwin使用手册,中英文版都有(建议通过看中文理解英文,因为别人翻译的不一定正确)。然后辅助以安富莱或正点原子的STemwin教程看,理解官方的使用手册如何具体使用。下面是5.12版的STemwin中文使用手册封面。安富莱或正点原子的STemwin教程均可到各自对应的论坛进行下载,均是开源,点赞!!
学习控件这块,我是笨方法学的,一个一个的学,因为都不知道对应的用途,好在内容不多,也学的快。
大方向是,我先在开发板上学习所有控件的用法,然后初步组成一个界面,并能正常运行后,再弄到师兄具体的硬件上跑,再保证其能正常运行,才算初步完成。说虽简单,但确做了很久,因为环境不同,有各种不同的问题,好在最后都一一大致解决了。
这篇总结真是拖太久了(拖延症患者伤不起,= =),具体细节实在记不清了,恕只能简单说下大概。
遇到的问题主要有三个。
第一个就是,Graph控件刷新闪屏的问题。因为我们用到了Graph控件,并需要它时刻刷新,时刻刷新是做出来了,但是会闪屏,闪屏就是跟以前的黑白电视机一样,你能明显看出一帧一帧的切换效果,这里我的确烦了一段时间,后来我一直在网上查为什么会闪屏后,"无意"得知,如果加上下面这行代码,就能不闪屏。
WM_SetCreateFlags(WM_CF_MEMDEV);//建立缓冲区,防止闪变效应
我立马加上,加上后果然没有闪屏,能正常显示了。如果前面有印象的话,我之前是因为黑屏,不能正常显示而把上面的这行代码屏蔽了,所以导致闪屏。一个小小的问题,不知道的竟能引发这么多问题。
第二个就是,实体按键的问题。因为师兄用的显示屏不是触屏的,所以只能通过外部实体按键来控制输入,这里比较麻烦一点,就是要理解官方“黑盒子”函数GUI_Delay,它不仅是用来延时的,它还负责界面的刷新,就是说,如果你在程序的顺序执行过程中,对界面进行了更改,你就得告知界面你做出了这些更改,予以显示。还要说是,GUI_Delay涉及到时钟了,要想做到精确时延,stm32就要使用systick,我用的也是systick,注意systick函数中的单位时间和GUI_Delay进行统一(就是最后输送至STemwin的时钟就是由GUI_Delay实现),最好不要跟网上的说法,另外写一个仿GUI_Delay函数,这样容易出错,我就是吃了这个亏,改了很久。
外部按键输入还是使用中断的方式,有例程可以参考。
最后一个,还是内存的问题。前面也说到一些内存的问题,按理说应该不会再出相关的问题了,但我比较笨 = =,界面刷新的动态内存在界面刷新30几次后,就会死机。后面查阅相关资料得知是,界面在每次刷新界面后没有释放内存导致,但在使用手册Graph控件这一章确丝毫没有提到,这个是我在论坛上查到的,然后再去随模拟器一起的源代码中、Graph控件的演示实验中才看到有释放内存的函数,Graph_clear函数(我记不太清了,函数名字大概是这个样子,去那个源代码中,一眼就能看到),所以我前面说,可以参考下源代码。
除了这个,还需要关注STemwin提供的内存使用函数,在内存那一章有提供内存使用函数,内存剩余函数,就是有函数会显示你使用了多少内存,剩余多少内存。
到此,大概我碰到的所有STemwin的东西就大致说完了,说的是乱七八糟,不知所云,也全是文字,让人看也不想看,反正我是写给自己看的,哈哈,= =。(虽然我是大致做出来了,但可能是因为屏幕太小(2.4寸)又不是触摸屏,所以效果不是太好,经我们统一商量后,决定还是不用这个了,直接用描点法吧,效果还比较好。虽然最后没用到,但也还是学到了很多东西,也不赖)
比赛过程
接下来再简单说下比赛过程。
研电赛初赛报名后,我们就进入“紧脏”的准备阶段,我负责STemwin这一块,另外一个负责算法说明部分,师弟就负责资料。都差不多弄好后,临近提交参赛作品一个月的时候,就开始拍摄演示测试视频、写参赛论文、做PPT。
拍摄视频,我们是去的达州,早上7点出发,下午1点才到,坐车路上难受的要死。。心想也就弄这一回,咬咬牙就过去了。我们之前也是大致想了下场景,现场练了下词,就几句介绍话(全是由我们组队长说,她口才较好),就开拍了,视频拍的还算顺利,也补拍了一些场景、图片,以防后面会用到,拍摄视频是找的几个新闻传媒学院的小学妹,也跟着我们受了不少罪。拍完后,就回学校了,晚上8点才回实验室,第二天穿上正装,补拍实验室的讲解视频和一些规定要用的图片(和指导老师、作品的合照等等)。还好不需要动太多脑筋,就是累的够呛。。
论文的话,我们仨是每人负责一部分,这里我还和队长闹了点小矛盾,她就挑简单的、少的自己写,然后难的给我和师弟写(老师说她比较会说话就让她当队长,就由她来安排),师弟也有怨言,只是我说话比较直就说出来了,还闹到老师那里,搞得不愉快,最后我看在老师的面子上,道个歉了事,想想这是第一次合作也是最后一次,忍忍算了。。
后面要做的事儿还得做,咱也不是个小气的人,该怎么弄就怎么认真弄,也不管啥气不气的了,反正是最后一次,以后话都不会跟她多说半句。
论文在老师的精心指导下,马马虎虎的算是混了过去。
PPT就是论文的缩影,自己做自己的,我的问题比较多,因为我负责的部分又难又多。。。 第一次讲解的时候,老师不知道我在说什么,但他们也没说怎么改,就说我没讲清楚要下来改,我又觉得很无辜,明明我已经讲得很清楚了,为什么就是没听懂呢。后来我才回过头,的确是没讲清楚,然后大改,加了很多分解图和方向箭头,才讲清楚。结果我这么一讲,讲的很清楚,相较之下,她说的不清楚,也要改,也要加方向箭头,哈哈哈!!最后我们的PP合在一起,也是各种改,改了不下8次。。
讲清楚以后,就得开始拍PPT讲解视频了,讲解稿子我们又改了很多次,因为时间有限制,我们又想讲清楚,只能反复讲,反复修改,提炼最少的词。PPT这块,麻烦的不是一点半点,改了实在是太多回了。。
然后跟着,新传院的小学妹也被折腾的不清,剪辑视频也跟着改了无数回,说有多折腾人这么说你们可不信,学妹到最后剪辑完以后,深信我是处女座(我真不是),并患有强迫症,,( ̄~ ̄#)
这里特别感谢任劳任怨的、跟我们一起熬夜的两个小学妹!!
最后几天,就是修改论文格式了,检查排版、字体大小、错别字,以及摘要部分,结果提交作品的日期又延后了一周,我们又改了一周。。。
终于,在提交作品的最后一天的半个小时前,我们把作品压缩打包提交,当看着上传进度条达到100%,我竟有点想哭。。然后收拾东西回宿舍,歇了一天,老师也没说什么。。
第二天,老板开了会,总结了下,忘了说的啥了,反正就是叫我们准备好接下来的电话论文答辩环节,因为如果你接到了电话就代表你有机会进入决赛,这个我们也不敢怠慢,想了很多可能会问到的问题,也一一作了比较好的回答,尽力就好。
到了预定的答辩那一天,我们把视频设备准备好,电话畅通,守在电脑旁。。心里说估计我们作品这么差,估计接电话的资格都没有。
上午没打来电话,想着我们估计是凉了,结果到了下午5点半(答辩的截止时间),也没打来电话,宣告彻底没戏,当然这是按照我们实验室历年来的经验看来,因为我们实验室每年都参加研电赛,每年都会接到电话。。结果到了我们这一届就没有,感觉我们好挫啊。。
结果在公布成绩的前几天,群里率先公布了出来,我们一看,我们竟然是重庆市一等奖,推荐进入决赛!!!哇,当时心里很开心,可惜的是,我们实验室另外一组种子队,却只拿了区区的重庆市三等奖(后来才发现他们论文出了很明显的低级错误,图片名字显示错误),当时就有点飘了,然后就被老师狠狠诛心了一通,说得意忘形。。其实我们心里也有底,作品没有很牛逼,估摸着也就是个重庆市二等奖,没想到老天爷给我们开了个大大的玩笑,把我们的暑假彻底玩进去了。。
于是乎,接下来,我们就得准备决赛了,痛苦的一匹,因为暑假要留到很晚很晚。。准备详情不想回忆,只有热,重庆夏天的炎热可想而知,有几天还38、39°C,虽有空调,路上可没有,出去吃一次饭,身上就湿一次。
终于熬到,去南京,老师不跟着,我们自己去。
我们提前了一天到,路上堵车差点就吐了,晚上8点才到酒店,酒店条件不错,包早晚自助,自助竟然有龙虾,大快朵颐的一番,回房间休息。(下面都是用的师弟拍的图片,不爱照相)
第二天,去南京工业大学,找好展台放好东西,布置展台,队长去进行答辩顺序抽签,抽到中间,不好不坏吧。
第三天,上午参加研电赛开幕式。
开幕式完后,下午就是紧张的现场答辩环节了,到我们组的时候,答辩老师提问,队长进行回答,我以为队长回答没对,就擅自打断了一下,结果越帮越忙,最后还是答辩老师自己弄懂了,说是昨天晚上认真看了我们的论文,啊哈。。晚上回酒店的时候,我很尴尬,因为我的莽撞,搞得我们现场答辩的不好。这里也提醒一下,千万不要打断队友说的话,实在要说,最好也是以补充的形式,不要打断,不要打断,不仅没礼貌,而且效果不好,会让答辩老师以为你们组内合作做的不好。
第四天就是PPT答辩了,这里我们初赛的时候,准备过,但到现场呢,队长说要进行稍微修改,我也觉得她说的有理,都进行了修改。我们上午9点就在那里等了,结果直到下午2点多才轮到我们,又紧张又难受,然后PPT讲解的时候,按部就班,最后一分钟的时候,我看时间快来不及的时候,就暗示说,直接播放现场演示视频吧,然后也顺利播放了,PPT讲解总算顺利完成,然后是老师提问了,队长回答,顺带把上午的遗留的问题也进行了补充回答,老师也听明白了,口才这点我比较佩服,PPT答辩的顺利结束也正式宣告着我们南京之行得以结束,后面都是些过程性的东西,不用再提心吊胆的了。
晚上出决赛成绩,我们都自认为是三等了,因为现场前后左右都是真的很牛逼的东西,什么FPGA、机器人、虚拟现实等,太多太多了,看的我眼花缭乱,我也是抱着开拓眼界,学习的心态来的,可没想到,竟然有惊喜,我们竟然是二等奖!!不过再往后几名,我们组就成了三等了,哈哈哈,但也是二等了,当天晚上我们都开心坏了!!赶紧给老师、师兄、同事发信息报喜,哈哈,真的很开心。
第五天上午,我们还要去展台,如果还有感兴趣的老师同学,需要进行讲解,可是没有。。我就到处乱逛,问一些自己感兴趣的,到处看看其他高校的真精英们。下午就去南京的夫子庙逛了下,买了些几块雨花石纪念品送给实验室的同学。
第六天,打道回校了。截止到8月22日,研电赛历时半年之久,终于落下帷幕。
2019年2月7日正月初三于乡下老家