【TM32HAL库--红外接收】

前言

红外遥控接收模块–基于HAL库,先读取其按键值,并通过串口将其显示出来,从而为进行按键操作其他器件奠定基础.

一. 产品介绍

这是一款新型的超薄 38K 通用红外遥控器,采用的是 NEC 编码格式,主要用于车载 MP3、足浴盆、灯光设配、 数码相框、单片机开发板和学习板等场合。因其是基于无线遥控,因此人们在使用起来显得方便、有效,现在的应用领域也越来越宽.在这里插入图片描述
在这里插入图片描述

(1). 技术参数

红外遥控距离:大于 8 米
发射管红外波长: 940Nm
晶振频率: 455KHZ 的晶振
载波频率: 38KHZ
编码:编码格式为 NEC
尺寸: 86* 40* 6mm
电源: CR2025/1600mAH

(2)使用说明

在使用前一定要记得给红外遥控器上电池,还有红外遥控器要结合红外接收模块使用, 它负责将接收红外遥控器发射过来的信息并将其解码成十六进制码,这样才能实现既定的通信。
将红外接收模块与 STM32正确连接, 其中 S 连接 D11, VCC 接+5V, GND 接 GND,并将其固定好;

二. NEC协议

当进行红外信号的发送和接收过程中,需要调制与解调信号,调制用在发送的过程中,解调用在接收的过程中NEC协议是红外遥控协议中的一种,协议构成由引导码,地址码,地址反码,命令码以及命令反码构成.

NEC功能特点包含:

1.地址码与地址反码,以及命令码与命令反码,具有数据校验作用,增强结果的准确性
2.脉冲距离调制,调制占空比
3.载波频率38KHZ
4.逻辑位时间为逻辑0:1.125ms或逻辑1:2.25ms
5.发送的信号与接收到的信号是反向的

在这里插入图片描述

NEC 码的位定义:一个脉冲对应 560us 的连续载波,一个逻辑 1 传输需要 2.25ms(560us脉冲+1680us 低电平),一个逻辑 0 的传输需要 1.125ms(560us 脉冲+560us 低电平)

NEC 遥控指令的数据格式为:同步码头、地址码、地址反码、控制码、控制反码。同步码由一个 9ms 的低电平和一个 4.5ms 的高电平组成,地址码、地址反码、控制码、控制反码均是8 位数据格式。按照低位在前,高位在后的顺序发送。采用反码是为了增加传输的可靠性(可用于校验)。

下图为接收到按键的值的波:
在这里插入图片描述

三 .CubeMX配置

使用了TIM2的输入捕获功能来读取红外接收器的输入信号

基本工程配置,参考上一篇文章,在此不演示.

在这里插入图片描述

四 . HAL库代码

(1)用到的变量

uint16_t Rmtsta=0;//二进制8位分别表示
uint16_t Dval=0;
uint16_t Rmtrec=0;
uint16_t Rmtcnt=0;

(2)定时器更新中断的回调函数

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)//更新中断
{
	if(htim ->Instance ==TIM2 )
	{
		if(Rmtsta &0x80)
		{
			Rmtsta &=~0x10;
			if((Rmtsta & 0x0F)==0x00)
			{
			Rmtsta |=1<<6;
			}
			if((Rmtsta &0x0f)<14)
			{
				Rmtsta ++;			
			}
			else 
			{
				Rmtsta &=~(1<<7);
				Rmtsta &=0xf0;
			}
		}
	}
}

(3)输入捕获中断的回调函数

void HAL_TIM_IC_CaptureCallback  ( TIM_HandleTypeDef *  htim ) //输入捕获中断
	{
	if(htim ->Instance == TIM2 )
	{
		if(HAL_GPIO_ReadPin (GPIOA ,GPIO_PIN_0 )!=0)//上升沿
		{
			__HAL_TIM_SET_CAPTUREPOLARITY(&htim2 ,TIM_CHANNEL_1,TIM_INPUTCHANNELPOLARITY_FALLING );//设置极性下降沿
			__HAL_TIM_SET_COUNTER (&htim2,0);//设置TIM寄存器值		
			Rmtsta |=0x10;			//位4,表示捕获到上升沿
		}
		else		//下降沿
		{
			Dval=HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);//读寄存器值
			__HAL_TIM_SET_CAPTUREPOLARITY(&htim2 ,TIM_CHANNEL_1,TIM_INPUTCHANNELPOLARITY_RISING );//设置极性上升沿
			if(Rmtsta &0x10)//第一次捕获到上升沿
			{
				if(Rmtsta &0x80)//接收到引导
				{
					//可以解码
					if(Dval>300&&Dval <800)
					{
						Rmtrec 	<<=1;
						Rmtrec |=0;
					}
						else if(Dval >1400&&Dval <1800)
						{
							Rmtrec <<=1;
							Rmtrec |=1;
						}
							else if(Dval >2000&&Dval <3000)
						{
							Rmtcnt ++;
							Rmtsta &=0xF0;
						}
					}
					else if(Dval>4200&&Dval <4750)//判断是非接收到引导码
					{
						Rmtsta |=1<<7;	//位7标志为1
						Rmtcnt =0;		//按键计数清零
					}
			}
			Rmtsta&=~(1<<4);
		}
	}
	__HAL_TIM_CLEAR_FLAG(&htim2,TIM_FLAG_UPDATE );
}

(4)遥控器扫描函数

uint8_t remote_scan(void)
{
	uint8_t t1,t2,sta=0;
	if (Rmtsta & (1 << 6))    /* 得到一个按键的所有信息了 */
    {
			t1 = Rmtrec>>24;                 /* 得到地址码 */
			t2 = (Rmtrec >> 16) &0xff;   /* 得到地址反码 */
			if ((t1 == (uint8_t)t2) && t1 == REMOTE_ID)    /* 检验遥控识别码(ID)及地址     && t1 == REMOTE_ID */
			{		
				t1 = Rmtrec >>8;
				t2 = Rmtrec ;
				if (t1 == (uint8_t)~t2)
				{
					sta = t1;           /* 键值正确 */
				}
				//printf ("%d\r\n",sta );//利于打印已解码出的十进制值
			}
			if ((sta == 0) || ((Rmtsta & 0X80) == 0)) /* 按键数据错误/遥控已经没有按下了 */
				{
					
					Rmtsta &= ~(1 << 6);  /* 清除接收到有效按键标识 */
					Rmtcnt = 0; 
          /* 清除按键次数计数器 */
				}	
		}
   
    return sta;
}

(5)main函数

在主函数中进行不断的扫描,(该代码只是测试代码,其按键值,更具实际情况进行更改)

while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		printf ("测试开始:\r\n");
		key =remote_scan();
		switch(key )
		{
			case 0:
				printf ("未收到数据\r\n");break;	
			
			case 162://162
				printf ("1\r\n");HAL_Delay (1000);
			break;	
			case 98:
				printf ("2\r\n");HAL_Delay (1000);
			break;
			case 226:
				printf ("3\r\n");HAL_Delay (1000);
			break;
			case 34:
				printf ("4\r\n");HAL_Delay (1000);
			break;
			case 2:
				printf ("5\r\n");HAL_Delay (1000);
			break;
			case 194:
				printf ("6\r\n");HAL_Delay (1000);
			break;
			case 224:
				printf ("7\r\n");HAL_Delay (1000);
			break;
			case 168:
				printf ("8\r\n");HAL_Delay (1000);
			break;
			case 144:
				printf ("9\r\n");HAL_Delay (1000);
			break;
			case 152:
				printf ("0\r\n");HAL_Delay (1000);
			break;
			case 104:
				printf ("*\r\n");HAL_Delay (1000);
			break;
			case 176:
				printf ("#\r\n");HAL_Delay (1000);
			break;
			case 24:
				printf ("UP\r\n");HAL_Delay (1000);
			break;
			case 74:
				printf ("DOWN\r\n");HAL_Delay (1000);
			break;
			case 16:
				printf ("Left\r\n");HAL_Delay (1000);
			break;
			case 90:
				printf ("Right\r\n");HAL_Delay (1000);
			break;
			case 56:
				printf ("Ok\r\n");HAL_Delay (1000);
			break;
		}
		HAL_Delay (100);
  }

五 . 结果

在这里插入图片描述

在这里插入图片描述

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值