433MHz无线模块解码扫描&定时器输入捕获

        记录一下工作的一个小项目,两种方法解码433,包括24Bit数据帧结构和32Bit数据帧结构

1、433接收模块

        本文用两种方法解析433Mhz模块的信号,分别是扫描和定时器输入捕获。解析信号首先要了解433信号的编码格式。以24Bit格式帧为例,包含同步码,20位地址码和4位数据码。

数据帧格式如下:同步码 + 20Bit地址码 + 4Bit按键码

        可以看出,每组信息都是紧跟在一个同步码后面,所以需要找到这个同步信号,然后解析出后面的24位数据。而同步信号、数据“1”和数据“0”的高低电平持续时间不同,可以根据这一点进行区分。

        下图左一是本文使用到的433接收模块,从右到左三个引脚分别是VCC,DATA,GND。再左边是天线。给433模块供电(3.3V),然后把DATA引脚与GND引脚接上示波器,查看数据波形。右图是两个433遥控器,棕色是24位编码格式,黑色是32位编码格式。

通过示波器查看接收模块收到的两个遥控器的数据,整理如下:

        棕色遥控器:

                上:同步信号 + 0000 0001 0000 0000 0111 + 0100

                下:同步信号 + 0000 0001 0000 0000 0111 + 1000

                锁:同步信号 + 0000 0001 0000 0000 0111 + 0001

                方块:同步信号 + 0000 0001 0000 0000 0111 + 0010

        四个按键前20位数据相同,为棕色遥控器的地址码,后面4位数据不同,为数据码,分别对应不同的按键。

        高低电平持续时间:

                同步信号:         高电平 408us                 低电平 12.4ms

                数据“1”:            高电平 1.2ms                 低电平 410us

                数据“0”:            高电平 410us                 低电平 1.2ms

        黑色遥控器:

                上:同步信号 + 1111 0111 1100 1100 1111 0000 0000 + 1000

                下:同步信号 + 1111 0111 1100 1100 1111 0000 0000 + 0001

                方块:同步信号 + 1111 0111 1100 1100 1111 0000 0000 + 0100

                圆圈:同步信号 + 1111 0111 1100 1100 1111 0000 0000 + 0010

        黑色遥控器的数据编码为32位,解析方法跟上面的基本一致。

        高低电平持续时间:

                同步信号:         高电平 364us             低电平 8ms

                数据“1”:            高电平 1.084ms         低电平 362us

                数据“0”:            高电平 362us             低电平 1.084ms

        现在已经整理出了两个遥控器的编码格式,以及每个按键对应的数据。接下来就要想办法把这些数据解析出来,MCU要能够检测到遥控器的哪一个按键被按下,才能去执行对应的功能。

2、扫描方式解析数据

编程思路:

        把433接收模块DATA引脚连接在一个IO上,并把IO配置为浮空输入。再配置一个定时器,50us进入一次中断。

        每50us检测一下IO的电平,如果是低电平,就开始计数,是高电平的话计算低电平持续的时间(计数值*50us),判断是否符合上面介绍的电平持续时间。如果符合其中一个同步信号,就开始准备接收数据,之后每个低电平过来,都拿它的持续时间跟数据“1”和数据“0”比较,并进行记录。这样就可以把数据解析出来。

源码:

//---------------------------------------------------------------------------------------------------------------------
//一些宏定义和变量

#define RF_DATA_PORT			GPIOA
#define RF_DATA_PIN			GPIO_Pin_8
#define RF_DATA_RCC_PORT	RCC_APB2Periph_GPIOA

//同步信号、数据'0'、数据'1'低电平持续时间范围
#define _24start_us_min		220		//低电平参考值(us)/定时器扫描周期(us)- 预留范围(us)	24Bit格式 同步信号 低电平持续时间参考值	12400us/50us == 248
#define _24start_us_max		260		//低电平参考值(us)/定时器扫描周期(us)+ 预留范围(us)
#define _24num0_us_min		23		//24Bit格式数据'0'低电平持续时间参考值 1200us/50us == 24
#define _24num0_us_max    	26
#define _24num1_us_min    	7		//24Bit格式数据'1'低电平持续时间参考值 410us/50us == 8
#define _24num1_us_max    	10

#define _32start_us_min    155		//32Bit格式 同步信号 低电平持续时间参考值	8000us/50us == 160
#define _32start_us_max    165
#define _32num0_us_min    16		//32Bit格式 数据'0' 低电平持续时间参考值 1084us/50us == 21
#define _32num0_us_max    26
#define _32num1_us_min    6			//32Bit格式 数据'1' 低电平持续时间参考值 360us/50us == 7
#define _32num1_us_max    10


#define RF_DATA  GPIO_ReadInputDataBit(RF_DATA_PORT,RF_DATA_PIN)//读取接口电平

/*
	变量说明:
		last_state		记录上一个电平,用来判断跳变沿  		例如:  last_state == 0   RF_DATA == 1  就表示上升沿
		ReadStep    	控制数据解析的进度   				ReadStep==0,接收同步信号 ;  ReadStep==1,接收24位(或32位)数据  ; ReadStep==2,数据接收完成,解析数据;
		DataFram    	数据帧格式  24位或者32位
		BitCount    	记录当前接收了多少位数据

		decode32_ok		32位格式数据解析成功
		decode24_ok		24位格式数据解析成功
		ReadLoop		读数据的次数							需要循环两次读两组数据
		CheckTime		校验计时								接收完第一组数据后,开始倒计时,如果100ms内没有接收到第二组数据,则解析失败,回到开始重新接收数据
		
		LowTime			低电平持续时间
		
		TempData[2];	存放临时数据
		rf_data32[4];	存放解析成功的32位格式数据,数组前几位存放地址值,最后一位存放数据值
		rf_data24[3];	存放解析成功的24位格式数据
		
*/
unsigned char last_state,ReadStep,DataFram,BitCount,decode32_ok,decode24_ok,ReadLoop;
unsigned int CheckTime;
unsigned int LowTime = 0;
unsigned int TempData[2] = {0};
unsigned char rf_data32[4] = {0};
unsigned char rf_data24[3] = {0};

//---------------------------------------------------------------------------------------------------------------------
//初始化

void RF433_Init(void)
{
	RF433_DATA_IO_Init();
	TIM3_Int_Init(49,71);//72分频,计数50, 即50us计时器      72MHZ经过分频编程1MHZ,1s内中断1M次,1us中断1次,50us终端50次
}

void RF433_DATA_IO_Init(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;
	 
	RCC_APB2PeriphClockCmd(RF_DATA_RCC_PORT, ENABLE);	    //使用PA端口时钟
	GPIO_InitStructure.GPIO_Pin = RF_DATA_PIN;			   
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 	 //浮空输入
	GPIO_Init(GPIOA, &GPIO_InitStructure);			    
}
void TIM3_Int_Init(u16 arr,u16 psc)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能
	
	//定时器TIM3初始化
	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值	
	TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位
 
	TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断

	//中断优先级NVIC设置
	NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
	NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器

	TIM_Cmd(TIM3, ENABLE);  //使能TIMx					 
}


//---------------------------------------------------------------------------------------------------------------------
//中断服务函数
void TIM3_IRQHandler(void)   //TIM3中断	50us中断
{
	static unsigned int TIM3_Count = 0;
	if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  //检查TIM3更新中断发生与否
	{
		TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  //清除TIMx更新中断标志 
		RF433_ReadAWord();		//解析函数
	}	
}


//---------------------------------------------------------------------------------------------------------------------
//解析函数

void RF433_ReadAWord(void)
{
	if(RF_DATA==0)		//记录低电平时间,来判断数据是'1'还是'0'
	{
		LowTime++;
		if(last_state == 1)
		{
			last_state = 0;
		}
	}
	else if(RF_DATA==1)
	{
		if(last_state == 0)	//判断是否是上升沿
		{
			last_state = 1;

			
			//进入这里说明一位数据传输结束了,现在开始判断这一位数据是什么
			if(ReadStep == 0)	//读同步信号
			{
//				if((LowTime > (7500/50)) && (LowTime < (8500/50)))		8000us/50us == 160
				if((LowTime >= _32start_us_min) && (LowTime <= _32start_us_max))
				{
					DataFram = 32;//32 位数据格式,黑色钥匙
					ReadStep = 1;
				}
				else if((LowTime >= _24start_us_min) && (LowTime <= _24start_us_max))		//12400us/50us == 248
				{
					DataFram = 24;//24 位数据格式,棕色钥匙
					ReadStep = 1;					
				}
				LowTime = 0;
			}
			else if(ReadStep == 1)	//接收数据
			{
				if(DataFram == 32)	//32 位数据解析
				{
					if((LowTime >= _32num1_us_min) && (LowTime <= _32num1_us_max))
	//					if((LowTime >= (300/50)) && (LowTime <= (400/50)))	//数据1		360us/50us == 7
					{
						
						TempData[ReadLoop] |= 0x80000000>>BitCount;

						BitCount++;
					}
					else if((LowTime >= _32num0_us_min) && (LowTime <= _32num0_us_max))
	//					else if((LowTime > (900/50)) && (LowTime < (1200/50)))	//数据0		1084us/50us == 21
					{
						TempData[ReadLoop] &= ~(0x80000000>>BitCount);

						BitCount++;
					}
					else	//数据出错,重新接收
					{
						ReadStep = 0;
						BitCount = 0;
					}
					LowTime = 0;
										
				}
				else if(DataFram == 24)	//24 位数据解析
				{
					if((LowTime >= _24num1_us_min) && (LowTime <= _24num1_us_max))		//数据1		410us/50us == 8
					{
						
						TempData[ReadLoop] |= 0x80000000>>BitCount;

						BitCount++;
					}
					else if((LowTime >= _24num0_us_min) && (LowTime <= _24num0_us_max))		//数据0		1200us/50us == 24
					{
						TempData[ReadLoop] &= ~(0x80000000>>BitCount);

						BitCount++;
					}
					else	//数据出错,重新接收
					{
						ReadStep = 0;
						BitCount = 0;
					}
					LowTime = 0;
					
				}
				if(BitCount >= DataFram)	//数据接收完成
				{
					BitCount = 0;
					ReadLoop++;
					if(ReadLoop < 2)	//接收数据少于 2 组
					{
						ReadStep = 0;	//重新读取同步信号,读 2 组数据
						CheckTime = 100000/50;	//接收完第一组,开始倒计时,设置为 100ms 内
					}
					else	//已经读取两组了
					{
						ReadLoop = 0;
						ReadStep = 2;
					}
					
				}
				
				if(ReadLoop==1)		//只读取到一组数据
				{
					CheckTime--;	//校验倒计时,规定时间内没收到第二组,就是校验失败,需要重新接收
					if(CheckTime == 0)
					{
						ReadLoop = 0;
						ReadStep = 0;
					}
				}
					
			}
			if(ReadStep == 2)	//接收完成,处理数据
			{
				
				if(TempData[0] == TempData[1])  	//收到连续两组相同的数据,再开始解析
				{
					if(DataFram == 32)	//32 位数据解析
					{
						rf_data32[0] = TempData[0]>>24;
						rf_data32[1] = TempData[0]>>16;
						rf_data32[2] = TempData[0]>>8;
						rf_data32[3] = TempData[0]>>0;
						decode32_ok = 1;
						RfDuty_32Bit();	//黑色遥控器任务函数,这里也可以在主函数里检测decode32_ok 标志位调用
						
					}
					else if(DataFram == 24)	//24 位数据解析
					{
						rf_data24[0] = TempData[0]>>24;
						rf_data24[1] = TempData[0]>>16;
						rf_data24[2] = TempData[0]>>8;
						decode24_ok = 1;
						RfDuty_24Bit();	//棕色遥控器任务函数
					}
				}

				ReadStep = 0;
				DataFram = 0;
			}
		}
	}	
}

//----------------------------------------------------------------------------------------------
//任务函数
void RfDuty_32Bit(void)
{
decode32_ok = 0;
	if(rf_data32[3] == 0x08)
		printf("黑色钥匙上三角\r\n");
	else if(rf_data32[3] == 0x01)	
		printf("黑色钥匙下三角\r\n");
	else if(rf_data32[3] == 0x04)	
		printf("黑色钥匙方块\r\n");
	else if(rf_data32[3] == 0x02)	
		printf("黑色钥匙圆\r\n");	
}


void RfDuty_24Bit(void)
{
Decode24_ok = 0;
	if(rf_data24[2] == 0x74)
		printf("棕色钥匙上三角\r\n");
	else if(rf_data24[2] == 0x78)	
		printf("棕色钥匙下三角\r\n");
	else if(rf_data24[2] == 0x71)	
		printf("棕色钥匙锁\r\n");
	else if(rf_data24[2] == 0x72)	
		printf("棕色钥匙方块\r\n");	
}

//--------------------------------------------------------------------------
//main函数

int main(void)
{	
  

	uart_init(115200); 
	RF433_Init();
	
	printf("433遥控器\r\n");

	while(1)
	{

			
	}
}


 

3、定时器输入捕获方式解析数据

        定时器输入捕获的编程思路跟扫描方式很相似,只是把检测低电平时间的任务交给了定时器,不再用扫描的方式对变量累加,本文使用定时器5的通道1。定时器的计数部分配置为1us中断,配置过程跟上面类似,这里主要注意定时器输入捕获的一些参数。

        TIM_ICInitTypeDef  TIM5_ICInitStructure;

        //初始化TIM5输入捕获参数

        TIM5_ICInitStructure.TIM_Channel = TIM_Channel_1; //CC1S=01 选择输入端 IC1映射到TI1上

        TIM5_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling; //下降沿捕获

        TIM5_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上

        TIM5_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;  //配置输入分频,不分频

        TIM5_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 配置输入滤波器 不滤波

        TIM_ICInit(TIM5, &TIM5_ICInitStructure);

        第一个参数是选择通道,选择通道1就行了。

        第二个是选择上升沿还是下降沿捕获,因为要捕获低电平所以先设置为下降沿捕获,在检测到下降沿后清0定时器的计数值,再更改为上升沿捕获,这样在捕获到上升沿时,定时器的计数值就是低电平的持续时间。

        第三个参数是映射,IC1可以映射到TI1,也可以映射到TI2,选择TI1就好(这里个人理解,如果映射到TI1,那么定时器的通道一电平跳变时触发捕获中断,如果映射到二,那么定时器通道二电平跳变时触发捕获中断)。

        第四个是分频,可以设置检测到几个上升沿才算做一个有效上升沿,如果设置为8,就是连续8个上升沿才记一次,这里不分频,就是每一个上升沿进入中断。

        第五个参数是滤波,检测到上升沿后,进行一些时钟周期的延迟,如果一直保持高电平,才算有效上升沿,把一些持续时间短的信号滤掉,这里不滤波,检测到高电平立刻进入中断。

源码:

//---------------------------------------------------------------------------------------

//宏定义和变量说明



#define h_24start_us_min 208 //24Bit格式 同步信号 高电平参考值 408us

#define h_24start_us_max 608

#define h_24num0_us_min 210 //24Bit格式数据'0'高电平持续时间参考值 410us

#define h_24num0_us_max     610

#define h_24num1_us_min     1000 //24Bit格式数据'1'高电平持续时间参考值 1200us

#define h_24num1_us_max     1400



#define l_24start_us_min 11400 //24Bit格式 同步信号 低电平参考值 12400us

#define l_24start_us_max 13400

#define l_24num0_us_min 1000 //24Bit格式数据'0'低电平持续时间参考值 1200us

#define l_24num0_us_max 1400

#define l_24num1_us_min 200 //24Bit格式数据'1'低电平持续时间参考值 410us

#define l_24num1_us_max 600



#define h_32start_us_min 164 //32Bit格式 同步信号 高电平持续时间参考值 364us

#define h_32start_us_max 564

#define h_32num0_us_min 162 //32Bit格式 数据'0' 高电平持续时间参考值 362us

#define h_32num0_us_max 562

#define h_32num1_us_min 884 //32Bit格式 数据'1' 高电平持续时间参考值 1084us

#define h_32num1_us_max 1284



#define l_32start_us_min 7000 //32Bit格式 同步信号 低电平持续时间参考值 8000us

#define l_32start_us_max 9000

#define l_32num0_us_min 884 //32Bit格式 数据'0' 低电平持续时间参考值 1084us

#define l_32num0_us_max 1284

#define l_32num1_us_min 160 //32Bit格式 数据'1' 低电平持续时间参考值 360us

#define l_32num1_us_max 560





/*

变量说明:

DataFram     数据帧格式  24位或者32位

BitCount     记录当前接收了多少位数据



decode32_ok 32位格式数据解析成功

decode24_ok 24位格式数据解析成功

ReadLoop 读数据的次数 需要循环两次读两组数据

CheckTime 校验计时 接收完第一组数据后,开始倒计时,如果100ms内没有接收到第二组数据,则解析失败,回到开始重新接收数据



TempData[2]; 存放临时数据

rf_data32[4]; 存放解析成功的32位格式数据,数组前几位存放地址值,最后一位存放数据值

rf_data24[3]; 存放解析成功的24位格式数据



*/

unsigned char DataFram,BitCount,decode32_ok,decode24_ok,ReadLoop;

unsigned int CheckTime;

unsigned int TempData[2] = {0};

unsigned char rf_data32[4] = {0};

unsigned char rf_data24[3] = {0};



/*TIM5CH1_CAPTURE_STA

Bit7 Bit6 Bit5 Bit4~Bit0

捕获完成 同步码 下降沿 保留

*/

u8  TIM5CH1_CAPTURE_STA=0; //输入捕获状态     

u16 TIM5CH1_CAPTURE_LVAL; //记录低电平持续时间

u16 TIM5CH1_CAPTURE_HVAL;





//---------------------------------------------------------------------------------------

//初始化

void RF433_Init(void)

{

TIM5_Cap_Init(0xFFFF,71);//72分频   72MHZ经过分频变成1MHZ,1us中断1次

}



void TIM5_Cap_Init(u16 arr,u16 psc)

{  

GPIO_InitTypeDef GPIO_InitStructure;

TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

    NVIC_InitTypeDef NVIC_InitStructure;

TIM_ICInitTypeDef  TIM5_ICInitStructure;



RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE); //使能TIM5时钟

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  //使能GPIOA时钟



GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_0;  //PA0 清除之前设置  

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0 输入  

GPIO_Init(GPIOA, &GPIO_InitStructure);

GPIO_ResetBits(GPIOA,GPIO_Pin_0);



//初始化定时器5 TIM5  

TIM_TimeBaseStructure.TIM_Period = arr; //设定计数器自动重装值

TIM_TimeBaseStructure.TIM_Prescaler =psc; //预分频器   

TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式

TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位

  

//初始化TIM5输入捕获参数

TIM5_ICInitStructure.TIM_Channel = TIM_Channel_1; //CC1S=01 选择输入端 IC1映射到TI1上

   TIM5_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling; //下降沿捕获

   TIM5_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上

   TIM5_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;  //配置输入分频,不分频

   TIM5_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 配置输入滤波器 不滤波

   TIM_ICInit(TIM5, &TIM5_ICInitStructure);



//中断分组初始化

NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;  //TIM3中断

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;  //先占优先级2级

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  //从优先级0级

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能

NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器



TIM_ITConfig(TIM5,TIM_IT_Update|TIM_IT_CC1,ENABLE);//允许更新中断 ,允许CC1IE捕获中断



    TIM_Cmd(TIM5,ENABLE ); //使能定时器5



}



//---------------------------------------------------------------------------------------

//中断服务函数

//定时器5中断服务程序  

void TIM5_IRQHandler(void)

{

if (TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET)

{     



}



if (TIM_GetITStatus(TIM5, TIM_IT_CC1) != RESET)//捕获1发生捕获事件

{



if(TIM5CH1_CAPTURE_STA&0x20) //第二步,捕获上升沿

{   

TIM5CH1_CAPTURE_STA &= ~0x20;

TIM5CH1_CAPTURE_LVAL = TIM_GetCapture1(TIM5); //读取低电平持续的时间



TIM_SetCounter(TIM5,0);

TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Falling); //准备捕获下降沿



if(TIM5CH1_CAPTURE_STA&0x40) //如果接收到了同步码

{

if(DataFram == 32) //32 位数据解析

{

if((TIM5CH1_CAPTURE_LVAL >= l_32num1_us_min) && (TIM5CH1_CAPTURE_LVAL <= l_32num1_us_max) && (TIM5CH1_CAPTURE_HVAL >= h_32num1_us_min) && (TIM5CH1_CAPTURE_HVAL <= h_32num1_us_max)) //数据1

{

TempData[ReadLoop] |= 0x80000000>>BitCount;

BitCount++;

}

else if((TIM5CH1_CAPTURE_LVAL >= l_32num0_us_min) && (TIM5CH1_CAPTURE_LVAL <= l_32num0_us_max) && (TIM5CH1_CAPTURE_HVAL >= h_32num0_us_min) && (TIM5CH1_CAPTURE_HVAL <= h_32num0_us_max)) //数据0

{

TempData[ReadLoop] &= ~(0x80000000>>BitCount);

BitCount++;

}

else //数据出错,重新接收

{

TIM5CH1_CAPTURE_STA &= ~0x40; //重新读取同步信号

BitCount = 0;

}



}

else if(DataFram == 24) //24 位数据解析

{

if((TIM5CH1_CAPTURE_LVAL >= l_24num1_us_min) && (TIM5CH1_CAPTURE_LVAL <= l_24num1_us_max) && (TIM5CH1_CAPTURE_HVAL >= h_24num1_us_min) && (TIM5CH1_CAPTURE_HVAL <= h_24num1_us_max)) //数据1

{

TempData[ReadLoop] |= 0x80000000>>BitCount;

BitCount++;

}

else if((TIM5CH1_CAPTURE_LVAL >= l_24num0_us_min) && (TIM5CH1_CAPTURE_LVAL <= l_24num0_us_max) && (TIM5CH1_CAPTURE_HVAL >= h_24num0_us_min) && (TIM5CH1_CAPTURE_HVAL <= h_24num0_us_max)) //数据0

{

TempData[ReadLoop] &= ~(0x80000000>>BitCount);

BitCount++;

}

else //数据出错,重新接收

{

TIM5CH1_CAPTURE_STA &= ~0x40; //重新读取同步信号

BitCount = 0;

}



}

if(BitCount >= DataFram) //黑色钥匙 32 位数据

{

BitCount = 0;

ReadLoop++;

if(ReadLoop < 2) //接收数据少于 2 组

{

TIM5CH1_CAPTURE_STA &= ~0x40; //重新读取同步信号,读 2 组数据

CheckTime = 100000; //接收完第一组,开始倒计时,设置为 100ms 内

}

else //已经读取两组了

{

ReadLoop = 0;

TIM5CH1_CAPTURE_STA |= 0x80; //标记读取数据完成

rf433_decode();

}



}

if(ReadLoop==1) //读取到一组数据,等待第二组,倒计时

{

CheckTime--; //校验倒计时,规定时间内没收到第二组,就是校验失败,需要重新接收

if(CheckTime == 0)

{

ReadLoop = 0;

TIM5CH1_CAPTURE_STA &= ~0x40; //重新读取同步信号

}

}



}

else //没有收到同步码

{

if((TIM5CH1_CAPTURE_LVAL >= l_32start_us_min) && (TIM5CH1_CAPTURE_LVAL <= l_32start_us_max) && (TIM5CH1_CAPTURE_HVAL >= h_32start_us_min) && (TIM5CH1_CAPTURE_HVAL <= h_32start_us_max))

{

DataFram = 32;//32 位数据格式,黑色钥匙

TIM5CH1_CAPTURE_STA |= 0x40; //标记收到了同步码

}

else if((TIM5CH1_CAPTURE_LVAL >= l_24start_us_min) && (TIM5CH1_CAPTURE_LVAL <= l_24start_us_max) && (TIM5CH1_CAPTURE_HVAL >= h_24start_us_min) && (TIM5CH1_CAPTURE_HVAL <= h_24start_us_max))

{

DataFram = 24;//24 位数据格式,棕色钥匙

TIM5CH1_CAPTURE_STA |= 0x40;

}

}

TIM5CH1_CAPTURE_HVAL=0;



}

else   //第一步,捕获下降沿

{

TIM5CH1_CAPTURE_HVAL = TIM_GetCapture1(TIM5); //读取高电平持续的时间

TIM5CH1_CAPTURE_LVAL=0;

TIM_SetCounter(TIM5,0);

TIM5CH1_CAPTURE_STA|=0X20; //标记捕获到了下降沿

TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Rising); //准备捕获上升沿

}

    

}

 

    TIM_ClearITPendingBit(TIM5, TIM_IT_CC1|TIM_IT_Update); //清除中断标志位



}





//---------------------------------------------------------------------------------------

//解码函数和任务函数



void rf433_decode(void)

{

if(TIM5CH1_CAPTURE_STA | 0x80) //接收到一次完整数据,开始解码

{

if(TempData[0] == TempData[1])   //收到连续两组相同的数据,再开始解析

{

if(DataFram == 32) //32 位数据解析

{

rf_data32[0] = TempData[0]>>24;

rf_data32[1] = TempData[0]>>16;

rf_data32[2] = TempData[0]>>8;

rf_data32[3] = TempData[0]>>0;

decode32_ok = 1;

RfDuty_32Bit();

}

else if(DataFram == 24) //24 位数据解析

{



rf_data24[0] = TempData[0]>>24;

rf_data24[1] = TempData[0]>>16;

rf_data24[2] = TempData[0]>>8;

decode24_ok = 1;

RfDuty_24Bit();

}

}

TIM5CH1_CAPTURE_STA = 0;//状态标志位清0

DataFram = 0;

}

}



void RfDuty_32Bit(void)

{

decode32_ok = 0;

if(rf_data32[3] == 0x08)

printf("黑色钥匙上三角\r\n");

else if(rf_data32[3] == 0x01)

printf("黑色钥匙下三角\r\n");

else if(rf_data32[3] == 0x04)

printf("黑色钥匙方块\r\n");

else if(rf_data32[3] == 0x02)

printf("黑色钥匙圆\r\n");

}





void RfDuty_24Bit(void)

{

decode24_ok = 0;

if(rf_data24[2] == 0x74)

printf("棕色钥匙上三角\r\n");

else if(rf_data24[2] == 0x78)

printf("棕色钥匙下三角\r\n");

else if(rf_data24[2] == 0x71)

printf("棕色钥匙锁\r\n");

else if(rf_data24[2] == 0x72)

printf("棕色钥匙方块\r\n");

}

 //---------------------------------------------------------------------------------------

//运行结果

  • 18
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值