枭龙战机

用ADuC7026解码遥控信号(原创)

0
阅读(2241)

遥控器型号:Spektrum DSx9

在每个传输周期共2个帧:Frame1和Frame2

这两个帧中包含了9个通道的序号及对应控制量。

Frame1:  00 00 + 8 byte data+ FF FF FF FF FF FF 共16 byte

Frame2:  00 00 + 10byte data+ FF FF FF FF 共16byte

传输时最小帧间隔7ms。

最大字节间隔310us,若传输时间隔大于此值则认为超时。

Frame1的起始处与Frame2的起始处时间间隔为11ms。

void IRQ_Handler() __irq			  //普通中断服务程序,执行周期10us
{
	MyIRQstate = IRQSTA;

	if((MyIRQstate & 0x10)  != 0)
	{
		count++;
		PPMCounter++;
		if(SpektrumTimer) SpektrumTimer--;	
	if((MyIRQstate & 0x4000) != 0)
	{
		if((COMIID0 & 0x04) != 0)
		{
			c = COMRX;
			Spektrum(c);
		}
	}
}

void Spektrum(unsigned char c)
{
	static unsigned char Sync=0, FrameCnt=0, ByteHigh=0, ReSync=1, Frame2=0;
	unsigned int Channel, index = 0;
	int bCheckDelay;

	#define MIN_FRAMEGAP 350           // 7ms    最小帧间隔
	#define MAX_BYTEGAP  16            // 310us  最大字节间隔


	if(ReSync == 1)		    //重新同步过程,首次执行是必走此处,若超时则也须重新同步
	{
		                              // 等待新的帧到来
		ReSync = 0;
		SpektrumTimer = MIN_FRAMEGAP; //定时变量设置为最小帧间隔
		FrameCnt = 0;	                  //统计收到的字节数而不是帧数
		Sync = 0;
		ByteHigh = 0;	                 //用于存储数据高字节
	}
	else
	{
		if(!SpektrumTimer) bCheckDelay = 1; else bCheckDelay = 0;  //若bCheckDelay,则表示未超时 
		if(Sync == 0)
		{
			if(bCheckDelay)
			{
				Sync = 1;	               //发现新的帧
				FrameCnt++;
				SpektrumTimer = MAX_BYTEGAP;//定时变量设置为最大字节时间间隔
			}
			else
			{
				Sync          = 0;      //若走此处则相当于什么也没做
				FrameCnt      = 0;
				SpektrumTimer = MIN_FRAMEGAP;
				ByteHigh 	  = 0;
			}
		}
		else if((Sync == 1) && !bCheckDelay)//已同步且在规定的超时时间内发现新的字节
		{								   
			Sync = 2;
			FrameCnt++;
			SpektrumTimer = MAX_BYTEGAP;
		}
		else if((Sync == 2) && !bCheckDelay)//又发现新字节,前两次发现的是开头 00 00 ,是不需要的数据
		{
		
			SpektrumTimer = MAX_BYTEGAP;
			ByteHigh = c;					//这是紧接在 00 00之后的数据,包含所需信息,称为高字节,要与下个字节组合才有意义
			if(FrameCnt ==2)
			{
				if(ByteHigh & 0x80)			//若最高位为1则此帧为Frame1,否则为Frame2;两个帧内数据不同 故需判别
					Frame2 = 0;
				else
					Frame2 = 1;
			}
			Sync = 3;
			FrameCnt++;
		}
		else if((Sync == 3) && !bCheckDelay)
		{
			Sync = 2;
			FrameCnt++;
			SpektrumTimer = MAX_BYTEGAP;
			Channel = ((unsigned int)ByteHigh << 8) | c;  //高低字节合成
			signal  = Channel & 0x7ff;					  //提取控制量
			index   = (ByteHigh >> 3) & 0x0f;			  //提取通道序号
			if((FrameCnt < 11) && !Frame2)				  //对于Frame1,其有效信息占10字节,超过此范围的信息无用
			{
				PPM_in[index] = signal;
			}
			if((FrameCnt < 13) &&  Frame2)				  //Frame2的有效信息共12字节,余下丢弃
			{
				PPM_in[index] = signal;
			}
		}
		else
		{ 										      //对于超时的处理
			ReSync = 1;
			FrameCnt = 0;
			Frame2 = 0;
			SpektrumTimer = MIN_FRAMEGAP;			
		}
		if(FrameCnt >= 16)								  //每帧长度为16字节,超过此值则等待下一帧到来
		{
			FrameCnt = 0;
			Frame2 = 0;
			Sync = 0;
			SpektrumTimer = MIN_FRAMEGAP;
		}
	} 
}

最终9通道的控制量存储在数组PPM_in[index]中