单片机实例分享,能“变频”显示的电子钟台灯
(此处已添加圈子卡片,请到今日头条客户端查看)电子钟的功能
我们先来看看这个时钟都有什么能耐。
◆ 24像素×7像素LED点阵显示[单色]
◆日期、时间、星期[年、月、日、星期显示]
◆温度[0 ~60℃]
◆闹铃[20组,可独立设置开关]
◆ LED台灯[99级亮度调整,自动亮度记忆]
◆走时补偿,自动较准[按天较正,范围±25s]
◆整点报时[可设定开或关]
◆整机声音开关设定
◆整屏信息切换显示
◆ 4按键操控,也可无线操控
◆后备可充电电池,断电依然走时
◆ 6 ~9V电源供电
它也就这么多能耐了,怎么样,是不是感觉比台灯功能要全面多了?目的只有一个,继续向人性化迈进。你可能会问,这个是不是很复杂啊,我能完成吗?不用担心,再复杂的东西也都是由一个个简单的东西组成的,只要各个击破就可以完成一个复杂的制作。但是你会不会看着这些功能很面熟?不错,这个时钟功能上跟杜洋老师制作的3208大体相似,但还是有些不同的。为了提起大家的兴趣,我特意在这里单独来讲这个时钟的独特之处,不然怎么吸引你继续往下阅读呢,当然也不会浪费你的时间。
个性的才是品牌的
前面已经提到,这款时钟是使用方形点阵屏,因为圆形点阵屏构成的笔划看起来连贯性不够好,点跟点之间是相切的,而方形点阵屏就不一样了,连贯性很好,很美观。只有美观我可不满意,讨个老婆只漂亮可不行,最好是又漂亮又贤惠,于是我就给它整合了LED台灯功能,让它更有魅力。可人心不足蛇吞象,你讨到了漂亮贤惠的老婆后可能还是会花心,身在福中不知福,这可真是一个头疼的问题。还好,有我在,想花心?嘿嘿,我再升级,教它用更聪明的办法处理事情,扫描显示屏的时候不会一列接一列地扫描,不管是否有数据显示,也不管显示多少数据。它只会在需要显示的地方显示,不需要就直接跳过不去扫描了。而且这种方法对由于营养不良(驱动功率不足)引起的面部雀斑(各点亮度不均匀)有很好的疗效,这个具体会在后面详细讲解。最后我还给它加上杀手锏,在它的背后左右分别装上一个蓝色的LED灯,工作时渐明渐暗好像会呼吸一样。这下你该死心踏地了吧?
硬件装备5大件
口水溅干,终于把全部功能特点讲述完毕,喝口水。接下来到了我们了解硬件装备的时候!我们按其功能先后来看,首先就是点阵屏,选用6×7的点阵模块,共4块拼成24×7分辨率的点阵屏。你也可以用其他方法组成24×7的屏,只要达到目的就可以。选择点阵屏要注意尽量挑选亮度高、电流小的,亮度低了效果不好,谁又能忍受整天对着一个灰蒙蒙的脸呢?选好屏之后,接下来就要考虑屏的驱动方式,为了节省口袋中的零花钱,我们采用动态扫描的方式,这样不仅可以在硬件装备上节省我们不少的投资,电路结构上也会变得更简单。可能你对“动态扫描”不太了解,有一头的问号,没关系,带着问号耐心往下看吧,后面我会为你详细道来。
由于单片机的I/O口资源是比较宝贵的,虽然动态扫描可以节省不少I/O口,但还远远不够,所以我们还要加上串入并出的芯片来进行扩展I/O口,常用的芯片型号有74HC164和74HC595,我选择74HC164进行列驱动。但测试后发现它的电流不够,显示亮度偏低,为了节省三极管,简化电路结构,最后选用74ACT164,它的电流足够大,而且经过我的特殊扫描处理后,亮度问题迎刃而解。这样,经过74ACT164一扩展,我们就可以只用2个I/O口对24列数据进行列扫描。
接着是日期、时间、星期功能,我们有两种方法可以解决:一是用单片机进行这部分数据的运算处理;二是用专用芯片进行协助处理,相当于单片机把这部分工作外包,在需要的时候直接拿结果,而不用自己操心去处理。前者虽然可以让电路简单,但是却会额外增加单片机的程序,最大的缺点是走时不准确,也不容易做到断电依然走时;用专用芯片就不一样了,作为一个独立的部件,走时准确,不受其他部分干扰。综合这些优缺点,我们选用DS1302专用芯片来处理,走时准确、断电依然走时的功能是很重要的。
同样,温度测量的实现办法也有好多种,比如可以用热敏电阻、二极管或三极管、专用芯片等,都可以用来检测温度。热敏电阻、二极管或三极管虽然可以检测温度,但需要配合电路,进行模数转换,再经单片机运算处理才可得到温度值。而专用芯片DS18B20就省去了很多麻烦,传感器、模数转换、运算处理等都集于一体,而且精度、准确度都很高,单片机在需要的时候直接去读结果就行。
至于闹铃功能就好办了,我们可以选择一款记忆力好的单片机,自带EEPROM,把闹铃设定数据都存在里面,掉电也不用怕丢失数据。或者如果选择的单片机不带EEPROM,DS1302内部还集成了31个RAM,也可以用来存储闹铃数据,只要DS1302不掉电就不会丢失数据。我们再来看看台灯功能,独立的台灯在台灯制作中已经介绍得很详细,现在只是将它跟时钟结合在一起就可以了,但是为了大功率LED的寿命,我们这次给它的驱动电路进行一下升级,搭个简单的恒流电路来更好地控制LED的工作电流,使其电流更稳定。
最后,核心出场,你是否已经猜到是什么?当然是统管整个电路的经理人——单片机是也,关于单片机的选择,各有所好,所谓萝卜白菜,各有所爱。只要符合要求,你自己喜欢都可以。这里我选用的是性价比很高的Atmel公司的ATmega8L,内置了很多常用的硬件资源,比如上面提到的EEPROM,真是价格便宜量又足!而且它还可以很方便地在电路上用下载线下载编译好的程序,而不用将芯片拔下来放到编程器上下载程序,下载完后再插到电路上那么麻烦,这对调试程序是非常方便的。
OK,几个大件我们都已确定,现在可以将电路设计出来,完整的电路原理图如图28.1所示。
硬件电路原理
图28.1是整个电路的设计图,左上角的model就是把4块6×7的方形点阵块的7条行线并接在一起组成的显示模块,共24列,由3片74ACT164进行列驱动。HA1是无源蜂鸣器,用于整机的声音提示。VT2、VT3、R11、R12组成LED台灯的恒流电路。这个恒流电路其实很简单,它们是一环套一环的,我们一步一步来推导。
图28.1 电路原理图
首先,LED是直接由VT2来控制的,而VT2的基极又受制于VT3,如果VT3导通则VT2截止,VT2的集电极和发射极之间没有电流通过,这样LED就不能点亮,反之则可以点亮。我们再向后推一步,VT3是受R12控制的,VT3的基极电压即为R12两端电压,该电压大于0.7V时,VT3就导通,反之则截止。R12两端的电压和通过R12的电流成正比,而通过R12的电流即通过VT2发射极的电流。聪明的你是否发现,绕来绕去最后又回到了VT2?不错,整个电路组成了一个反馈回路,互相牵制着。是不是拐来拐去看得有点眼花了?呵呵,不要急,慢慢看,分析电路这可是电子爱好者的基本功,相信你一定可以分析清楚。我们发现,当VT2发射极电流变大,R12两端电压就增加,到超过0.7V,VT3就导通,VT2截止,VT2的发射极电流想大也大不了;反之,如果VT2发射极电流变小,R12两端电压也减小,小于0.7V,VT3就截止,VT2就导通,VT2的发射极电流想变小也不行,所以VT2的发射极电流会稳定在某个值。你是不是已经想到了,对,由于VT3的导通、截止的基极电压界限是0.7V,所以R12两端电压会稳定在0.7V。根据LED的功率先计算它的正常工作电流大小,这也就是要控制的VT2发射极电流,VT2的发射极电流控制到多少又要看R12的取值,根据公式I=0.7V/R12就可以得到R12的值了。提醒一下,计算好R12的值还不要忘记计算R12的功率哦。关于LED的相关计算,大家可以去查阅,这里不再重复。左下角的IC6与周围元件组成+5V稳压电路,给整机供电。由于LED台灯有了恒流电路的控制,不用担心工作电压不稳定,所以LED台灯的电源没有经过稳压,直接用接入电压驱动,这样也可以让接入电压的范围增大。右上角为DS1302、DS18B20与单片机直接相连,接口电路很简单。P3为下载线接口,P6为预留的无线模块接口。轻触按键S1~S4为了兼容无线模块的电平,还是以下拉的方式接入。差点忘了,VD1、VD2就是杀手锏,蓝色的“呼吸”灯,夜间看起来很炫,由一个I/O口控制,其实它们的“呼吸”效果也是用PWM来实现的。扯了这么多终于算是把硬件大致讲完了,不知你是否已经明白,面对这么一大片文字我肯定会头晕的,不清楚没关系,多看几遍就好了,一回生,二回熟。
硬件电路制作
我们看看元器件清单,如表28.1所示。
这个时钟电路看起来比台灯电路复杂多了,不知你是否已经学会用电脑设计PCB板,如果已经学会,你大可以利用这次制作的机会练练手,温习一下。否则,还像LED台灯那样,用万用板来焊接仿制,可能得耐心花上几天功夫。如果有兴趣愿意这样做,那倒是好事,就怕你花了几天苦功夫焊好的板子,到时候会出现各种意外的错误,头都大了。更有甚者,把板子往角落里一扔,不玩了,那我就汗颜啦。所以,如果决定用万用板来仿制,就要做好心理准备,而且要耐心、细心。动手之前按照表28.1所示清单准备好材料。好了,接下来就是你动手的时候!祝你一次成功。
表28.1 采购清单
点阵LED屏扫描原理
漫长的几天等待,你的硬件是否已经准备好了?OK,很有效率。如图28.2所示,看看我焊的,我就没这么有耐心,画了块PCB板做出来的。硬件准备好了我们是不是要进入软件部分?你真聪明。不过在写软件之前我们得弄清楚扫描显示的原理及处理方法,不然写软件就会无从下手。重点来了,到底什么是扫描显示呢?说到底就是利用了人的视觉暂留效应实现的,即在光线消失的一定时间内,人的眼睛会感觉光线还存在着,这个时间一般为1/24s或者更久。或者你可以这么想,人的眼睛反应很迟钝,它会把1/24s时间内看到的景象当作一幅景象来处理。举个简单的例子,晚上你拿着手电筒照着墙上,会看到是一个光斑,但是如果你快速左右挥动的话,你就会看到照在墙上的光变成一条条的线,其实这就是一种方式的扫描。虽然在任意一刻,手电筒照在墙上的光都是一个光斑,但呈现在眼前的却是线。文字写多了我都烦,所谓百“文”不如一见,我想,用以下的图来对显示屏的原理进行解说,应该会更容易理解,我们来边看图边认识吧。
图28.2 制作好的硬件
图28.3 点阵模块结构
首先,我们来了解一下点阵屏的内部结构,本文所用到的6×7的点阵模块结构如图28.3所示,就是由一个个的发光二极管组合而成,将这些发光二极管按行列的方式焊接在一起,大家注意仔细看它的焊接方式,焊接完后,最后再封装成一个模块。了解了内部的结构后,如果你很感兴趣又不怕麻烦,我们也可以用LED自己动手制作显示模块,这样灵活性更大。现在我们要让这个显示模块显示如图28.3所示的“H”字符,由于模块内部已经将发光二极管按行列方式焊接在一起,我们要一下子显示“H”字符是不行的。那用什么方法才能让它显示呢?也许聪明的你会立马想到,那我们能不能分步骤来显示出来呢?答案是肯定的。如果你还能根据前面我所讲的一堆文字想到分步骤显示的方法,那你为什么不跳过这段直接去读下段呢?不要紧张,其实分步骤显示原理很简单,即刚才讲的扫描显示,利用人眼的视觉暂留效应,在比较短的时间内每次显示一部分内容,最后由于眼睛的迟钝反应,感觉这些内容就是一次显示出来的。还有疑问?带着疑问继续看图吧。
如图28.4所示,箭头代表电流的流向,灰色的方块代表亮起的点。总共6帧图,即显示“H”字符的整个过程图解。“H”字符共5列数据,加上字符后的空格共6列数据,我们就把它分成6个步骤来显示,从左至右一列一列地显示,每次只亮起一列数据,每幅图表示每一次显示的状态。请注意,它每次只显示一列数据。前面已经讲过,我们人眼的视觉暂留效应时间一般是1/24s或者更久,如果是只显示这个“H”字符,那只要保证6列数据都显示完一次的总时间在1/24s内,我们就会感觉这6次显示的画面是一次显示出来的画面。但这个时钟的屏是24列显示的,同样的道理,只要保证在1/24s内显示完这24列数据就可以让我们感觉是一次显示出了整个画面,我们把显示完一次这24列数据叫做“刷新一次”。换个说法,就是一秒钟内能将整屏数据刷新24遍以上。就像电视的显示一样,1s钟刷新24遍以上,我们才不会感觉画面有闪烁。是不是有点头昏脑胀呢?不用急,闭上眼睛仔细体会一下整个扫描过程,但千万不要睡着,我们还要接着往下思考呢。
图28.4 点阵LED扫描过程
程序流程
我已经绞尽脑汁用各种通俗的方法来描述这个时钟的显示和工作原理,能不能理解得看你的造化,希望到此时你已经理解。整理整理思路,我们进入下个步骤。还是那句话,保持良好的习惯,在准备动手写程序之前不要忘记流程图,根据对显示原理的了解,我们先用流程图的方式把这一过程表达出来,写程序时就会轻松得多。流程图如图28.5所示。
图28.5只是一个抽象的流程图,具体到每块功能处理又会有很多流程。框架搭好后,再向里面添砖就比较容易,具体每块功能的流程就交给你自己去解决。在写程序之前你最好能将所有流程都整理出来,待思路清晰后再动手。否则,你可能会陷入程序的迷宫中辨不清方向,迷迷糊糊,人世间还有什么事情比这更痛苦呢?
在程序中,按键的处理是最为复杂的,你得很花一些功夫在里面,主要在按键操作之后菜单的进出和显示的配合部分,处理不好很可能会出现画面定格,整机无反应的现象,像是死机了,其实是已经进入了某个死循环。
闹铃的判断方法是在每次分钟值更新后将各组闹铃设定的分钟值与之比较,如有相同,则继续与相同的这路闹铃的小时值比较,如又有相同,则进行响闹一分钟,反之则不响闹。整点报时的实现方法比较容易一些,只需要判断小时的数据是否更新,如有更新则进行整点报时即可。
好了,现在行动起来,按照流程图与之前的分析理解,开始动手写程序吧!我写的源程序可以在本书配套光盘上找到。
图28.5 流程图
调试秘籍
制作这个时钟你是否会感觉我进行得一切顺利?如果是的话,那肯定是你的错觉。每个制作过程中都多少会出现各种问题,这些并不可怕,重要的是遇到这些问题,我们动力十足,有一颗持之以恒的心去解决它,不知你是否拥有这种耐性呢?在这个时钟制作中,我遇到过一些问题,其中记忆比较深刻的有几个,在这里跟大家分享一下,希望能对你有所帮助。
和你一样,当制作好硬件时,我便兴冲冲地拿着它连接好电脑,开始写屏幕测试程序,可问题接踵而至,马上打击了我的兴致。最不想出现的问题居然出现——屏幕显示有问题。只能显示前8列数据,后面的都不能显示。这是硬件问题还是软件问题呢?谁才是真正的幕后黑手?为了揭密事情的真相,我修改屏幕测试程序为单一竖条流动循环显示,发现8列以后的数据虽然不能显示,但竖条的流动时间还是花了那么多,并不是8列流动完就再从第一列开始,这说明软件应该没有问题。排除了软件,那会不会是硬件问题呢?“8”在数字电路中是一个很特殊的数字,资料总会有“8”或者它的倍数。
74ACT164是一个串入并出的芯片,输出并行的8位数据,那会不会是第一块芯片的数据没有传送到下一块芯片呢?带着这个疑问我将74ACT164都加焊了一遍,再测试还是不行,我又用示波器测试了第2块74ACT164的串行输入脚,终于有重大发现,输入脚当接收到“0”数据时低电平不到位,只是稍微凹了一下,导致“0”数据不能正常传送。接着顺藤摸瓜,幕后黑手终于浮出水面,原来是因为74ACT164在回路中的内阻有点大,导致该列LED的电流流通时这个内阻分到了一半以上的电压,强行地将低电平拉高而引起不正常。能想到的硬件解决办法是增加限流电阻值以减少74ACT164的分压值,可这样做显示亮度会大大减低,显示效果不理想。
硬件方面没辙了,那能不能从软件方面着手解决这个问题呢?当然可以,不然我还如何继续写完这篇文章,如何向大家交待?不知你是否已经想到解决的方法,不妨先听我说。其实做法很简单,既然是因为LED的电流引起电平不正常,那就从根本治理,在每次74ACT164的数据移位前先关闭LED的显示,移位之后重新开启,从关闭到重新开启LED显示这段时间极短,对显示的影响是微不足道的。
话虽如此,可由于LED显示屏材料和74ACT164的驱动电流问题,显示屏的亮度还是让我不能接受,而且由于驱动电流不足,导致显示亮度随每列亮起的点数不同而不同。这个问题困扰了我好一段时间,电路已经确定,想更换材料来解决问题不太现实,思路还是锁定在软件上。万能的软件,遇到问题总可以靠它来解决,这种可以节省出午餐费用的方法也总能得到我的青睐,这一次又是软件解决了问题。这是某天中午我对着它发呆时突然想到的方法,传统的扫描方法是,逐列地扫描显示,每扫描一列给予固定的显示时间,不管该列是否有点亮起,亮起的点数有多少。
这样的显示刷新频率是固定的,而且很浪费资源,当某列没有点亮起的时候,为什么还要浪费这个固定的显示时间呢,在这一刻整个屏幕是处于无显示状态的。那我为何不直接跳过?节省这些时间就提高了显示的刷新频率,也间接地提高了显示亮度,真可谓是两全齐美。虽然是两全齐美,可这怎么就能够满足贪心的我,还要继续琢磨。这一琢磨又发现,每列用固定的显示时间并不科学。每列亮起的点数不同亮度也不同,因为每列共7个点,这样就有7种不同的显示亮度,亮起的点数越多亮度越低,那我为何不在亮起点数少的时候减少显示时间,亮起点数多的时候增加其显示时间呢,对应7种显示亮度给出7种显示时间。
这样一折腾,又来了个两全齐美。亮度继续提升而且均匀,刷新频率又有所增加,完全响应口号“不闪的才是健康”。不知是否有朋友想到这样的方法,但我真的很佩服自己能想到这个方法,我称这个方法为“时间扫描法”。把刷新一次的时间看作一个整体,分成24×7份,传统的扫描方法需要24×7份时间,而经过我优化后的方法需要的时间理论上接近亮起的点数,屏幕上有多少个点亮起就需要多少份时间,当只有一个点显示时就只需要一份时间,刷新频率远比传统的显示方法高,是一个动态的刷新频率,套用流行的新名词叫做“变频”显示。一不留神,扯远了,体验了一回王婆卖瓜的感受。
可别高兴得太早,显示的问题是解决了,可摆在床头使用一段时间后发现走时总是会有误差,隔三岔五的要调整一次时间,这可不是什么愉快的事儿。细心的你可能已经发现,图28.5所示的程序图里有个时间校正功能,到现在压根儿还没讲是咋实现的呢。到这里终于暴露出来,我还是老老实实地招了吧。时钟难免会出现走时不准的现象,对硬件上的处理调校比较麻烦,从软件上下功夫进行走时的调校是一个不错的方法,灵活性大且容易调整。实现原理比较简单,在菜单中先设定为不校正,以较准确的钟表或电视时间为标准,让时钟走时一天,观察其秒钟值的误差是多少。
如果有误差则在系统菜单中设定相对应的校正值。在程序编写时设置一个固定的时间每天进行校正一次,比如晚上一点钟。到了晚上一点钟,它就会按照设定的校正值进行加或减的校正,校正的时候会看到秒值突然变化。写程序时你可千万别一定等到晚上一点钟去验证这个一天才有一次的景观,可以调整时间接近一点钟,也可以在程序中将校正时间改变。随时都可以进行验证。所谓“师父领进门,修行在个人”,方法教给了你,具体的运用还得靠自己。
发挥创意锦上添花
不知上述经历对你是否有帮助,你的时钟已经工作了吗?程序是否已经调试完毕?如果还在调试中,不要着急,继续加油!如果已经成功制作,那么恭喜你!苦心人,终不负,你可以端着咖啡坐在椅子上静静地欣赏着它。
但是你觉得它很完美了吗?如果到这里就已经很满足,表示你还没有让脑子动起来,充分发挥你的想象力,让它更具有个性色彩吧!我的电子钟虽然早已摆上床头,孜孜不倦地工作数日,像大多数花心的人一样,时间久了,总会有点不满意。对于这个时钟,我已经有了许多新的改进想法,但现在还没有去实现。做完这个时钟后,发现原来很多朋友都喜欢大的点阵屏,实在是对我的爱好汗颜,但是大的方形点阵屏很少见,如果找不到,自己用方形LED制作一个这样的屏也未尝不可,玩在其中,乐在其中。倘若你是一个贪睡的人,你还可以给这个时钟加上贪睡功能。倘若你是一个重视视觉感受的人,你可以试着增加显示的方式,比如上下翻屏、流动显示等。倘若你是一个喜欢人性化的人,你不妨在闹铃功能里加上台灯控制功能,给予3种控制状态:开灯、关灯、保持,用两组闹铃就可设置一个开关灯循环,你更可以在每组闹铃里增加亮度值设置。
想想,每天晚上6点天快黑下来的时候,它自动渐渐亮起,到晚上10点你快休息的时候它又自动将亮度渐渐减低作夜灯照明,清晨7点,你睁开惺忪的眼睛看到第一缕阳光的时候,它又会自动渐渐灭掉。想到这些是多么惬意,它就像一个任劳任怨的仆人永远为你服务,而你却不用担心薪水支付问题。原来闹铃不只是可以做闹铃功能,那你有没有想过显示屏也可以当做台灯来照明呢?用超高亮的白光LED自制点阵屏,当需要点亮台灯的时候就全屏点亮,这样不失为一种精简电路而节约出早餐费用的好方法。
这些想法都只是围绕生活的,其他方面有没有呢?贪心的我总是异想天开地想让它拥有尽可能多的功能而变成超强的电子制作,电子爱好者们做一些实验的时候经常会用到显示屏来进行调试,这么好的一个点阵屏不用简直是浪费,可以给它增加一个通用显示屏功能,当切换到该功能时,屏幕作为一个通用的显示屏来使用,主控芯片内置数字、字母及符号字库,通过串口通信。也可进一步用些方法进行拼屏显示,每个屏手动设置一个编号作为自己的地址,而且可以直接用上位机发送数据进行显示,这样它摇身一变又成为一个串口调试显示屏了。如果继续拿它做文章,你还可以将它变成能够自己下载显示内容的广告牌。恐怕我再写下去有人要扔月光宝盒了,当年《大话西游》的唐僧又在脑海浮现,所以赶紧停下唾沫横飞的入镜状态。
当然,这些想法可能因为一些原因而不能同时实现,萝卜白菜,各有所爱,如果你对这些想法感兴趣,不妨一试,希望你能做得比我更好,到时不要忘记和我分享喜悦哦!
(此处已添加圈子卡片,请到今日头条客户端查看)嵌入式软件面试那点事
导读:本篇笔记将总结关于嵌入式软件面试的一些东西,东西太多,不会全部展开,仅做个人总结之用,各位道友也可参考参考。首先说个大概的,嵌入式软件需要掌握什么东西?
1) 对单片机的熟悉程度(包括中断系统、各种外设模块、时钟系统等)
2) 对通信协议的熟悉程度(常见的有SPI、UART、I2C等)
3) 掌握基本的数据结构(如队列、栈、链表)
4) 掌握基本的算法(多种排序算法,数据结构中需要的一些算法)
其实嵌入式的东西很庞杂,不是一下子就能说清的,只能想到哪写到哪了。
对单片机的熟悉程度,这个就要考你的基本功了,比如单片机运行到main函数之前做了什么(首先是从启动文件的复位中断进入,然后初始化时钟,进入main函数之前还得初始化一些全局变量)?单片机的中断机制是怎样的(这个和向量表有很大关系)?固件升级原理(一份BootLoader程序,一份APP,这个其实不难,鱼鹰有专门的笔记讲述,如果你的简历没有写这个的话可能不会问这个,
STM32固件升级之基础知识(一)
)?是否使用过DMA,原理是什么(DMA传输方式,怎么设置,
数据传输还用 CPU?不如交给 DMA 吧!
)?
通信协议的话,主要不是上层的通信协议,而是物理层面的通信协议,比如串口通信需要掌握一帧格式(起始位、数据域、奇偶校验位、停止位等);SPI通信的四种模式,你又是如何确定使用哪种模式的?I2C通信格式(起始信号、结束信号、应答信号等)?如果说你学过USB,可能会问你USB采用什么编码、有几种端点模式、简单介绍枚举过程(但也别太简单)?更高级的可能问你关于网络这块的知识(具体鱼鹰也不知道,因为还没系统学过,这里推荐《TCP/IP详解》)
数据结构,比如最常接触的栈、队列、链表(单向、多向链表)的原理,而数据结构肯定会涉及到一些算法操作,比如出栈、入栈;出队、入队;插入、删除等操作,而比较纯粹的算法是排序算法,其中有冒泡算法、快速排序算法等(这里推荐《大话数据结构》),注意这些知识常以笔试形式出现,所以一定要能写出来(关于笔试推荐《剑指Offer》)。
鱼鹰最弱的应该是笔试了,或者说算法。在嵌入式软件开发过程中,用到的算法其实并不多,但是要你自己用笔写出来还是有很大的难度的,鱼鹰这方面的能力确实欠缺,因为我一般喜欢深入理解思考后就把细节记录下来,然后选择遗忘的(遗忘不是说全部不记得了,而是说只记得大概,细节记不住而已),所以说面试前不来个系统的刷题,临时抱佛脚一下,基本笔试是没戏的。
但是笔试成绩我觉得只是一个方面,一般来说笔试之后会有面试(社招一般笔试、面试紧邻的,校招的话如果你的笔试成绩不合格,那么连面试资格都没有),所以如果笔试成绩不理想的话,一定要好好准备面试(这里插一句,面试前,一定一定要上网查找公司的背景信息,起码要知道公司是做什么产品的,鱼鹰就在这里吃了一个亏,之前对这个不重视,有的公司查过,有的公司没查过,刚好没查过的公司突然就问到这个问题,很尴尬,因为这体现了你对这次面试的尊重,而不是在浪费面试官的时间)。面试的话,就随你发挥了,只要你对自己的技术有信心,那么面试应该不会太难,一般来说,面试官问的都是简历上的东西,所以简历的内容不要造假,否则回答不出来就麻烦了。
现在就来具体聊聊几个一般人不知道的知识:
01、你是怎么接收、发送串口数据的?
这个问题其实比较宽泛,一般经验少的会说使用查询方式,但是查询方式效率是非常低下的,所以如果你只能回答这个,100分的题你只能得个30分。如果你说用中断方式,那么请问你具体是如何处理的?如果你回答说一个字节接收完之后再接收下一个字节,那么可以得个50分。
紧接着又问你,你是怎么接收一帧数据的(这个其实不应该由面试官问,而是由你自己补充全面),如果你说采用帧头、帧尾判断的方式接收的,那么这道题还是给你50分,但是你说用空闲中断,那么70分以上,如果你说用DMA+空闲中断的方式接收的,那么90分以上(这是我认为最好的方式了,可能会有其他更好的方式也说不定)。
那么现在说说空闲中断,为什么你说了空闲中断之后,一下子从不及格到及格了?
空闲中断,顾名思义,就是串口空闲后产生的中断。我们都知道,数据一般是按照数据帧来发送的,即一个数据帧一个数据帧的发送,如果两帧发送之间能间隔一段时间,那么在接收端就可以产生空闲中断(关于这个空闲中断,以后可能会专门写一篇笔记介绍),有了空闲中断有什么好处?
1) 可以接收不定长数据(这是最明显的好处)
2) 不需要复杂的帧格式(比如帧头、帧尾可以不要)
3) 一个数据帧接收错误,不会影响到下一帧数据的接收
有了空闲中断,可谓好处多多(有的单片机没有空闲中断,那就没办法,当然也可以舍弃一个定时器资源来获得空闲中断的效果),所以当初了解到这个之后,就一直使用这种方式接收了。
但是空闲中断虽好,如果你每接收一个字节都要CPU干预,还是效率太低,那么这时候就得配合DMA了。
怎么配合?比如说你一个数据帧的最大长度是10个字节,设置串口接收缓存区为20个字节,那么你可以设置DMA传输长度为20,这样DMA每从串口传输一个字节,传输长度就会自减,当产生空闲中断时,只要你知道开始设置的传输长度和剩余的传输长度,那么就可以得到你已经接收的数据长度,之后你再重新设置新的接收长度即可进行下一次数据帧的接收。
如此一来,接收一个数据帧只要CPU干预一次就够了,就是在接收完数据帧的时候由空闲中断通知CPU进行后续处理即可(注意不是DMA中断),极大的减少了CPU工作时间。
有的时候,数据量很大,CPU来不及处理,那么你可以通过以下方式解决:
1) 增加消息队列(非常好的解决方式)
2) 增加两帧之间的发送时间(对于实时性要求很高的可能不合适)
3) 前面两种方式叠加
02、LCD显示屏上的按键有多种触发方式,比如触摸、实体按键,以后还可能增加其他方式,你会怎么设计结构,让其兼容适应不同的环境?
如果是你,你会怎么考虑?
鱼鹰当初的答案是:软件层次上设计三层。
第一层:和硬件底层驱动相关的
第二层:中间层,负责对接底层驱动和上层应用
第三层:上层调用接口
这个答案我不知道到底好不好,但就以我现有的知识介绍吧。
一般开发人员的软件设计只有第一层和第三层(即应用层直接访问底层函数),很少有第二层,事实上设计第二层很有必要,为什么这么说呢,就像题目所说的,一旦你将触摸换成了按键,那么所有用到这个按键程序的地方,你都得进行修改,虽然不是很难,但是也麻烦,并且增加了出错的可能性,但是有了中间层就不一样了,你只要修改这个中间层的代码就可以了,你的应用层根本不需要修改。所以中间层的设计很关键,要尽可能的把关键信息抽象化,这样才不会导致明明已经设计了中间层,还是免不了大面积修改,那么就得不偿失了(这里的中间层可以使用函数指针或者使用一个函数封装一个底层函数,而你的函数(指针)原型就得好好考虑清楚了)。
03、FIFO队列中,有一个后面接收的数据,但是想让它更快处理,应该怎么办?
FIFO队列的特点就是先进先出,为什么这个问题反着来?既然你都是顺序处理了,为啥你还要插队?但是实际上确实可能出现插队的情况,那该怎么办?这个问题如果是以前的自己可能回答不出来,但是当鱼鹰把uCOS II 源码看了个遍之后,就知道该怎么做了。
uCOS II的消息队列的源码中,有个函数的选项,就可以选择你插入队列的数据放在队头还是队尾。按照队列的特点,肯定是要插入到队尾的,但是题目要求更快处理,那么插入到队头是最好的方式,所以这个问题的答案是,将数据插入到队头,这样既可保持队列的特性,又能处理一些紧急的消息,一举两得。
从这里也可以知道,阅读源码虽然看似费时费力,但是对你的思想、思维是有很大拓展意义的,与其停留在表明不明所以,遇到操作系统问题到处问人,不如静下心来好好看看源码,对你的技术水平是会有很大的提高的。
最后留一个问题,如果单片机没有在线调试功能,你会用什么方式调试?
相关问答
有哪些比较基础的计算机书籍?我就从一个算法初学者的角度来回答一下吧。推荐一下「算法与数据结构」从入门到进阶的书单。一.入门系列这些书籍通过图片、打比方等通俗易懂的方法来讲述,让...
如何骂醒大学不想学习的人?感谢邀请!大学是一个相对来说比较自由的环境,没有家长和老师的监督和督促,很多人就会没有动力,会比较懒散。当一个人需要靠自己的自主地去学习的时候,很多...读...