记一次单片机曼彻斯特解码调试

博客参考:https://blog.csdn.net/Stack_/article/details/116952678

发送数据时序
在这里插入图片描述
相比ID卡,解码思路差不多,但这个时序是要简单一些的,特点是有起始头码,数据一共3个字节(24位),发码间隔时间150ms,没有校验码

解码思路:
1.设置外部中断边沿触发
2.设置定时器计数,进入外部中断后关闭定时器计数,然后读取定时器计数值TH0和TL0的值,再开启定时器计数,根据定时器计数值判断4T,T,2T的值的范围
3.设置头码检验,也就是定时器计数值在4T范围内
4.设置数据检验,并且记录这一次的值。由于头码是一段低电平,那么标记头码低电平状态,头码之后的第一次是上升沿中断,并且读取到定时器计数值是T范围的值,记录这一次的状态,不记录这一次的数据。下一次下降沿中断再次读取到定时器计数值是T范围的值,那么记录下这次读取到的值为0,并且记录为低电平状态
5.如果上一次为低电平状态,并且在下降沿读到2T,那么说明数据跳变为1了,记录为高电平状态,如果在上升沿读到T,说明数据还是0,记录为低电平状态;如果上一次为高电平状态,并且在下降沿读到T,说明数据是1,记录为高电平状态,如果上升沿读到2T,那么数据是0,记录为低电平状态。

//外部中断0处理函数
{  
	static U8	XDATA dataenflag=0;
	static U8	XDATA LastState=0;
	static U16	XDATA WaveNow=0;
	static U8	XDATA DataStateFlag=0;
	static U8	XDATA RfState=0;
	static U8 XDATA Invcnt=0;
	U8 XDATA i=0;	
	T0En(OFF);
	
	// 判断上升沿还是下降沿
	Invcnt = R_FLAG & 0x07;
	if(Invcnt & 0x04)
	{
		DataStateFlag=DATA_STATE_H;//上升沿
	}
	else
	{
		DataStateFlag=DATA_STATE_L;//下降沿
	}
	
	WaveNow=0; 
	WaveNow=((U16)TH0)&0x00ff; 
	WaveNow=(WaveNow<<8)&0xff00; 
	WaveNow+=(((U16)TL0)&0x00ff); 
	TH0=TL0=0;
	T0En(ON);
/*接收足够的数据判断T,2T,4T的值的范围*/
	#if 0
	g_u8Tesetbuf[g_u8Tesetcnt]=WaveNow;
	if(++g_u8Tesetcnt>=59)
	{
		g_u8Teseflag=1;
	}
	else
	{
		T0En(ON);
	}
	#endif

	#if 1
	switch(RfState)
	{
		case 0:  //找头
			if(DataStateFlag==DATA_STATE_H)
			{
				if((WaveNow>RF_STAR_MIX)&&(WaveNow<RF_STAR_MAX))
				{
					RfState=1;
					g_u8Tesetcnt=0;
					Invcnt=0;
					LastState=DATA_TYPE_L;
				}	
			}
			break;			
		#if 1
		case 1:
			//g_u8Teseflag=1;
			if(LastState==DATA_TYPE_L)
			{
				if(DataStateFlag==DATA_STATE_L)
				{
					if((WaveNow>RF_DATA_B_MIX)&&(WaveNow<RF_DATA_B_MAX))
					{
						g_u8Tesetbuf[g_u8Tesetcnt]=0x01;
						dataenflag=1;
						LastState=DATA_TYPE_H;
					}
					//else if((WaveNow<RF_DATA_A_MIX)||(WaveNow>RF_DATA_B_MAX))
					else if(WaveNow>RF_DATA_B_MAX)
					{
						dataenflag=2;		//  异常值
					}
					else{dataenflag=0;}
				}
				else if(DataStateFlag==DATA_STATE_H)
				{
					//if((WaveNow>RF_DATA_A_MIX)&&(WaveNow<RF_DATA_A_MAX))
					if((WaveNow<RF_DATA_A_MAX))
					{
						g_u8Tesetbuf[g_u8Tesetcnt]=0x00;
						dataenflag=1;
						LastState=DATA_TYPE_L;
					}
					else if((WaveNow>RF_DATA_B_MAX))
					{
						dataenflag=2;		//  异常值
					}
					else{dataenflag=0;}
				}
				
			}
			
			else if(LastState==DATA_TYPE_H)
			{
				if(DataStateFlag==DATA_STATE_L)
				{
					//if((WaveNow>RF_DATA_A_MIX)&&(WaveNow<RF_DATA_A_MAX))
					if((WaveNow<RF_DATA_A_MAX))
					{
						g_u8Tesetbuf[g_u8Tesetcnt]=0x01;
						dataenflag=1;
						LastState=DATA_TYPE_H;
					}
					else if((WaveNow>RF_DATA_B_MAX))
					{
						dataenflag=2;		//  异常值
					}					
					else{dataenflag=0;}
				}
				else if(DataStateFlag==DATA_STATE_H)
				{
					if((WaveNow>RF_DATA_B_MIX)&&(WaveNow<RF_DATA_B_MAX))
					{
						g_u8Tesetbuf[g_u8Tesetcnt]=0x00;
						dataenflag=1;
						LastState=DATA_TYPE_L;
					}
					else if((WaveNow>RF_DATA_B_MAX))
					{
						dataenflag=2;		//  异常值
					}					
					else{dataenflag=0;}
				}
			}
			/**/
			if(dataenflag==1)
			{
				dataenflag=0;
				if(g_u8Tesetcnt<23)
				{
					g_u8Tesetcnt++;
				}
				else
				{
					for(i=0;i<24;i++)
					{
						g_u8Tesetbuf2[i]=g_u8Tesetbuf[i];
					}
					g_u8Teseflag=1;
					RfState=0;

				}
			}
			else if(dataenflag==2)
			{
				g_u8DATAflag=WaveNow;//看看出错情况
				RfState=0;
				g_u8Tesetcnt=0;
			}
			break;
		#endif
		default:break;
	}
	#endif			    
	
	IE0 = 0;	// 清除中断标志
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
曼彻斯特编码是一种将数字信号转换为具有直流平衡的信号的编码方法,其解码过程需要单片机进行处理。下面是一个使用单片机解码曼彻斯特码波形的示例程序: ```c /* Manchester decoding program */ #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <stdbool.h> #define BUF_SIZE 1024 /* Input waveform */ const uint8_t waveform[] = { 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA, }; /* Decoded data buffer */ uint8_t decoded_buf[BUF_SIZE]; int main(void) { uint8_t bit_buf = 0; bool is_polarity_positive = true; // Start with positive polarity size_t bit_pos = 0; size_t byte_pos = 0; /* Decode the waveform */ for(size_t i = 0; i < sizeof(waveform); i++) { uint8_t byte = waveform[i]; for(uint8_t mask = 0x80; mask > 0; mask >>= 1) { bool is_bit_positive = (byte & mask) != 0; if(is_polarity_positive && !is_bit_positive) { decoded_buf[byte_pos] = bit_buf; byte_pos++; bit_buf = 0; bit_pos = 0; } else if(!is_polarity_positive && is_bit_positive) { decoded_buf[byte_pos] = bit_buf; byte_pos++; bit_buf = 0; bit_pos = 0; } else { bit_buf |= is_bit_positive << bit_pos; bit_pos++; } is_polarity_positive = !is_polarity_positive; } } /* Print the decoded data */ for(size_t i = 0; i < byte_pos; i++) { printf("%02X ", decoded_buf[i]); } printf("\n"); return EXIT_SUCCESS; } ``` 这个程序将一个预定义的曼彻斯特编码波形解码成8位字节,并将结果存储在 `decoded_buf` 数组中。程序首先设置了一些变量,包括一个 `bit_buf` 缓冲区,用于存储正在解码的字节,以及一个 `is_polarity_positive` 变量,指示当前位是正极性还是负极性。 程序的主要循环遍历输入波形的每个字节和字节中的每个位。如果当前位的极性与前一位不同,则将 `bit_buf` 中的位视为解码的位,并将其存储到 `decoded_buf` 中。否则,当前位被添加到 `bit_buf` 的下一个位置。在这个过程中,`is_polarity_positive` 变量被反转,以便在下一次迭代中使用相反的极性。 最后,程序打印解码的字节序列,以验证解码的正确性。需要注意的是,这个程序只适用于标准曼彻斯特编码,对于其他变种,可能需要进行一些修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值