STC51单片机433M解码程序详解

最近需要用到433M的单片机解码,上网搜了一下。大部分的程序都是基于定时器定时检测。感觉逻辑不够严谨。对于新手理解起来也比较困难。

查看EV1527手册

我是用的240K电阻。得到了每个数据宽度是1.29MS,每个数据宽度为16个LCK,每个LCK宽度大约为80us,

可以算出同步位的高电平时间大约为:320us,低电平持续时间为:9.9ms

数据1的高电平持续时间为:960us,  数据1的低电平持续时间为320us

数据0的高电平持续时间为:320us,数据0的低电平持续时间为960us。

已经知道了数据0和1还有同步信号的持续时间,我们来说一下思路

我首先开了一个us级的定时器,持续计数。不需要打开中断。

然后配置好对应的接收芯片的管脚。配置为外部中断。触发方式为上升沿,下降沿都触发。

在外部中断函数里面,记录当前定时器的计数值,然后清零计数器。

定义一个状态机

state = 0时:默认状态,检测是否为高电平。如果为高电平代表为上升沿,判断同步信号。

state = 1时:检测是否为低电平,如果为低电平,表示为下降沿,此时记录的时间为高电平的持续时间。判断是否符合同步信号的高电平时间要求。符合进入下一状态

state = 2时:检测管脚是否为高电平,如果为高电平,表示为上升沿,此时记录的时间为低电平持续时间。判断是否符合同步信号的低电平时间要求。符合进入接收状态。不符合,回到初始状态。

以此类推….具体可以看代码

//这里有优化。一搬同步信号只需要判断低电平持续时间就可以了。所以这个高电平范围可以大一点。

#define SYNC_H_MIN   0           //同步信号高电平持续时间 最低范围

#define SYNC_H_MAX   600       //同步信号高电平持续时间 最高范围

#define SYNC_L_MIN  8000       //同步信号低电平持续时间的最小值

#define SYNC_L_MAX  10997    //同步信号高电平持续时间的最大值,符合这个范围都判定有效。

#define DAT1_H_MIN     800    //数据1的高电平持续时间最小值  

#define DAT1_H_MAX   1063   //数据1的高电平持续时间最大值

#define DAT1_L_MIN      220    //数据1的低电平持续时间最小值

#define DAT1_L_MAX    400     //数据1的低电平持续时间最大值   

#define DAT0_H_MIN     220

#define DAT0_H_MAX    400

#define DAT0_L_MIN      800

#define DAT0_L_MAX    1063

uint32_t bitNums  = 0;    //已经接收的位数。
uint32_t valueTmp = 0;    //接收的数据。
uint32_t value = 0;  

void Ext_INT1 (void) interrupt INT1_VECTOR		//进中断时已经清除标志
{
		uint8_t  de = 0;						    //管脚的状态
		uint32_t holdTime  = 0;				    //持续的时间
		
		Timer1_Stop();
		holdTime  = (TH1<<8) | TL1;
		TH1= 0;TL1 =0;
		de = P33;	    //读取IO口状态
		Timer1_Run();
		

		switch(state)
		{
			case 0:		
				if(de == 1) 	//如果是高电平,那么是上升沿
					state= 1;
			break;
			case 1:		        //同步头高电平时间结束的时候
				if( de == 0		//检测到下降沿,并判断持续的时间 
					&& holdTime  >= SYNC_H_MIN 
					&& holdTime  <= SYNC_H_MAX)
				{
					state = 2;
				}
				else
				{
					state = 1;
				}
					
			break;
			case 2:		//同步信号低电平时间结束时,上升沿
			{
				if( de == 1 
					&& holdTime >= SYNC_L_MIN
					&& holdTime <= SYNC_L_MAX)    //判断同步低电平时间是否符合要求
				{
                    //符合要求,清0接收到的位数和数据。准备开始接收
					bitNums = 0;    
					valueTmp= 0;
					state = 3;
				}
				else
				{
                    //不符合要求直接回到状态1,不用回到状态0,因为不需要判断同步信号的高电平
                    //持续时间,低电平满足需求即可
					state = 1;
				}
			}
			break;
			case 3:		//信号高电平结束时
				if(de == 0)
				{
					valueTmp <<= 1;
					
					if(holdTime >= DAT1_H_MIN && holdTime <= DAT1_H_MAX)
					{
						valueTmp += 1;		//符合数据1的高部分
						state = 4;
					}
					else if(holdTime >= DAT0_H_MIN && holdTime <= DAT0_H_MAX)
					{
									//符合数据0的高部分
						state = 5;
					}
					else
					{
						state = 1;
						break;
					}
					bitNums += 1;
					if(bitNums >= 24)
					{    
                        value = valueTmp;       //保存接收到的数据。
						state = 1;
					}
				}
				else
				{

					state = 1;
				}
			break;
			case 4:		//判断数据1的低电平时间是否符合要求
			{
				if( de == 1
					&& holdTime >= DAT1_L_MIN
					&& holdTime <= DAT1_L_MAX)
				{
                    //符合数据1的低电平时间要求,回到3重新接收下一个数据。
					state = 3;
				}
				else
				{
					state = 1;	
				}
			}
			break;
			case 5:	//判断数据0的低电平时间是否符合要求
			{
				if( de == 1 
					&& holdTime >= DAT0_L_MIN
					&& holdTime <= DAT0_L_MAX)
				{
                    //符合要求,接收下一个数据。
					state = 3;
				}
				else
				{
					state = 1;
				}
			}			
			break;
			default:
				state = 0;
			break;
		}
	
}

 

物联沃分享整理
物联沃-IOTWORD物联网 » STC51单片机433M解码程序详解

发表评论