这儿使用一个实践产生的比如,针对初级工程师常常犯的一个小过错,或许常常要走的一个弯路,做了针对性的纠正。期望能够帮到咱们,文笔欠好文章中有叙说不清的当地咱们多多指教。
这篇文章我不是想说编程的标准性的东西,假如你想让自己的程序文件最起码直观的看起来漂亮、可读性强,引荐找华为的“C言语编程标准”。我只想说一说当咱们的单片机遇到多个模块的数据需求处理,相似于“多使命”时咱们应该怎样办?
布景是这样的,上一年9月份开端组织一个工程师开端做电动轿车沟通充电桩,机械规划部分由公司机械结构部分担任。充电桩的电子部分总体上分为X个部分(用到的资源),电阻触摸屏(RS232),M1卡读写(RS232),电能计量表(RS485),语音提示(SPI),电力开关(继电器IO),通讯接口(RS485、CAN)。
工程师做的进程非常勤勉,期间也是困难重重,改了许多个版别,总算本年6月把充电桩立起来了。
咱们来检验一下吧,成果发现读卡的时分不能处理触摸屏,播映语音的时分不能处理读卡,语音播映不能打断或许跳动,横竖便是一切事情有必要一个一个墨守成规的来,一旦操作过错就需求屡次履行、等候、乃至从头来过。
一个作业3年多的工程师怎样会把产品做成这样呢?看看程序吧!
一看没联系,吓一跳!整个的程序是没有逻辑的,一条线就往下写……
While(1)
{
//上电进入主程序 或 触发触摸屏
//播映提示语音
Delay();//等候播映结束
//读取M1卡信息
Delay();//等候读卡数据回来
//播映提示语音
Delay();//等候播映结束
//M1卡数据交互,断定下一步操作及提示
Delay();//等候数据处理结束
……
……
}
这儿说这个工程师基本上关于自己规划的产品没有任何的全体概念,或许说对自己开发的程序用到规划上会有怎样的实践效果底子就不清楚。
他犯了几个咱们在程序开发进程中最忌讳的几个问题:
1、 delay(死等)这类函数只在应该实验室验证某个功用进程中用到,在实践的产品开发时无论是主循环while中,仍是其调用的函数中,亦或是中止服务程序中肯定不能够用到。
2、 产品规划的各个子模块之间的逻辑联系太强,例如:有必要等候播音结束才干读卡进入下一步操作等。
咱们讲,产品规划中只需各个事情处理模块间的逻辑联系弱化,才干愈加灵敏的进行处理。例如:两个事情A和B,假如程序开发时将A做成B事情的必要条件,B事情的触发就有必要等候A事情的产生。反之假如A事情作为B事情处理的一个特殊状况,那么程序开发起来就变得灵敏许多。
3、 没有考虑到单片机自身是一个单核单使命的架构,每一个事情都会独占CPU内核,当多个使命模块一起存在时咱们应该对各个事情进行区别,咱们应当分状况、分事情实时性要求等区别对待。
那么针关于这样的问题,或许是遇到相似的项目咱们应该怎么处理呢?
我提几条主张:
1、将硬件体系区别为独立单元独自做成底层驱动函数和使用函数,而且函数正常应该有参数和回来值,其间回来值是必要的。怎么衡量这类函数呢?这类函数可移植性强,只需一个.h文件和一个.c文件就能够随意放到任何工程中。例如:语音播映、M1读卡、485处理等等。
2、将1中的一切函数进行时刻评价,评价点有两个。一个是函数的履行时刻t,第二个是函数的周期性产生的时刻T,一个最基本的条件是t < T,抱负状况应该是t << T。
3、树立一个会集逻辑处理函数,在这个函数中对1中的各个函数进行调度。这个函数发挥的效果相当于嵌入式体系中的体系调度。这种调度是整个硬件逻辑中一切事情处理的调度,它的意图是完结一个处理进程,可是绝不依赖于恣意事情的必要处理进程。这样就将问题2中说到的事情间的逻辑联系弱化了,处理起来变得非常灵敏,使得各个联系不在彼此必要。
4、为了确保前面内容的正常施行还需求针对各类事情的周期,树立一个必要的时刻管理函数,时刻函数的根底一般状况下由一个内部定时器的中止来完结,中止的周期一般咱们考虑5-10ms。依照实践需求将N个定时器中止界说为一个事情处理的周期TT,这个周期应该确保处理完最恶劣状况可能产生的一切t,且确保TT < T。
5、 这其间也有破例,一些实时性要求高的事情应当用中止完结。其间中止处理函数的处理事情应尽量短,时刻要求拜见2。