红外遥控模块的使用方法,以及stm32代码

本文详细介绍了使用STM32F103R8T6单片机配合STM32CubeMX实现红外遥控串口通讯的过程,包括红外编码的基本原理、NEC编码格式,以及红外遥控模块的头文件和函数实现。重点展示了如何通过定时器捕获和PPM调制解调来实现数据的发送和接收。
摘要由CSDN通过智能技术生成

我使用的模块是stm32F103R8T6,配合STM32CudeMX实现的红外遥控串口通讯

一、 红外编码

1、实物设备

发射管,红外发光二极管,发出的是红外线而不是可见光,红外线波长为940nm左右。(在遥控器上面):
在这里插入图片描述
接收管是红外接收二极管VS1838B,在实际应用中要给红外接收二极管加反向偏压,它才能正常工作,亦即红外接收二极管在电路中应用时是反向运用,这样才能获得较高的灵敏度。和主控芯片具有定时器输入捕获功能的I/O引脚连接在一起:
在这里插入图片描述
遥控器:
在这里插入图片描述

2、基本原理

调制:将数据能够发送更远,并且数据的损耗在合理范围内,大致过程如下1–》2–》3。
解调:将接收到的已调数据重新恢复并获取出来,大致过程如下的3–》2–》1。
在这里插入图片描述
红外通信是利用950nm近红外波段的红外线作为传递信息的媒体, 即通信信道。
发送端采用脉时调制(PPM) 方式, 将二进制数字信号调制成某一频率的脉冲序列, 并驱动红外发射管以光脉冲的形式发送出去;
接收端将接收到的光脉转换成电信号, 再经过放大、 滤波等处理后送给解调电路进行解调, 还原为二进制数字信号后输出。
简而言之, 红外通信的实质就是对二进制数字信号进行调制与解调, 以便利用红外信道进行传输, 红外通信接口就是针对红外信道的调制解调器。
特点:
红外遥控的特点是不影响周边环境、不干扰其它电器设备。由于其无法穿透墙壁,故不同房间的家用电器可使用通用的遥控器而不会产生相互干扰;电路调试简单,只要按给定电路连接无误,一般不需任何调试即可投入工作;编解码容易,可进行多路遥控。因此,红外遥控在家用电器、室内近距离(小于10米)遥控中得到了广泛的应用。

3、红外编码原理

NEC编码原理(还有一种Philips RC5协议)
NEC格式的特征:
1:使用38 kHz载波频率
2:引导码间隔是9 ms + 4.5 ms
3:使用16位客户代码
4:使用8位数据代码和8位取反的数据代码
NEC编码的一帧(通常按一下遥控器按钮所发送的数据) 由引导码、 地址码及数据码组成,如下图所示, 把地址码及数据码取反的作用是加强数据的正确性。
在这里插入图片描述
NEC 协议通过脉冲串之间的时间间隔来实现信号的调制(英文简写PPM)。逻辑“0”是由0.56ms的38KHZ载波和0.560ms的无 载波间隔组成;逻辑“1”是由0.56ms的38KHZ载波和1.68ms的无载波间隔组成;结束位是0.56ms的38K载波。

二、红外遥控模块程序

1、红外遥控模块头文件

//红外遥控模块头文件
#ifndef __IR_H
#define __IR_H
#include "main.h"
#define IR_TIM						TIM2
#define MAX_DATALEN 5
typedef struct{
	uint8_t mode;
	uint8_t Ir_Data[MAX_DATALEN];
	uint16_t Ir_Length;
}IR_DATA_TypeDef;
extern uint8_t IR_code;
uint8_t Ir_RecvAnalysis(void);
#endif

2、红外遥控模块函数实现代码

//红外遥控模块函数实现代码
#include "ir.h"

#define RCKeyNum 		17
#define RCIRLength 	4

uint8_t IR_key[17] ="123456789*0#+LOR-";

uint8_t RemoteControl_Table[RCKeyNum][RCIRLength] = {
	{0x00,0xFF,0x45,0xBA},
	{0x00,0xFF,0x46,0xB9},
	{0x00,0xFF,0x47,0xB8},	
	{0x00,0xFF,0x44,0xBB},	
	{0x00,0xFF,0x40,0xBF},	
	{0x00,0xFF,0x43,0xBC},	
	{0x00,0xFF,0x07,0xF8},	
	{0x00,0xFF,0x15,0xEA},	
	{0x00,0xFF,0x09,0xF6},	
	{0x00,0xFF,0x16,0xE9},	
	{0x00,0xFF,0x19,0xE6},	
	{0x00,0xFF,0x0D,0xF2},		
	{0x00,0xFF,0x18,0xE7},		
	{0x00,0xFF,0x08,0xF7},	
	{0x00,0xFF,0x1C,0xE3},	
	{0x00,0xFF,0x5A,0xA5},		
	{0x00,0xFF,0x52,0xAD},		
};

uint16_t ir_buf[1024] = {0};
uint16_t ir_count = 0;
uint16_t ir_flag = 0;

	
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim==&htim2)
	{
		ir_flag = 1;
		Ir_RecvAnalysis();	//接收红外信号
	}
}


void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2 )
	{
		if(ir_flag == 0)
		{
			ir_buf[ir_count++] = IR_TIM->CCR2;
			__HAL_TIM_SET_COUNTER(&htim2,0);
			IR_TIM->CCER ^= (1<<5);				
		}	
}
}



//判断数据范围函数
//数据在给定的范围之内:返回1
//数据在给定的范围之外:返回0
//time1:待判断时间
//time2:标准时间
uint8_t Time_Range(uint16_t time1, uint16_t time2, uint16_t range1, uint16_t range2)
{
	if((time1 > (time2-range1)) && (time1 < (time2+range2)))
		return 1;
	else 
		return 0;
}

//校验遥控器按键
//正确,返回遥控器按键所对应的数组行号
//错误 -1  按键地址错误 不是这个遥控器
//错误 -2  地址正确,但是当前版本遥控器没有这个按键值
int Check_RemoteControlKey(uint8_t *buff)
{
	uint8_t i=0;
	int retn;
//	if(buff[0] != RemoteControl_Table[0][0] || buff[1] != RemoteControl_Table[0][1])
	if((buff[0]!=0x00) || (buff[1]!=0xFF))
		retn = -1;//地址错误
	for(i=0; i<RCKeyNum; i++)
	{
		if((buff[2]==RemoteControl_Table[i][2]) && (buff[3]==RemoteControl_Table[i][3]))
		{
			retn = i;
			break;
		}
		
	}
	if(i>=RCKeyNum)	retn = -2;
	return retn;
}


//返回值 
//0 解析成功
//1 没有接收完成
//2 引导码错误
//3 前半段数据错误
//4 后半段数据错误

IR_DATA_TypeDef ir = {0};
uint8_t IR_code = 0XFF;
uint8_t Ir_RecvAnalysis(void)
{
	uint16_t i = 0;
	uint8_t err;
	if(ir_flag == 0) return 1;
//	for(i=0; i<ir_count; i++)
//		printf("%d\r\n",ir_buf[i]);
	
	if(Time_Range(ir_buf[1],9000,1000,1000) == 0){
		err = 2;
		goto error;
	}
	if(Time_Range(ir_buf[2],4500,500,500) == 0){
		err = 2;
		goto error;
	}
	for(i=3; i<ir_count-1; i++)
	{
		if(Time_Range(ir_buf[i],560,200,200))
		{
			i++;
			if(Time_Range(ir_buf[i],560,200,200))
			{
				//数据0  0-7  data[0]  8-15 data[1]
				//先收到低位保存到低位,也可以反着
				ir.Ir_Data[ir.Ir_Length/8] &= ~(1<<(ir.Ir_Length%8));
				ir.Ir_Length++;
			}
			else if(Time_Range(ir_buf[i],1690,200,200)==1)
			{
				//数据1
				ir.Ir_Data[ir.Ir_Length/8] |= (1<<(ir.Ir_Length%8));
				ir.Ir_Length++;
			}
			else{
				err = 4;
				goto error;
			}			
		}
		else{
			err = 3;
			goto error;
		}
	}
	
	
//	for(i=0; i<ir.Ir_Length/8; i++)
//	
//		printf("%02X\t",ir.Ir_Data[i]);
//	printf("\r\n");
	
	
	if(Check_RemoteControlKey(ir.Ir_Data) < 17 && Check_RemoteControlKey(ir.Ir_Data) >=0)
	{
		IR_code = IR_key[Check_RemoteControlKey(ir.Ir_Data)];
		memset(ir_buf,0,sizeof(ir_buf));
		memset(ir.Ir_Data,0,sizeof(ir.Ir_Data));
		ir.Ir_Length = 0;
		ir_count = 0;
		ir_flag = 0;
		return 0;
	}
		
error:
	memset(ir_buf,0,sizeof(ir_buf));
	memset(ir.Ir_Data,0,sizeof(ir.Ir_Data));
	ir.Ir_Length = 0;
	ir_count = 0;
	ir_flag = 0;
//	TIM_Cmd(TIM2,ENABLE);
	HAL_TIM_Base_Start_IT(&htim2);
	if(err)	return err;
	else	return 0;
}




使用STM32进行红外遥控时,可以通过使用红外线发射管和红外线接收头来发送和接收红外信号。在学习阶段,可以购买现成的模块来简化连接和接线的过程。具体的代码实现可以参考以下步骤: 1. 首先,需要配置STM32的GPIO引脚,将红外线发射管的DAT引脚连接到任意一个GPIO引脚上。如果想使用硬件PWM控制发送,可以将DAT引脚连接到PWM输出引脚上。 2. 在代码中,可以使用NEC协议来发送红外信号。NEC协议已经在之前的文章中详细介绍过。可以按照NEC协议的格式组织数据,并使用相应的红外发送函数发送数据。可以自定义数据来模拟家电遥控器,对不同设备进行遥控操作。 3. 在发送红外信号时,需要注意使用适当的延时函数来控制红外信号的时序。根据NEC协议的要求,发送的红外信号需要满足一定的时序要求。 综上所述,STM32红外遥控代码的实现主要包括配置GPIO引脚、使用NEC协议发送红外信号以及控制红外信号的时序。关于具体的代码实现细节,可以参考相关的教程或文档。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [STM32入门开发: 制作红外线遥控器(智能居家-万能遥控器)](https://blog.csdn.net/xiaolong1126626497/article/details/118313109)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

通信汪的美好生活

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值