一、前期准备
单片机:STM32F103ZET6
开发环境:MDK5.14
库函数:STM32Cube_FW_F1_V1.7.0
红外遥控器:淘宝有售 )
二、实验效果
三、驱动原理
解析NEC协议,使用TIM2输入捕获抓取高低电平时间,判断0或者1,识别传输过来的码流。
CubeMX TIM2配置如下:
需要完整工程的请加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;
}
}
}
}
由于作者能力有限,有不妥之处欢迎指正,邮箱alex_hua@foxmail.com