物联网ARM开发-3协议-单总线应用红外遥控
创始人
2024-04-01 09:48:33

前言:单总线类传感器-红外遥控的实现

目录

一、红外遥控工作原理讲解

1、光的基础知识

2、红外通信

3、红外NEC协议详解

二、红外遥控实例讲解

1、实验目的:按下遥控按键,主机通过红外接收器接收到信号并解码,识别出按键的命令码,打印出对应的按键符号。

2、Cubmx配置

3、实现思路分析

(1)协议分析:

(2)功能分析

(3)具体实现

(4)实验演示和源码


 

一、红外遥控工作原理讲解

1、光的基础知识

  • 光的本质:光的本质是电磁波,其传播本质上是一种粒子振动。广义上,光是指所有的电磁波谱。狭义上的光是人类眼睛可以看见的一种电磁波,也称可见光。
  • 光的波长:是指波在一个振动周期内传播的距离。光的波长由光的频率以及传播的介质决定,光通过不同介质的时候,频率不变而波长发生改变
  • 光的颜色: 是由它的波长来决定的,各种颜色有各自的波长,人的眼睛能看到的可见光按波长从长到短排列,依次为红、橙、黄、绿、青、蓝、紫。
  • 可见光:光整个电磁波谱包括了无线电波、红外线、紫外线以及X射线等。它们的波长不同,其中波长在380~760纳米之间就是一般的可见光。依次为红、橙、黄、绿、青、蓝、紫。比紫光波长还短的光叫紫外线,比红光波长还长的光叫红外线。
  • 红外线:是波长介于微波与可见光之间的电磁波,波长在1mm到760纳米(nm)之间,比红光长的非可见光。    高于绝对零度(-273.15℃)的物质都可以产生红外线。现代物理学称之为热射线。我们把红光之外的辐射叫做红外线(紫光之外是紫外线),人的肉眼不可见。

2、红外通信

无线远程遥控技术:   又称为遥控技术,是指实现对被控目标的遥远控制,在工业控制、航空航天、家电领域应用广泛。

红外遥控:     是一种无线、非接触控制技术,具有抗干扰能力强,信息传输可靠,功耗低,成本低,易实现等显著优点,被诸多电子设备特别是家用电器广泛采用,并越来越多的应用到计算机和手机系统中。

红外通讯:就是通过红外线传输数据。发射器发出红外信号,接收器接收到信号进行解析。

红外遥控器:     红外遥控器是利用一个红外发光二极管,以红外光为载体来将按键信息传递给接收端的设备。红外光对于人眼是不可见的,因此使用红外遥控器不会影响人的视觉(可以打开手机摄像头,遥控器对着摄像头按,可以看到遥控器发出的红外光)。

信号调制:     日常生活环境中有很多红外光源,太阳、蜡烛火光、白炽灯、甚至是我们的身体。这些红外光源都可能会对我们的接收设备产生干扰,为了屏蔽干扰,只接收有效信息,我们就需要用到调制。     通过调制我们可以把指定的数字信号转换为特定频率的红外光进行发送,调制载波频率一般在30khz到60khz之间,大多数使用的是38kHz

红外接受器:    红外线接收器是一种可以接收红外信号并能独立完成从红外线接收到输出与TTL电平信号兼容的器件,体积和普通的塑封三极管差不多,适合于各种红外线遥控和红外线数据传输。

信号解调:    解调就是将模拟信号转换成数字信号。红外接收器接收到外部发射器传过来的红外信号后,会按照固定的协议去解析信号,并转换成数字信号输出。

3、红外NEC协议详解

7b44464252ac474c97e7747d1abc7703.png

二、红外遥控实例讲解

 

1、实验目的:按下遥控按键,主机通过红外接收器接收到信号并解码,识别出按键的命令码,打印出对应的按键符号。

所要用到的硬件资源如下: 1) 红外接收头,遥控接收头在板子上,与MCU 的连接原理图如下 2) 红外遥控器

9bf92a338a4045f085bcd3600ba7b54f.png

 我们红外接收器连接的是PA8,一根总线实现通信协议。

2、Cubmx配置

使能led,使能168mhz时钟,定时器Tim5用于输入捕获,pa8外部中断配置

19c46e1070284f3cab39bd3a362020f7.png

 2f97e9fb095648f3a8c4200d0ac052ee.png

bf6fb9083f4c4c6c9587a9692f9cfc45.png 

 eff8c8e0e3ce4fab97cef32dac31d0dd.png

 2d95fa52d7eb4ae89b740f37ba62c373.png

触发中断方式是上升沿下降沿都触发

67d108d30c74471aa5afc8057c6cedb9.png

3、实现思路分析

7b44464252ac474c97e7747d1abc7703.png

(1)协议分析:

红外遥控传输的数据格式:地址码+地址反码+命令码+命令反码

根据协议规定,每个地址码或命令码8位,一条数据一共32位数据。

  • 我们定义一个结构体Remote_Infrared_data_struct,定义4个成员来表示地址码和命令码。
  • 再定义一个共同体Remote_Infrared_data_union,定义2个成员,一个保存上面的结构体和完整32位数据。不同数据类型的数据可以使用共同的存储区域

(2)功能分析

开始拉低9ms,接着是一个4.5ms的高脉冲,通知器件开始传送数据了接着是发送4个8位二进制码,第一二个是遥控识别码(REMOTE_ID),第一个为正码(0),第二个为反码(255),接着两个数据是键值,第一个为正码第二个为反码.发送完后40ms,遥控再发送一个9ms低,2ms高的脉冲,表示按键的次数,出现一次则证明只按下了一次,如果出现多次,则可以认为是持续按下该键。

处理红外接收

定义一个标志位 bBitCounter 记录键盘帧的位数。每次信号进来都加1,代表进来的次数。通过bBitCounter次数和计数器时长来判定起始码和数据码。最后读取按键值。

261fb691081b4e9d847d3fbde5888a1e.png​​​​​​​

(3)具体实现

RomoteInfrared.h

#include "stm32f4xx_hal.h"#define	Remote_Infrared_DAT_INPUT HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8)typedef struct _Remote_Infrared_data_struct //定义红外线接收到的数据结构体类型
{uint8_t bKeyCodeNot; //按键的的ASIIC码值  按键反码uint8_t bKeyCode; //shift键按下标志  按键码uint8_t bIDNot; //断码标志位   用户反码uint8_t bID; //新键标志位   用户码
}Remote_Infrared_data_struct;typedef union _Remote_Infrared_data_union //定义红外线接收到的数据结构体类型
{Remote_Infrared_data_struct RemoteInfraredDataStruct; //上面定义的红外线接收到的数据结构体类型uint32_t uiRemoteInfraredData;  // 记录 用户码用户反码按键码按键反码
}Remote_Infrared_data_union;void Remote_Infrared_KEY_ISR(void);
uint8_t Remote_Infrared_KeyDeCode(void);

RomoteInfrared.c

#include "RemoteInfrared.h"#define REPEAT_KEY  0xEEextern __IO uint32_t GlobalTimingDelay100us;
extern __IO uint32_t GlobalTimingDelay100usTx;__IO uint32_t FlagGotKey = 0;__IO Remote_Infrared_data_union RemoteInfrareddata;/************************************************************************
//处理红外接收  
-------------------------协议--------------------------
开始拉低9ms,接着是一个4.5ms的高脉冲,通知器件开始传送数据了
接着是发送4个8位二进制码,第一二个是遥控识别码(REMOTE_ID),第一个为
正码(0),第二个为反码(255),接着两个数据是键值,第一个为正码
第二个为反码.发送完后40ms,遥控再发送一个9ms低,2ms高的脉冲,
表示按键的次数,出现一次则证明只按下了一次,如果出现多次,则可
以认为是持续按下该键.*名称: Remote_Infrared_KEY_ISR(INT11_vect )													 
*功能: INT0中断服务程序		       									
*参数: 无					          									
*返回: 无		                           								
*************************************************************************/	
// 检测脉冲宽度最长脉宽为5ms
const uint32_t TIME_DELAY_6MS = 60;
const uint32_t TIME_DELAY_10MS = 100;//按键中断服务程序ISR
void Remote_Infrared_KEY_ISR(void)
{static __IO uint8_t  bBitCounter = 0; //键盘帧位计数 static __IO uint32_t bKeyCode = 0;bBitCounter++;  //每次信号进来都加加,代表进来的次数if(bBitCounter == 1)        // 开始拉低9ms{if(Remote_Infrared_DAT_INPUT) // 高电平无效{bBitCounter = 0;}else{GlobalTimingDelay100us = TIME_DELAY_10MS; //100赋给变量 ,这个变量会在中断函数里减}}else if(bBitCounter == 2)   // 4.5ms的高脉冲{if(Remote_Infrared_DAT_INPUT){if((GlobalTimingDelay100us > 2) && (GlobalTimingDelay100us < 18))  //GlobalTimingDelay100us检查到减到什么程度了 100-90应该是10 2-18范围内{GlobalTimingDelay100us = TIME_DELAY_6MS;}else{ bBitCounter = 0; //printf(".");}}else{bBitCounter = 0;            }}else if(bBitCounter == 3)   // 4.5ms的高脉冲{if(Remote_Infrared_DAT_INPUT){bBitCounter = 0; }else{if((GlobalTimingDelay100us > 5) && (GlobalTimingDelay100us < 20))    //起始码 4.5ms   5<60-45<20{GlobalTimingDelay100us = TIME_DELAY_6MS;//printf("引导码");}else if((GlobalTimingDelay100us > 32) && (GlobalTimingDelay100us < 46))   //重复码 2.25ms{//重复码bBitCounter = 0;                                           //检测到结束信号 次数置0RemoteInfrareddata.uiRemoteInfraredData = bKeyCode;               //把按键码保存到结构体//RemoteInfrareddata.uiRemoteInfraredData = REPEAT_KEY;bBitCounter = 0;FlagGotKey = 1;}            else{bBitCounter = 0; //printf("%d&", GlobalTimingDelay100us);}          }}    else if(bBitCounter > 3 && bBitCounter < 68) //接收8位数据{  if(Remote_Infrared_DAT_INPUT)          //检测数据脉冲低电平的时间{if((GlobalTimingDelay100us > 50) && (GlobalTimingDelay100us < 58)){GlobalTimingDelay100us = TIME_DELAY_6MS;}else{bBitCounter = 0; //printf("#");}           }else{if((GlobalTimingDelay100us > 50) && (GlobalTimingDelay100us < 58))       // '0'  0.56ms左右{GlobalTimingDelay100us = TIME_DELAY_6MS;bKeyCode <<= 1;  // MSB First bKeyCode += 0x00;}else if((GlobalTimingDelay100us > 40) && (GlobalTimingDelay100us < 48))  //'1'   1.685ms左右{GlobalTimingDelay100us = TIME_DELAY_6MS;            bKeyCode <<= 1;  // MSB First bKeyCode += 0x01;}              else{bBitCounter = 0; }  }if(bBitCounter == 67){RemoteInfrareddata.uiRemoteInfraredData = bKeyCode;bBitCounter = 0;FlagGotKey = 1;//printf("KeyCode = 0x%X", bKeyCode);}}else{bBitCounter = 0;//printf("KeyCode = 0x%X", bKeyCode);}
}/************************************************************************
*名称: unsigned char Remote_Infrared_KeyDeCode(unsigned char bKeyCode)					 
*功能: PS2键盘解码程序		       									    
*参数: bKeyCode 键盘码 							
*返回: 按键的ASIIC码		                           								
************************************************************************/
uint8_t Remote_Infrared_KeyDeCode(void)
{
//	uint8_t Key = 0xFF;if (FlagGotKey == 1)//通码   0没按,1按了,外部会判断解析按没按并返回值{FlagGotKey = 0;//方便下次再进来if((RemoteInfrareddata.RemoteInfraredDataStruct.bID == (uint8_t)~ RemoteInfrareddata.RemoteInfraredDataStruct.bIDNot)  //校验用户码&& (RemoteInfrareddata.RemoteInfraredDataStruct.bKeyCode == (uint8_t)~ RemoteInfrareddata.RemoteInfraredDataStruct.bKeyCodeNot))  //校验按键码{printf("\n\r IR Receive KeyCode = 0x%02X, ", RemoteInfrareddata.RemoteInfraredDataStruct.bKeyCode);switch(RemoteInfrareddata.RemoteInfraredDataStruct.bKeyCode)  //提取按键码{case 0: printf("ERROR");break;			   case 162:printf("POWER");break;	    case 98:printf("UP");break;	    case 2:printf("PLAY");break;		 case 226:printf("ALIENTEK");break;		  case 194:printf("RIGHT");break;	   case 34:printf("LEFT");break;		  case 224:printf("VOL-");break;		  case 168:printf("DOWN");break;		   case 144:printf("VOL+");break;		    case 104:printf("1");HAL_GPIO_WritePin(GPIOF, GPIO_PIN_9, GPIO_PIN_RESET);break;		  case 152:printf("2");HAL_GPIO_WritePin(GPIOF, GPIO_PIN_9, GPIO_PIN_SET);break;	   case 176:printf("3");break;	    case 48:printf("4");break;		    case 24:printf("5");break;		    case 122:printf("6");break;		  case 16:printf("7");break;			   					case 56:printf("8");break;	 case 90:printf("9");break;case 66:printf("0");break;case 82:printf("DELETE");break;	default:printf("Unknown key!");}}else{printf("\n\r ERR 0x%08X", RemoteInfrareddata.uiRemoteInfraredData);}}return RemoteInfrareddata.RemoteInfraredDataStruct.bKeyCode;
}

main.c

#include "main.h"
#include "stm32f4xx_hal.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"/* USER CODE BEGIN Includes */
#include
#include "RemoteInfrared.h"
/* USER CODE END Includes *//* Private variables ---------------------------------------------------------*//* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
__IO uint32_t GlobalTimingDelay100us;
/* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*//* USER CODE END PFP *//* USER CODE BEGIN 0 */
int fputc(int ch,FILE *p)
{while(!(USART1->SR & (1<<7)));USART1->DR = (uint8_t)ch;return ch;
}
/* USER CODE BEGIN 0 */
int fputc(int ch,FILE *p)
{while(!(USART1->SR & (1<<7)));USART1->DR = (uint8_t)ch;return ch;
}
/* USER CODE END 0 *//*** @brief  The application entry point.** @retval None*/
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration----------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_USART1_UART_Init();MX_TIM5_Init();/* USER CODE BEGIN 2 *//*设置SYSTICK为 100us中断一次 */HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/10000);        //原本主频/1000得到的是1ms中断,因为我们需要用到计时器100us计数,所以我们除10000,得到的是100us计数1次HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);printf("remote test");printf("\n\r");printf("\n\r-------------------------------------------------");printf("\n\r FS-STM32开发板 IR红外线接收实验程序");printf("\n\r 请将红外线接收头连接到开发板的对应接口");printf("\n\r 然后用红外遥控器进行控制,注意串口输出");printf("\n\r-------------------------------------------------");  printf("\n\r----------------- 协议如下 ----------------------");printf("\n\r 首先是引导码: 开始拉低9ms,接着一个4.5ms的高脉冲.");    printf("\n\r       引导码的作用是通知接收方器准备接收数据;");printf("\n\r 引导码之后是4个字节的二进制码, 其中前两个字节是");printf("\n\r       遥控识别码(ID), 第一个为正码,第二个为反码,");printf("\n\r       后两字节是键值, 第一个为正码,第二个为反码.");printf("\n\r 最后可能有持续按下通知, 上述数据发送完后如果刚才");printf("\n\r       的按键持续被按下, 则发送9ms低,2ms高的脉冲。");printf("\n\r---------------- 载波为38kHz --------------------");  printf("\n\r 传输一个逻辑1需要2.25ms(560us低电平+1680us高电平)");printf("\n\r 传输一个逻辑0需要1.125ms(560us低电平+560us高电平)");printf("\n\r-------------------------------------------------");  printf("\n\r----- 本实验在中断中检测接收IR红外线的数据 ------\n\r");/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){HAL_GPIO_WritePin(GPIOF, GPIO_PIN_8, GPIO_PIN_RESET);HAL_Delay(1000);HAL_GPIO_WritePin(GPIOF, GPIO_PIN_8, GPIO_PIN_SET);HAL_Delay(1000);Remote_Infrared_KeyDeCode();/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */}/* USER CODE BEGIN 4 */
void HAL_SYSTICK_Callback(void)
{if(GlobalTimingDelay100us != 0){GlobalTimingDelay100us--;}
}void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{Remote_Infrared_KEY_ISR();
}
/* USER CODE END 4 */

a4c1ce193f794d1d89b4c4a3398dc82e.png

(4)实验演示和源码

后期上传实验效果和源码

 

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...