12号开始的,就是紧接着微机完了就开始了。题目是用VHDL写一个红外遥控系统,就是一个电视机遥控系统差不多吧。刚开始的5天,就是要求斋写程序,等实验板发下来再download落块板度测试。于是乎就很明显,前5天又是休息时间了,没板对照着怎么写程序呢,后来实践也证明了这一点。
就这样,前5天承接着微机休息时间的玩乐势头,玩游戏的玩游戏,打球的打球,看电影的看电影,睡觉的睡觉地颓掉了。 到了17号,板发下来了,才正式开始忙起来。
用忙字来形容这几天可能还不够,应该用拼命这两个字才对。每天废寝忘餐地写程序-仿真-修改-重写程序,持续十几个钟,工作时间是中午12点到凌晨3点几,连睡觉做梦也想着怎么写的说。每个模块都最少重写了2次,修改仿真就无数次了,很多次想放弃的时候,那份执着的精神让我坚持了下去。尤其红外线接收译码那部份,用各种算法写了4、5次,都搞得天昏地暗了,终于把误码率由90%降低到0%,那份激动啊......可是答辩阵老师叫偶当场写一个接收译码的程序出来的时候,因为太混乱了,我呆在那里想了半天,给了老师我是抄回来的印象,555。不过也没什么所谓了,啧啧。奋斗了几天,终于实现了所要求的功能,而且都是自己一手写成的,看着遥控按下时实验板可爱的反应,成就感不禁涌上心头。
而且,这次也总结出一点VHDL数字设计的经验。最重要最重要的一点是所有模块的时序都必须同步,就算什么二路数据选择啊,键盘输入啊,与门啊,或门啊等等那些组合逻辑的东东都必须用同一个时钟频率来同步,这样才能使系统达到最大的稳定,而且可能会节省一点芯片的资源。如果时序异步的话,会出现很多很多意想不到的结果的,呵呵。 另一点是状态机的问题,个人感觉状态机比较可靠,比斋在那里if......then......elsif......then可靠,因为在每个时钟就限定了它在一个状态里活动而不会走到其他状态去,感觉要稳定点。还有单进程、2进程、3进程状态机其实实现出来的结果很不一样,尽管程序逻辑上看起来一样。例如计数器的话,要设置变量自加,就只能用单进程状态机,用两进程的话会有零延时震荡,就是不稳定了,这个我吃过大亏>_<~~。最后就是那些寄存器产生的问题,我还是没有掌握好,实在太飘忽了,怪自己本来数电与VHDL都不学得咋样的,所以写这个东西的时候在寄存器的问题也浪费了大量时间。最后写完了,也不知其究竟......看来这行不太适合我的说......
This entry was posted on Sunday, January 21st, 2007 at 2:53 pm.
Diky says
January 22nd, 2007 at 10:00 am
很复杂的样子......
ligy says
January 22nd, 2007 at 2:36 pm
呵呵,自己写的不错,我也正做紧呢个,不过误码不知道怎么解决哈,你用什么方法把误码率降到0%的?
cone says
January 23rd, 2007 at 12:01 am
re Diky: 其实不复杂的。。只是对该语言掌握得不好。。很多想到的却实现不到。。re ligy: 其实就是很普遍的方法,用一个计数器来检测低电平的时间嘛。我是这样的,设时钟8k,就是周期0.125ms,一个a就0.421ms嘛,然后就一个时钟周期计数器就+1,无信号的时候是高电平,当一有低电平就开始计数,加到5的时候,判断输入是高电平还是低电平,高的话就是'0′,低的话就'1′啦。 这个办法你们应该都用了吧。还有个关键之处,就是作一个延时。检测完一串码,就是12bit后,用一个计数器来延时,延时一段时间后再开始接受检测。这样准成度就高很多了。 另外,写状态机带计数器的话,一定要用单进程状态机。
ligy says
January 23rd, 2007 at 12:30 am
上面说的都是解码,大家都是这样做,可是接收信号时会出现误码: 当红外接收头不是从发射端发出的第一个码开始接收时,就有可能会出现错码。 例如: 当遥控器用户码为010时, 发射端010100010000 010100010000(发射按键2) 接收端从右边第三位开始接010001000001(解出按键18,这里只接收到一个串) 本来发射的是按键2,结果解出来的是按键18。 VHDL学得很差,不知道应该怎么样去检验解码是否正确,估计编不出来了~~~~呵呵
cone says
January 23rd, 2007 at 12:45 am
如果用检测低电平来决定是否开始接收的话,我觉得肯定会无误的,关键是在每接受完一次12bit后延时一段时间再进行接收,在延时那段时间不管它是否低电平都不做任何事,延时完后再开始检测接受,就会大大降低误码率了。我就是这样降低了误码率的,不做延时的话,误码率差不多50%。
-EOF-