|
项目维护人: 鲁郁 |
ENGLISH |
|
|
|
|
|
|
|
|
老祖宗的这句话直到今天还闪烁着睿智的光芒. 这句话对谁都适用,不管你的智商是75还是205. 这里的"勤"并非意味着要早上5点起床,晚上12点才睡觉,我想,这里的"勤"应有更广的含义. 我的体会是: 要勤学,勤思,勤练.
所谓勤学, 就是要持之以恒的学习,"书到用时方恨少"(下联什么来着?"衣到洗时才嫌多"?). 以硬件设计来说,在课堂上学的数电和模电是基础, 但仅有基础是远远不够的,硬件设计牵涉的知识包括阻容晶体管分立器件,常用门电路, 单片机设计,FPGA/PLD可编程逻辑器件,DSP系统,存储器芯片,PC机接口(RS232,RS485, 并口,ISA,PCI,USB,FIREWIRE...).这些知识不可能都在课堂上学习,但如果不掌握这些知识, 在做硬件选型的时候就会受限制,最多只能勉勉强强地拿出一个或两个设计,这样谈何最优方案? 以软件设计来说,对一个电子工程师,C语言可以说是基本功中的基本功了,谈到C语言, 有人可能会不屑一顾:"学C语言应该是大一新生的事情". 的确,我学C语言至今也有10年了, 可直到今天我的枕边还常备一本C/C++的书,闲来无事就拿起来翻几页。 在实际工作中学C语言和在学校里学习是不同的:在学校里,某一个知识点错过了, 至多考试时少个3或5分,可现在,错过一个知识点,那么把你折腾了好几宿的那个BUG可能就是那个知识点。 这都是血泪教训呀。
所谓勤思,就是要多想想。一个别人的成功设计,作为一个电子工程师,不仅要会用, 还应该想一想某一个功能别人是如何实现的,如果让我做,我会怎么做。在学习理论的时候, 不要仅局限于理论上的推导,还要想一想在一个数字系统应该怎样来实现。只有这样, 才能在遇到问题的时候不致于措手不及,才会有清晰的物理概念.
所谓勤练,就是要经常练兵.做硬件的,如果有条件,时不时做块小板子,写上几行汇编程序, 实现一些简单功能,这样使技艺不致生疏,所谓"业精于勤荒于嬉";做软件的, 可以经常编一些小程序,也是同样的目的.
回首我做这个项目的8个月中,其中共有5次大的沮丧,每一次都令我几乎放弃.
沮丧一: 在2003年的10-12月,我全力以赴调试固件和驱动,主要是将USB通信搞定. 当我完成了设备驱动,准备做GP2021的读写接口时,猛然发现,GP2021的数据线是16位的, 而51单片机(我最初用的是ATMEL89C51)的总线是8位的.每一个本科毕业的电子系学生都知道:8位机是不能直接接16位器件的! 这让我极其郁闷:想我鲁少侠行走江湖也有6,7年了,从未失过手, 竟在这么简单的问题上疏忽大意, 实在不可原谅。痛定思痛,坐下来找解决方案:方案1,用16个IO脚造出16位总线的读写时序; 方案2,废掉该接口板,另外找16位或32位处理器重新做硬件.方案1的问题在于,读写的速度要减慢很多, 以前只用一个读写指令就完成的事,现在必须用10几条指令才能完成.方案2的问题在于违反了我的很重要的设计思想, 既硬件的简洁和硬件开发的难度要低.这个问题在后来选定DS89C420以后才解决,我选的还是方案1.
沮丧二: 驱动完成后,我开始编写简单的测试程序来测试接口板和PC机的通信.令我惊讶的是, 我的USB设备和PC的通信速率只有几十K字节每秒,这个和USB1.1 12Mbps的理论值实在差别太大. 以这个速率,要想实时控制GP2021是不可能的.我努力了一个月后,没有什么起色,非常沮丧, 当时的想法还是废掉USB接口板,转而采用并口的EPP模式,但我看看丑陋粗大的25针的并口电缆, 还是咬咬牙坚持调试USB.这个过程持续了将近两个月,才把USB通信速率提上去.在当时,可真是极度的折磨.
沮丧三:在传输GP2021的数据时,因为每一帧数据包含4组,每一组包含12个通道的数据(在一开始我是想做12通道的), 每一个通道的数据包含PROMPT的I,Q, TRACK的I,Q, 加上8个测量值(CODE_SLEW,CODE_PHASE, CARRIER_CYCLE_LOW, CARRIER_DCO_PHASE,EPOCH,CODE_DCO_PHASE,CARRIER_CYCLE_HIGH,EPOCH_CHECK). 有兴趣的可以算算需要多少个字节: (4*2+8*2)*12*4 = 1152. 而DS89C420的片上RAM只有1K, 这样带来的另一个问题是,USB提供不了这样宽的总线带宽(也许理论上可以,至少我的硬件不能).怎么办? 废掉当前的板子,另外做一块DSP板子?资源倒是够了,可开发难度又上去了,而且说句粗话, 这样的做法有点象"脱裤子放屁---多此一举",因为DSP本身就有很强的处理能力,1MS一次的处理强度对DSP来说是小菜一碟, 还要你PC机干吗? 这个问题的解决是在读了GP2021的数据手册N遍以后,蓦然发现, 原来每个通道的8个测量值只有在TIC发生后才更新,所以只需要在TIC发生后才有必要传输给PC, 而TIC是每100毫秒才发生一次, 这样就大大降低了数据量,不仅减轻了对数据缓存的压力,也降低了对数据带宽的要求, 在加上将欲锁定的通道数由12个减到6个(这个是没有办法的办法,只有等USB2.0的接口板来实现12个通道了), 实时控制GP2021已经不是困难了.这个问题也折磨了我近一个月之久.
沮丧四: 这一次是我开始调试TRACKING LOOP以后.我的环路怎么都不能锁定信号,我能确定信号肯定存在, 因为我在CONFIRM状态将数据存在文件里分析,相关器的输出很强,而且都是在同一个伪随机码相位出现, 这是典型的GPS信号. 可我的环路就是不能锁定. 因为USB不是一种萃发读写的总线, 我的GP2021的控制指令是由跟踪环路代码根据每3或4毫秒的相关器的输出才产生一次,而CLIFFORD的设计中, GP2021的控制指令是每一毫秒的相关器的输出就会产生一次.这一次我心中实在是没底了, 因为看起来在锁相(和锁频)环路,(PLL 和 FLL), 的更新时钟就完全不一样了,而且有时是3毫秒, 有时是4毫秒.这个问题的解决就不是一两句话可以说清的了,有兴趣的可以读一读我的环路代码. 这个问题也困扰了我一个月之久.
沮丧五:这一次的沮丧在我认为最不可能的时机出现:我的程序已经可以锁定6路卫星数据, TOW和TLM,以及EPHEMERIS数据都可以被正确解调,卫星的精确位置我也已经可以毫不费力地算出, 看起来眼前是一片康庄大道,前途一片光明, 还有什么工作的干活? 对,解算PSEUDORANGE和用户的位置坐标!但我又一次突然发现, 我竟然得不到卫星信号精确的发送时间,这一点是由于USB硬件所限:每一个数据比特是20毫秒, 在数据的跳变沿,常规的做法是要置GP2021的EPOCH寄存器的MS部分为1, 这样在TIC发生时读到的EPOCH值才是同步的, 否则会有一个未知的偏移,偏移一个毫秒便是300公里呀(0.001*光速=300KM)! 而对USB通信来说,是不可能在任意时刻向设备发号施令的,所有的USB包都必须在1毫秒的时间帧上发送. 在那段日子里,我算出的位置一会在加州,一会在佛罗里达,一会又到了加拿大,一个小时之内可以游遍整个北美洲! 这个问题的解决也是不能用几句话能说清的,可以参看我的代码.我只所以坚持下去是我实在不甘心放弃, 感觉象两万五千里长征已经走完了1.2499999E7米,于是奋力的熬了一个星期的夜,搞定. (当然我的解决方案偶尔还会算错,但大部分时间都能给出正确结果,对于一个面向教育意义的项目已经足够了).
回首前尘,我很庆幸在每一个挫折前没有轻易放弃,而是征服了它.我的感觉是,往往当你觉得走投无路的时候, 你其实已经快要胜利了,你要做的只是再坚持一下.而当你解决了这个困难以后,你的经验值就又长了几分.
有趣的是,这个道理是我的一对双胞胎儿子使我明白的.有点匪夷所思? 在他俩还没出生的时候,我每天可以有3到4个小时的时间用在开发上.在这3到4个小时里, 我几乎都坐在电脑前写程序,如果顺利的话可以写个几百行没问题,可是我发现,当天写的程序, 总是会在第二或第三天被删掉一大半,也就是说,大部分的工作最后都是垃圾; 随着宝宝的出生, 我每天的开发时间骤减到1个小时, 而且这一个小时还是断断续续的:刚坐下20分钟,有情况发生(儿子饿了,渴了,尿了,屙了,寂寞了..., 刚搞定老大,老二又开始上场了), 当我把他安抚了,一个小时又过去了.可是在这一个小时里,虽然我没有写代码,但是大脑却没有停止思考. 也就是说,为了20分钟的程序我思考了1个小时,我会想出好几个方案,这样当我再坐在电脑前的时候, 我可以选择一个最优的方案来实现. 于是在每天一个小时的开发时间里,我虽然只能写一百行甚至几十行程序, 但返工的却少得多,大部分程序都可以一次通过. 另外一个有趣的现象是,白天当我发现我的程序运行不正常, 肯定是有BUG, 而很多的BUG却是我在凌晨3,4点钟给孩子喂奶的时候灵感突现解决的:-),不过这样的后果就是失眠.
UTC 时间: 6:55, 七月25日, 2004 本地时间:23:55, 七月24日, 2004 |
|
于UC, Riverside ( 经度:-117.326 纬度: 33.981 高度:294.17米) |