应用场景
#ifndef __RED_H
#define __RED_H
#include "main.h"
#define RDATA PDin(4) //红外数据输入脚
#define IR_IN GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_4) // PC3 红外接收DQ引脚
//红外遥控识别码(ID),每款遥控器的该值基本都不一样,但也有一样的.
//我们选用的遥控器识别码为0
#define REMOTE_ID 0
extern u8 ir_code[4]; // 解码值保存变量
extern u8 ir_decode_ok_flag; // 解码成功标志位
void ALR_Remote_Init(void); //红外传感器接收头引脚初始化
void Ir_Decode(void);
#endif
#include "remote.h"
u8 ir_code[4]; // 解码值保存变量
u8 ir_decode_ok_flag = RESET; // 解码成功标志位
//红外遥控初始化
//设置IO以及定时器4的输入捕获
void ALR_Remote_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Schmit = GPIO_Schmit_Disable;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOD, &GPIO_InitStructure);
}
/*
NEC红外编码: 引导码 + 地址码 + 地址码(取反) + 数据 + 数据(取反)
引导吗:0.56ms(低电平) + 2.25ms(高电平)
数据1: 0.56ms(低电平) + 1.12ms(高电平)
*/
// 红外解码程序,100us定期执行就可以了
void Ir_Decode(void)
{
static unsigned char l_cnt = 0; // 低电平时间计数
static unsigned char h_cnt = 0; // 高电平时间计数
static unsigned char l_cnt_save = 0; // 保存低电平时长
static unsigned char h_cnt_save = 0; // 保存高电平时长
static unsigned char falling_edge_valid_flag = RESET; // IR电平由高变低标志位
static unsigned char rcv_sync_ok_flag = RESET; // 同步码接收成功标志位
static unsigned char bit_value = 0; // 位解码值
static unsigned char bit_rcv_cnt = 0; // 位接收个数变量
if( RESET == IR_IN )
{
if( 0 == l_cnt ) // IR由高变低后立马记录上次测得的高电平时长
{
h_cnt_save = h_cnt;
falling_edge_valid_flag = SET;
}
l_cnt ++;
if( l_cnt > 250 ) // 防止计数溢出
{
l_cnt = 250;
}
h_cnt = 0; // 计数清零
}
else
{
if( 0 == h_cnt ) // IR由低变高后立马记录上次测得的低电平时长
{
l_cnt_save = l_cnt;
}
h_cnt ++;
if( h_cnt > 250 ) // 防止计数溢出
{
h_cnt = 250;
}
l_cnt = 0; // 计数清零
}
if( SET == falling_edge_valid_flag )
{
falling_edge_valid_flag = RESET;
/* 位解码 */
if( ((l_cnt_save >= 3)&&(l_cnt_save <= 9)) && // 560us低电平, 560us高电平
((h_cnt_save >= 3)&&(h_cnt_save <= 9)) )
{
bit_value = 0;
}
else if( ((l_cnt_save >= 3)&&(l_cnt_save <= 9)) && // 560us低电平,1680us高电平
((h_cnt_save >= 14)&&(h_cnt_save <= 20)) )
{
bit_value = 1;
}
else
{
bit_value = 2;
}
if( SET == rcv_sync_ok_flag )
{
if((1 == bit_value) || (0 == bit_value) )
{
if( bit_rcv_cnt < 8 )
{
ir_code[0] |= (bit_value<< (bit_rcv_cnt%8));
}
else if( bit_rcv_cnt < 16 )
{
ir_code[1] |= (bit_value<< (bit_rcv_cnt%8));
}
else if( bit_rcv_cnt < 24 )
{
ir_code[2] |= (bit_value<< (bit_rcv_cnt%8));
}
else if( bit_rcv_cnt < 32 )
{
ir_code[3] |= (bit_value<< (bit_rcv_cnt%8));
}
if( bit_rcv_cnt >= 31 )
{
ir_decode_ok_flag = SET;
rcv_sync_ok_flag = RESET;
}
bit_rcv_cnt ++;
}
else
{
rcv_sync_ok_flag = RESET; // 位接收错误,重新解码
}
}
if( ((l_cnt_save >= 87)&&(l_cnt_save <= 93)) &&
((h_cnt_save >= 42)&&(h_cnt_save <= 48)) ) // 同步码,4.5ms低电平,4.5ms高电平
{
rcv_sync_ok_flag = SET;
bit_rcv_cnt = 0;
ir_code[0] = 0;
ir_code[1] = 0;
ir_code[2] = 0;
ir_code[3] = 0;
}
}
}