一、NEC红外线协议与接收头介绍
红外线遥控是家电领域里很常见的一种遥控方式,常见的电视机、空调、投影机等设备基本都支持红外线遥控;这也主要是红外线遥控成本比较低,现在很多电视机也支持蓝牙遥控器了,穿透性、速度、比红外线遥控要好很多。
红外线遥控的原理: 就是通过红外光的闪烁传递数据,需要一对红外线发射管、一个红外线接收头。 这个红外线接收头对红外光很敏感,接收到红外光就输出低电平,相反就是高电平。所以可以通过这个原理就可以通过与遥控器端、接收端约定协议就能传递数据了。
二、解码实现代码
红外线协议有很多,下面就以NEC协议为例: NEC协议分为: 引导码、用户码、用户反码、按键码、按键反码组成。 引导码是9ms低电平+4.5毫秒高电平组成。 数据位一共32位。也就是个字节。对应上面说的后4个数据位。
数据1表示:0.56ms低电平+1.68ms高电平 数据0表示:0.56ms低电平+0.56ms低电平。
红外线解码思路在M4上面实现有两种方式(其实本质是一样的):
通过定时器输入捕获方式
通过定时器+外部中断的方式
下面的代码就是采用定时器捕获+外部中断方式实现解码。
2.1 main.c代码
#include 'stm32f4xx.h' // Device header
#include 'led.h'
#include 'delay.h'
#include 'key.h'
#include 'usart.h'
#include 'sys.h'
#include 'exti.h'
#include 'timer.h'
#include 'pwm.h'
#include 'ds18b20.h'
#include 'infrared.h'
extern u8 InfraredRxBuff[5];
int main(void)
{
LED_Init();
KEY_Init();
USART1_Init(84,115200);
KEY_EXTI_Init();
DS18B20_Init();
InfraredRxInit(); //红外线解码初始化
while(1)
{
if(InfraredRxBuff[4])
{
InfraredRxBuff[4]=0; //清除接收成功标志
printf('USER=0x%xrn',InfraredRxBuff[0]);
printf('KEY=0x%xrn',InfraredRxBuff[2]);
LED0=0;
DelayMs(100);
LED0=1;
}
}
}
复制代码
2.2 解码核心代码
复制
#include 'infrared.h'
/*
函数功能:红外线解码初始化
硬件连接:PA8
定 时 器:使用TIM2
*/
void InfraredRxInit(void)
{
/*1. 开时钟*/
RCC->AHB1ENR|=1<<0;//使能PORTA时钟
/*2. 配置GPIO口模式*/
GPIOA->MODER&=~(0x3<<8*2); //清除模式
GPIOA->MODER|=0x0<<8*2; //配置输入模式
/*3. 开启SYSCFG时钟 */
RCC->APB2ENR|=1<<14;
/*4. 开放来自线x上的中断请求*/
EXTI->IMR|=1<<8; //中断线8
/*3. 配置中断线触发边沿*/
EXTI->FTSR|=1<<8; //下降沿
/*4. 配置产生中断的对应IO口*/
SYSCFG->EXTICR[2]&=~(0xf<<0*4);
SYSCFG->EXTICR[2]|=0x0<<0*4;
/*5. 配置中断优先级*/
SetNVICPriorityGrouping(EXTI9_5_IRQn,1,1);
/*6. 初始化定时器*/
RCC->APB1ENR|=1<<0; //开启定时器2的时钟
RCC->APB1RSTR|=1<<0; //开启复位时钟
RCC->APB1RSTR&=~(1<<0); //关闭
TIM2->PSC=84; //预分频
TIM2->ARR=65535; //重装载寄存器
TIM2->CR1&=~(1<<0); //开启计数器
}
/*
函数功能:获取高电平持续的时间
返 回 值:高电平持续的时间
*/
u32 GetInfraredRxH(void)
{
TIM2->CR1|=1<<0;
TIM2->CNT=0;
while(INFRARED_RX){}
TIM2->CR1&=~(1<<0);
return TIM2->CNT;
}
/*
函数功能:获取低电平持续的时间
返 回 值:低电平持续的时间
*/
u32 GetInfraredRxL(void)
{
TIM2->CR1|=1<<0;
TIM2->CNT=0;
while(!INFRARED_RX){}
TIM2->CR1&=~(1<<0);
return TIM2->CNT;
}
/*
函数功能:外部中断线0中断服务函数
NEC协议解码原理:
1. 先接收引导码:9ms低电平+4.5ms高电平
2. 引导码之后,是连续的32位数据。用户码+用户反码+按键码+按键反码
3. 数据‘0’ :560us低电平+560us高电平
4. 数据‘1’ :560us低电平+1680us高电平
*/
u8 InfraredRxBuff[5]={0}; //存放红外线接收的数据值,其中[4]表示标志位。=0失败,=1成功
void EXTI9_5_IRQHandler(void)
{
u32 time,j,i;
u8 data=0;
EXTI->PR|=1<<0; //清除中断标志位
/*1. 判断引导码*/
time=GetInfraredRxL(); //获取低电平的时间
if(time<5000||time>11000)return;
time=GetInfraredRxH();
if(time<2500||time>5500)return;
/*2. 接收用户码和按键码*/
for(i=0;i<4;i++)
{
for(j=0;j<8;j++)
{
time=GetInfraredRxL(); //获取低电平的时间
if(time<360||time>660)return;
time=GetInfraredRxH(); //获取高电平的时间
//560us高电平 0 、 1680us高电平 1
if(time>360&&time<660)
{
data>>=1;
}
else if(time>1480&&time<1880)
{
data>>=1;
data|=0x80; //1000 0000
}
}
InfraredRxBuff[i]=data;
}
InfraredRxBuff[4]=1; //标志红外线解码成功
}
#ifndef _INFRARED_H
#define _INFRARED_H
#include 'stm32f4xx.h'
#include 'sys.h'
void InfraredRxInit(void);
u32 GetInfraredRxH(void);
u32 GetInfraredRxL(void);
#define INFRARED_RX PAin(8) //红外线的接收口
#endif
上一篇:总结STM32控制中常见的PID算法 理解万能的PID算法
下一篇:ESP8266应用案例 基于STM32核心板获取网络天气数据
推荐阅读最新更新时间:2026-03-25 10:55
- 用于 7VIN 至 16VIN、1.5V 和 1.2V 输出的 LTM4628EV DC/DC 模块稳压器的典型应用电路
- 使用 Analog Devices 的 LTC3728LIGN 的参考设计
- DER-406 - 适用于 A19 灯的 5.76 W 高 PF 非隔离降压-升压型 TRIAC 调光 LED 驱动器
- ADR5045B 5V 输出精密微功率并联模式电压基准的典型应用
- LT3970EDDB-3.42 2.5V 降压转换器的典型应用
- MC78M08BDTG 8V 电流调节器的典型应用
- LT1021DCN8-5 精密电压基准的典型应用
- DER-282 - 100W, 扁平(11 mm), LLC DC-DC转换器
- REF193 低压差开尔文连接电压基准的典型应用电路
- LT3088EM 线性稳压器用于添加软启动的典型应用

立晶CL1009S音频编解码IC手册和驱动代码
codec2_一个高效率的音频编解码开源库
ES4408_DVD解码板电路图
非常经典的关于LLC的杨波博士论文
XC6406PP60DL






京公网安备 11010802033920号