先来分析一个这个程序,这个程序用了两个中断,一个定时器中断,一个外断中断,程序的算法是让定时器中断不停的记数,外部中断在下降没来临的时候将这个记数值并将上一次记的数值存在一个数组中,不过这个程序有一个小Bug,就是那个startflag是没有起到关键性的作用的啊?!其实编这个程序的程序员想的是用startflag,这个方法可以过滤过那一个引导码,但是如果你足够细心就会发现他没有做startflag清0的操作,不过诡异的事情是即使这样也没有影响正常的解码程序的运行,其实只要你认真分析一下就会发现有没有startflag清0这一个判断的条件其实没有多大的意义,我的意思是有没有这一条语句都不会影响正常的解码,首先来分析原程序,也就是没有startflag清0这一语句的情况,第一个引导码来的时候,进入else语句,将第一个引导码过虑掉,进入else语句的就是后面有用的解值了,第一次会执行到if(irtime<54&&irtime>=50)这一条语句,因为引导码的长度刚好在这个范围内,所以会执行下会的一条i=0,也就是会把数组的下标清0,然后会把相应的32个红外编码存到数组中,注意这里的数组的长度是33,而不是32,因为irdata[0]是用来存放引导码的,还有一点非常值很注意,就是这32个有效的红外数据接收完了之后,会有一个重复码,这个重复码和引导码长得很相似,这个我用示波器看过,这个重复码可以看作是第34个波形,而且有一点非常值很注意,就是这个重复码只要你按键不松手的话是一直会发的,所以如何处理这个重复码的问题也是很关键的,至于这个问题我后面会有讲到,现有我们先来将这个重复码看成是第34个红外码,他的意义在于可以提供一个下降沿,有了这个下降沿就会将第32个红外码值存入data[32]中,所以最终的结果就是33个红外编码全部存入了容量为33的数组中,但是这时还有一个问题就是如果按键按下不放的话,后面还会有无数的波形啊,这时解码程序还在不停的处理,后面的红外编码会存入第34,35,36……等后面的数组中,这是不希望看到的,这也会导致一个更加可怕的问题,那就是程序的溢出,那天在防真器上出现了这个问题决对就是这个原因.因为数组只有33个元素,而在接收到这33个元素之后还没有停止对红外码的接收,后面的元素继续存入只有33个元素的数组中,必定会导致数据的溢出,也就是会弹出那样的一个溢出的界面,我还记得当天没有接红外接收管硬件的时候也会有这个溢出的窗口,那是因为当时没有在中断进入这后将中断标志位清0,所以会一直有中断进来,从而这33个元素的数组就会很快存满了,然后还在进入不停的进入中断,最后导致这33个元素的数组全部存满了还在不停的往里面存数据,所以也会导致程序的溢出.所以以后就有了一条经验,那就是如果程序溢出了有一种可能性就是往一个固定长度的数组中存入了大于其长度的数据.那么如何解决这个问题呢,一种可行的方法是这样的,待33个红外数据全部存完以后,置一个标志,后面接收到的数据只要不是引导码就做一次函数返回,当接收到这个正确的引导码以后才可以进行下一轮数据的接收.
上面的这个问题暂且放下(只要摇控器发出的波形只有34个脉冲就不会出现上面的问题 ,这种摇控器的特点就是只要你按下一个按键不论你是不松手,它都只会发出一帧数据,不会有后面的故虑),下面考虑第二帧数据的接收情况,当第二帧数据来临的时候,由于没有清0 startflag,程序会进入if(startflag)这一个分支,也就是会处理引导码的情况,这里会到下面的一条语句if(irtime<63&&irtime>=33),而这时irtime是一个随机的数,所以说这条语句有可能能被执行到也有可能不会被执行到,无论其是否能被执行到,都无所谓,等下一个下降沿到来的时候那个时候irtime存入的才是引导码的数据,也就是直到第二个下降沿到来的时候,irdata的下标才会清0,这时才会将引导码存入irdata的第0个格子里面.而后的数据会将先前的数据覆盖掉,也就消除了第一次接收到的数据的不稳定因素.
如果有接收到第33个元素后将startflag清0.每次接收红外的时候就和第一次的一样了,还过即使是这样也不能摆脱那个接收到重复码的问题.下面是有startflag清0的程序.
|