STM32接收红外遥控器的遥控信号

经过几天早晨的学习,终于把遥控器的红外信号给搞通了,特此记录一下;其实说白了,红外遥控就是高低电平的信号,用时间来区分是二进制的0还是1;然后把这些0或1,在组装成一个32位的数基本就算是完事了,最后程序里判断你按下的这个遥控按键的值是不是你预先设定的值就好了,执行自己想要的动作就OK了。

下面是NEC红外码的编码时序:

NEC 码的位定义: 一个脉冲对应 560us 的连续载波, 一个逻辑 1 传输需要2.25ms(560us 脉冲+1680us 低电平) , 一个逻辑 0 的传输需要 1.125ms(560us脉冲+560us 低电平) 。 而红外接收头在收到脉冲的时候为低电平, 在没有脉冲的时候为高电平, 这样, 我们在接收头端收到的信号为: 逻辑 1 应该是 560us 低+1680us 高, 逻辑 0 应该是 560us 低+560us 高。 所以可以通过计算高电平时间判断接收到的数据是 0 还是 1。

知道了0和1的编码方式,剩下的就简单了,发送的话就是控制一个IO口560us的低电平560us的高电平就是发送一个0. 控制IO口560us的低电平1680微妙的高电平就是发送一个1.

用个for循环发送8次就是发送了一个字节。还是很简单的。当然这个IO口外面需要接一个红外发光二极管,高电平的时候就点亮,低电平的时候就熄灭。

接收的时候也是一样,外面接一个红外接收二极管,红外接收二极管的一端接IO口,一端接地,这个IO口设置成上拉输入的模式,并开启下降沿中断,每次接收到红外信号后这个接收二极管就会导通,拉低IO口电平,也就会进入中断,在中断中统计时间就能区分出是0还是1了。由于不论是0还是1低电平的时间都是560us,所以只统计高电平的时间就能知道是0还是1了。这样就省去了一半的事情了。

还有就是NEC码还规定了最前面还有一个引导码,这也很简单的:

前面的低电平9ms,4.5ms的高电平就是引导码了,其余的32位不是0就是1了。整体的区分也是只需要区分高电平的时间就行了,4.5ms的是引导码,560us的是0,1680us的是1,还有就是时间上不用卡的那么死,毕竟晶振的震动频率也不见得就那么精准的,有点误差也很正常,所以判断的时候只要给个范围就好了:

比如说: 4ms到5ms的高电平就可以认为是引导码了

200us到800us的高电平就可以认为是数据0了

1000us到1800us的高电平就可以认为是数据1了

有了上面这些理论知识,编写程序就简单多了,先来看看统计高电平的函数要怎么写:

cs 复制代码
u8 HW_JSSJ(void) //红外接收时间的首字母
{
	u8 t=0;
	while(HWJS)  //HWJS红外接收是一个位带操作,查看连接红外就收二极管的IO的电平  如果是高电平进入
	{
		t++;
		Delay_us(20);           //t每次加1就延时20us
		if(t>=250) return t;   //如果大于了250,也就是5ms了,超出了NEC码中的最高的高电平时间了,再统计也没有什么意义了
	}
	return t;
}

有了统计高电平时间的统计函数,就可以写中断函数了,每次引导码时都是首先得低电平,所以就以低电平触发中断开始,进入中断就获取高电平时间,然后判断时间范围,是引导码就写个引导码的标志置1,是0或1就把0或1写入8位的变量中,还是直接看程序吧:打字太多了,懒了,5点半了,要去跑步了:

cs 复制代码
#include "hwjs.h"

void HWJS_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOB, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStruct);
	
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource12);
	EXTI_ClearITPendingBit(EXTI_Line12);
	
	EXTI_InitTypeDef EXTI_InitStruct;
	EXTI_InitStruct.EXTI_Line = EXTI_Line12;
	EXTI_InitStruct.EXTI_LineCmd = ENABLE;
	EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling;
	EXTI_Init(&EXTI_InitStruct);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	NVIC_InitTypeDef NVIC_InitStruct;
	NVIC_InitStruct.NVIC_IRQChannel = EXTI15_10_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStruct);
}

u8 HW_JSSJ(void) //红外接收时间的首字母
{
	u8 t=0;
	while(HWJS)  //HWJS红外接收是一个位带操作,查看连接红外就收二极管的IO的电平  如果是高电平进入
	{
		t++;
		Delay_us(20);           //t每次加1就延时20us
		if(t>=250) return t;   //如果大于了250,也就是5ms了,超出了NEC码中的最高的高电平时间了,再统计也没有什么意义了
	}
	return t;
}

u32 HWJSM=0;
u8 HW_JSBZ=0;

void EXTI15_10_IRQHandler(void)
{
	u8 time=0, YD=0, dat=0, Num=0;
	while(1)
	{
		if(HWJS)
		{
			time = HW_JSSJ();
			if(time >= 250) break;
			if(time >= 200 && time < 250)
			{
				YD=1;
			}
			else if(time >= 10 && time < 40)
			{
				dat = 0;
			}
			else if(time >= 50 && time < 90)
			{
				dat = 1;
			}
			if( YD )
			{
				HWJSM <<= 1;
				HWJSM |= dat;
				Num++;
				if(Num >= 31) 
				{
					HW_JSBZ = 1;
					break;
				}
			}
		}
	}
	EXTI_ClearITPendingBit(EXTI_Line12);
}

.h文件:

cs 复制代码
#ifndef _hwjs_H
#define _hwjs_H

#include "system.h"
#include "Delay.h"

extern u32 HWJSM;
extern u8 HW_JSBZ;

#define HWJS    PBin(12)



void HWJS_Init(void);


#endif

主函数:

cs 复制代码
#include "led.h"
#include "Serail1.h"
#include "OLED.h"
#include "hwjs.h"

u8 i=0;

int main(void)
{
	Serail1_Init();
	Serail2_Init();
	led_Init();
	OLED_Init();
	HWJS_Init();
	

	while(1)
	{
		if(HW_JSBZ)
		{
			i++;
			OLED_ShowHexNum(1,1,HWJSM,8);
			OLED_ShowNum(2,1,i,3);
			HW_JSBZ=0;
			HWJSM=0;
		}
	}
}

手头上只有空调遥控器,也是能精准识别的,红外二极管也是随便淘宝的:

接收管长脚接地,短脚接IO口就能识别的,翻过了不行,总共就两种可能性,试试就出来了,很简单的。好了去跑步5公里走起!

相关推荐
智者知已应修善业1 小时前
【51单片机用数码管显示流水灯的种类是按钮控制数码管加一和流水灯】2022-6-14
c语言·经验分享·笔记·单片机·嵌入式硬件·51单片机
智商偏低7 小时前
单片机之helloworld
单片机·嵌入式硬件
青牛科技-Allen8 小时前
GC3910S:一款高性能双通道直流电机驱动芯片
stm32·单片机·嵌入式硬件·机器人·医疗器械·水泵、
森焱森10 小时前
无人机三轴稳定控制(2)____根据目标俯仰角,实现俯仰稳定化控制,计算出升降舵输出
c语言·单片机·算法·架构·无人机
白鱼不小白10 小时前
stm32 USART串口协议与外设(程序)——江协教程踩坑经验分享
stm32·单片机·嵌入式硬件
S,D11 小时前
MCU引脚的漏电流、灌电流、拉电流区别是什么
驱动开发·stm32·单片机·嵌入式硬件·mcu·物联网·硬件工程
芯岭技术14 小时前
PY32F002A单片机 低成本控制器解决方案,提供多种封装
单片机·嵌入式硬件
youmdt14 小时前
Arduino IDE ESP8266连接0.96寸SSD1306 IIC单色屏显示北京时间
单片机·嵌入式硬件
嘿·嘘15 小时前
第七章 STM32内部FLASH读写
stm32·单片机·嵌入式硬件
Meraki.Zhang15 小时前
【STM32实践篇】:I2C驱动编写
stm32·单片机·iic·驱动·i2c