STM32红外遥控器驱动(STM32F1 CubeMX)

一、前期准备
单片机:STM32F103ZET6
开发环境:MDK5.14
库函数:STM32Cube_FW_F1_V1.7.0
红外遥控器:淘宝有售 )
STM32红外遥控器驱动(STM32F1 CubeMX)_第1张图片
二、实验效果
STM32红外遥控器驱动(STM32F1 CubeMX)_第2张图片
三、驱动原理
解析NEC协议,使用TIM2输入捕获抓取高低电平时间,判断0或者1,识别传输过来的码流。

CubeMX TIM2配置如下:
STM32红外遥控器驱动(STM32F1 CubeMX)_第3张图片
需要完整工程的请加QQ:1002521871,验证:呵呵!

四、驱动代码
remote.h

#ifndef __REMOTE_H__
#define	__REMOTE_H__
#include "stm32f1xx_hal.h"
#include "user_gpio.h"
extern TIM_HandleTypeDef htim2;

#define 	Remote	 	PAin(1)	 
		   
extern uint8_t RmtCnt;			//按键按下的次数

uint8_t Remote_Scan(void);	   

extern void RemoteConfiguration(void);
extern uint16_t Remote_GetPressCode(void);
#endif

remote.c

#include "remote.h"

/*
	NEC协议:
		数据格式	:同步码头 + 地址码 +地址反码 + 按键码 + 按键反码 (LSB先行)
		同步码头	:9ms低电平 + 4.5ms高电平
		连发码 	:9ms低电平 + 2.5ms高电平
		逻辑1	:560us  +  1680us
		逻辑0	:560us  +  560us
*/
uint32_t RmtRec = 0;
uint8_t Remote_Press_Flag = 0;
uint16_t fallingCnt = 0;
uint8_t risingFlag = 0;
uint8_t synchronization = 0;

uint8_t RemoteDealFlag = 0;
uint8_t Timeout = 0;
uint8_t RmtCnt = 0;

void RemoteConfiguration(void)
{
	HAL_TIM_Base_Start(&htim2);
	HAL_TIM_Base_Start_IT(&htim2);
	HAL_TIM_IC_Start(&htim2, TIM_CHANNEL_2);
	HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_2);
}

uint16_t Remote_GetPressCode(void)
{
	uint16_t code = 0;
	if (RemoteDealFlag == 1)
	{
		if (((uint8_t)((RmtRec >> 8) & 0xFF) + (uint8_t)(RmtRec & 0xFF)) == 0xFF)
		{
			code = RmtRec % 65536;
			RemoteDealFlag= 0;
		}
		RmtCnt = 0;
	}
	return code;
}


void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
	if (htim->Instance == TIM2)
	{
		__HAL_TIM_CLEAR_FLAG(htim, TIM_FLAG_CC2);
		if(Remote)//上升沿捕获
		{
			__HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_2, TIM_INPUTCHANNELPOLARITY_FALLING);
			__HAL_TIM_SET_COUNTER(htim, 0);
			risingFlag = 1;
		}
		else
		{
			fallingCnt = __HAL_TIM_GET_COUNTER(htim);
			__HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_2, TIM_INPUTCHANNELPOLARITY_RISING);
			if (synchronization == 1)
			{
				if ((fallingCnt > 500) && (fallingCnt < 600))	//560 us
				{
					RmtRec <<= 1;
					RmtRec |= 0;
				}
				else if ((fallingCnt > 1600) && (fallingCnt < 1700))	//1680 us
				{
					RmtRec <<= 1;
					RmtRec |= 1;
				}
				else if ((fallingCnt > 2450) && (fallingCnt < 2550))	//2.5 ms
				{
					RmtCnt ++;
					Timeout = 0;
				}
				
			}
			else if ((fallingCnt > 4450) && (fallingCnt < 4550))	//4.5ms
			{
				synchronization = 1;
				RmtCnt = 0;
			}
			
			risingFlag = 0;
		}
	}
}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if (htim->Instance == TIM2)
	{
		__HAL_TIM_CLEAR_FLAG(htim, TIM_FLAG_UPDATE);
		if (synchronization == 1)
		{
			risingFlag = 0;
			if (Timeout < 14)
			{
				if (Timeout == 0)
				{
					RemoteDealFlag = 1;
				}
				Timeout ++;
			}
			else
			{
				synchronization = 0;
				Timeout = 0;
			}
			
		}
	}
}

由于作者能力有限,有不妥之处欢迎指正,邮箱[email protected]

你可能感兴趣的:(嵌入式通信模块驱动)