个人很难做出一番伟大的成就,团队才有可能完成一个完整的项目,团队精神的重要不言而喻,以前对这一系列话的理解,只是停留在脑海,实践了才真正知道团队的含义。刚参加工作时,总听别的同事在讨论他们之间要定接口,对于这个概念很陌生,只是别人给我讲解了很多遍,没有应用场景,依然不明白接口的具体应用应该是一个什么样子。所以每次领导让我定接口,写协议的时候总是很茫然,难免有些天马行空,不知所云。此番经历之后,明白了接口的深意。
工作两年,第一次需要与同事一起去配合完成一个项目,第一次感受到了一个项目的模块划分,以及最终功能的配合。项目刚开始进展没有多久,领导就说让开始与传输上方定一个上行传输协议,协议定好了再各干各的工作,第一次正式有了定协议的概念。基于以前导师的悉心教导和刚来公司时老板的细致要求,我已正式版本的格式要求自己,定了一个还算合格的协议。不管任何事情都需要经历反复的修改,才可能达到一种相对的完美。协议反复修改了很多次,把上行、下行通信的所有数据信息都仔细考虑,经过跟领导的协商,通信协议的第一个正式版诞生了。这次项目主要由我们3个人完成,需要两次传输才能实现底层数据与上层命令之间的交互。最终协议版本是由我操刀,与领导商讨出炉的,完成后需要将协议分发给另外两个同事参阅,以后数据传输就按照这种格式来进行。每一种经历,都可以学习一种知识,这就是做技术的魅力所在。这次协议制定好,分发下去之后,项目组仅有的三个人,除我之外每个人都会有一种不同的声音。这使我知道以后在指定协议时,要尽可能的考虑完备,避免反复修改,不然的话很有可能发生被口水淹死的惨剧。还有就是在协议中一定要给出一定的例子作为参考,尽可能使阅读者在不发问的情况下明白如何使用你所制定的协议。
之前的2.4G传输涉及的接收终端少,传输数据也比较简单,所以直接都是把带传输的内容写在一个数组中,之前填充到2.4G的发送缓冲中完成的。这次协议制定好之后,领导建议把协议包装成结构体,这样写出来的代码比较清晰。这给我出了第一个难题,之前都是直接将缓冲数组的首地址直接赋给待调用的函数作为参数传输给缓冲区的,这次变成数组了,我要如何让函数知道要调用这一块数据呢。原来在内存中一个结构体和一个连续数组所占用的内存形式是一样的,所以如果有办法告诉函数要调用的地址是哪里,那么这个问题也就可以解决了。办法就是用一个强制类型转换将结构体的指针转换成字符型指针,而这个地址其实就是整个数据块的首地址指针。
在这一块还发现一个问题就是在定义结构体是,一定要注意结构体成员中的数据类型。这是一个结构体成员在内存中地址存放的问题。结构体数组的内存对齐方式是由其成员中占用内存最长的数据类型决定的。而且任何一个成员变量其首地址值一定是一个能被其所占用的内存数整除的值。所以在定义结构体时,一般都会将同一数据类型的成员放在连续的一块地址中。
这一次的项目要求中融入了收发两种功能,而且在必要的时候还需要进行收发转换。之前笨笨的还以为所有的这些功能,包括双向传输的协议都要自己制定。但是后来功能完成之后发现收发两端的配合总是存在问题,总是存在发送好多次却收不到数据的问题。后来,老板告诉我们24L01内部本来就已经定义好了全双工通信的机制。之前在应用24L01时,总是喜欢把接收通道的Enhance ShockBrust(增强式突发模式)关闭,因为一旦把这个功能打开,当开了两个接收端的时候,接收端就总是会收到一些无法解析的、感觉不是由发放发送的数据。这次终于是要不得不用了,其实实现这个功能也不外乎以下5点:
1、打开Enhance ShockBrust寄存器的响应通道,使能其自动回复功能。
2、特殊功能寄存器0X1D中打开发送数据自动回复,和接收动态数据载荷两个功能。
3、设置合适的自动重发次数,不能设置为0,这样会认为是禁止自动重发。同时,设置响应的每次自动重发延时。
4、对于发送方而言,在发送的时候一定是使用带载荷发送这样的命令。
5、在中断中判断相应的中断标志位是否被置位。
经过这个修改后,再试了一次,果然收发感觉比以前快了很多。以为这样总算是大功告成了,但是好景不长。当把3个地址、频点相同的接收设备都上电之后,工作一段时间之后如同死机了一样无法正常工作,但是事实上430并没有死机,而是程序进不了中断,收不到数据。用示波器观察24L01中断引脚IRQ电平,发现工作一段时间后IRQ被拉低,无法拉高。所以在主程序中加入了补偿机制,可是发现,如果两个设备同时工作还是会出现工作一段时间后无法正常的问题,再次测量IRQ引脚,虽然这时IRQ引脚处于高电平(正常状态),可是却仍然是无法收到中断。费解的问题弄了一半,新任务又要来了,这个问题又要暂时搁置了。过段时间再说吧