基于stm32实现红外自发自收

  • 红外遥控简介
    • 红外发射
      • stm32模拟红外发射思路及效果
    • 红外接收
      • stm32红外接收思路
  • 硬件电路
  • STM32Cube几个重要配置
  • 代码部分
    • 发射代码
    • 接收代码
  • 最终效果
    • 源码链接

之前我写过一篇使用Arduino实现红外接收发射的博客(链接: 如何用一块 Arduino uno 板同时进行红外发送和接收)。但仅仅实现了一个中继站的功能。但为了实现真正意义上的红外自发自收,我在那篇文章提出了几个思路,但由于Arduino硬件的限制,无法实现我的思路。因此,这篇博客我将使用高级一点的硬件——STM32,实现真正意义的红外自发自收!!!
下面列出一些参考网站:

  • STM32CubeMX系列|红外遥控
  • NEC的红外编码!
  • 基于stm32实现红外遥控信号接收解码的详细步骤

红外遥控简介

红外遥控是一种无线、非接触控制技术,具有抗干扰能力强,信息传输可靠,功耗低,成本低,易实现等显著优点,被诸多电子设备特别是家用电器广泛采用,并越来越多的应用到计算机系统中。
个人觉得,使用红外进行无线通信有几大优势。一,便宜!便宜!!便宜!!!(重要的事情强调3遍)。二,直线传输,穿透力差,无法穿墙,较低概率受到他人的干扰(某些场景的缺点却是某些场景的优点)。三,其本身不发任何类型辐射,器件功耗很小。

红外发射

注:此处直接摘抄于STM32CubeMX系列|红外遥控
红外发射装置(红外遥控器)是由键盘电路、红外编码电路、电源电路和红外发射电路组成。红外发射电路的主要元件为红外发光二极管(目前使用的红外线波长多为940nm)。红外遥控器常用载波的方式传送二进制编码,常用的载波频率为38kHz,红外遥控器将遥控信号(二进制脉冲码)调制在38kHz的载波上,经缓冲放大后送至红外发光二极管,转化为红外信号发射出去。
二进制脉冲码目前最广泛使用的是:NEC Protocol的PWM(脉冲宽度调制)和Philips RC-5 Protocol的PPM(脉冲位置调制)。本例程遥控器使用的是NEC协议,其特征如下:

  • 8位地址和8位指令长度
  • 地址和命令2次传输(确保可靠性)
  • PWM脉冲位置调制,以发射红外载波的占空比代表0和1
  • 载波频率为38kHz

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

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

stm32模拟红外发射思路及效果

下图为遥控器信号(使用逻辑分析仪查看红外接收管的电信号)

我们需要做的就是通过stm32实现红外精确的时序逻辑。同无线通信,红外发射作为调制环节,我们首先需要产生一个38KHz载波(由于载波频率不高,对应的可使用stm32的定时器PWM模式产生38KHz的方波信号),然后通过控制PWM开启关闭实现具体的时序。
由于本人偷懒,就省掉了遥控器最后面的那个结束帧信号。
下图为本人模拟遥控器信号结果(使用逻辑分析仪查看红外接收管的电信号)

红外接收

红外接收设备是由红外接收电路、红外解码、电源和应用电路组成。红外遥控接收器的主要作用是将遥控发射器发来的红外光信好转换成电信号,再放大、限幅、 检波、整形,形成遥控指令脉冲,输出至遥控微处理器。

stm32红外接收思路

由于红外接收头在没有脉冲的时候为高电平,当收到脉冲的时候为低电平,所以可以通过定时器输入捕获中断的上升和下降沿触发中断,在中断内通过计算高电平时间来判断接收到的数据是0还是1。

硬件电路

感觉较简单,就不细讲了吧。相信大家都很熟悉那个STM32F103C8T6最小系统板吧!
发射部分就是加了个NPN管放大(9014,增益带宽积15MHz)
接收部分就是直接按照红外管datasheet接就好了,也不用放大它的信号,没有必要,因为接收灵敏度取决于红外管。
下图就是我搭的电路:(很简单,一看就懂)

STM32Cube几个重要配置

管脚配置(PA1接发射管脚,PA6接接收管脚):

时钟我用的是外部晶振,主频72M。
时钟1用于产生微妙延时。

时钟2产生38KHz的PWM

时钟3用于输入捕获红外接收信号

代码部分

发射代码

我的注释是ASCII码,所以乱码,大家注意一下导入Keil改一下语言设置

void delay_us(uint16_t us){uint16_t differ = 0xffff-us-5;               __HAL_TIM_SET_COUNTER(&htim1,differ);   //É趨TIM¶¨ÊýÆ÷µÄÆðʼֵHAL_TIM_Base_Start(&htim1);      //Æô¶¯¶¨Ê±Æ÷while(differ < 0xffff-5){    //ÅжÏdiffer = __HAL_TIM_GET_COUNTER(&htim1);      //²éѯ¶¨Ê±Æ÷µÄ¼ÆÊýÖµ}HAL_TIM_Base_Stop(&htim1);
}

变量声明

uint8_t send_Flag = 0;
uint32_t send_Code = 0;
uint32_t receive_Code = 0;
uint8_t receive[33] = {0};
uint8_t receive_Flag = 0;
uint8_t addr = 0x00;
uint8_t data = 0xA2;

发射时序逻辑(放在主函数即可)

if(send_Flag == 1){send_Flag = 0;HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);delay_us(9000);HAL_TIM_PWM_Stop(&htim2,TIM_CHANNEL_2);delay_us(4500);uint8_t iaddr = ~addr;uint8_t idata = ~data;send_Code = addr<<24 | iaddr<<16 | data<<8 | idata;for(int i=31;i>=0;i--){HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);delay_us(560);HAL_TIM_PWM_Stop(&htim2,TIM_CHANNEL_2);if((send_Code>>i) & 0x01)//ÊÇ·ñ·´Ïòdelay_us(1690);elsedelay_us(560);
//              if((send_Code>>i) & 0x01)//ÊÇ·ñ·´Ïò
//                  delay_us(560);
//              else
//                  delay_us(1690);}HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);delay_us(560);HAL_TIM_PWM_Stop(&htim2,TIM_CHANNEL_2);
}

接收代码

记得在cube里开中断!!!

uint32_t pwm_low_level_time;
uint32_t pwm_high_level_time;
int tim_mode_raise_or_falling = 0;
int Index = 0;
int ok = 0,ok2=0;
int datawp[35] = {0};
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{if(tim_mode_raise_or_falling == 0)           {pwm_low_level_time = HAL_TIM_ReadCapturedValue(&htim3,TIM_CHANNEL_1) + 1;        __HAL_TIM_SET_COUNTER(&htim3,0);        TIM_RESET_CAPTUREPOLARITY(&htim3, TIM_CHANNEL_1);       TIM_SET_CAPTUREPOLARITY(&htim3,TIM_CHANNEL_1,TIM_ICPOLARITY_FALLING);       tim_mode_raise_or_falling = 1;     ok2 = 0;}else if(tim_mode_raise_or_falling == 1)         {pwm_high_level_time = HAL_TIM_ReadCapturedValue(&htim3,TIM_CHANNEL_1) + 1;       __HAL_TIM_SET_COUNTER(&htim3,0);    TIM_RESET_CAPTUREPOLARITY(&htim3, TIM_CHANNEL_1);       TIM_SET_CAPTUREPOLARITY(&htim3,TIM_CHANNEL_1,TIM_ICPOLARITY_RISING);        tim_mode_raise_or_falling = 0;     ok2 = 1;}uint8_t Data=0;if(pwm_high_level_time >= 5000){Index=0;ok = 0;}else if(pwm_high_level_time >= 3500 && pwm_high_level_time < 5000){Index=0;ok = 1;}else if(pwm_high_level_time >= 1000 && pwm_high_level_time < 2000){Data=1;      }else if(pwm_high_level_time > 0 && pwm_high_level_time < 1000){Data=0;      }if(ok == 1 && ok2 == 1){receive_Code <<= 1;receive_Code += Data;receive[Index] = Data;datawp[Index] = pwm_high_level_time;Index++;if(Index>=32){receive_Flag=1;Index = ok = 0;}}
}

最终效果

接收遥控器信号

自发自收

源码链接

gif可能看不太清楚,我放在Gitee上吧。

  • stm32_IR

stm32实现红外自发自收相关推荐

  1. STM32之红外遥控信号自学习实现

    文章目录 一.序言 二.硬件实现原理 三.软件实现自学习 一.序言 很早前就想实现这个红外遥控自学习的这个实验,用于来自己控制房子里如空调等红外遥控设备的自动化,NEC的标准到具体的产品上可能就被厂家 ...

  2. 利用STM32制作红外测温仪之软件设计(MLX90614)

    目录 (一)工程目录如图: (二)main函数实现: (三)MLX90614测温代码实现 前面介绍了使用 STM32制作红外测温仪硬件设计,今天来说一下软件的实现,具体的程序,完整的keil代码我已经 ...

  3. 基于STM32与红外感应开关的自动门设计与实现(结构+设计)

    基于STM32与红外感应开关的自动门设计与实现 采用STM32作为主控,设计了自动和手动开门装置,MLX90614作为设计测温装置. 前言说明 元器件清单说明 STM32F103C8T6系统板 微型滑 ...

  4. STC15W408AS的485串口实现自发自收

    STC15W408AS的485串口实现自发自收 485串口 STC的坑 STC单片机发送数据给485串口的时候,发数据一般都没有问题,但是收数据的时候,一般收不到.我改动了两版电路板,才得到正确的方式 ...

  5. 单片机实验(十三)串口自发自收实现

    1.实验环境:win732位系统,keil2,proteus7.5sp3. 2.实验目的:学习通过编程串口自发自收实现. 3.实验连接图. 4.实验代码. #include<reg52.h> ...

  6. STM32 NEC红外遥控器解码

    STM32 NEC红外遥控器解码 红外遥控编码格式 一体化红外接收头 STM32显示遥控器按下的数字代码 代码片 总结 原文链接:https://www.yourcee.com/newsinfo/29 ...

  7. 树莓派_C++(Cmake)_GPIO_bcm2835_SPI通信自发自收

    文章介绍一种使用bcm2835实现SPI通信的方案 操作环境:树莓派4B.bcm2835-1.71 实现功能:完成SPI通信的自发自收功能 主要代码:SPI通信部分 #include <iost ...

  8. ft4232树莓派linux扩展串口,树莓派Linux串口编程实现自发自收

    串口是计算机上一种非常通用设备通信的协议,常用PC机上包含的是RS232规格的串口,具有连接线少,通讯简单,得到广泛的使用. Linux对所有设备的访问是通过设备文件来进行的,串口也是这样,为了访问串 ...

  9. stm32解码红外遥控实验

    stm32解码红外遥控 红外遥控的简介 有关编程的解释 使用hal库进行红外遥控实验 红外遥控的简介 红外解码目前广泛使用的NEC Protocol的PWM(脉冲宽度调制)和Philips RC-5 ...

  10. 利用STM32制作红外测温仪之硬件设计

    最近受疫情的影响详细大家都在家里没事干,这里利用stm32最小系统做一个红外测温仪 这篇教程里我们来制作红外测温仪需要用到的硬件,关于PCB的工程文件,后文会给出. (一)系统分析 由于我们的功能比较 ...

最新文章

  1. 关于Python爬虫原理和数据抓取1.1
  2. 马斯克教你的五步做事法
  3. 替代还是扩展:云的下一站真是雾计算?
  4. 实验吧—Web——WP之 上传绕过
  5. Hive的索引操作【小结】
  6. shuffle操作图解以及job-stage-task-partition区别
  7. uiview生命周期
  8. Apache Shiro 简介
  9. 如何获取不重复的随机数
  10. Dirichlet Process 和 Dirichlet Process Mixture模型
  11. 【vjudge contest 418548】2021 BUAA Winter Training 3(Private),签到题ABCDG
  12. 音乐混音怎么做?教你完美制作野狼disco与周杰伦双节棍合唱!
  13. linux运维必学python吗_Python学习资源整理
  14. 计算机录屏幕和声音的软件是什么,哪个录屏软件可以录内部声音?分享开启与调节的方法...
  15. VS配置GLAD+GLFW
  16. Anaconda 的Jupyter Notebook更换默认浏览器
  17. UG二次开发GRIP修改颜色
  18. R和RStudio安装包下载
  19. 微信小程序地图定位开发教程
  20. PHP png合并到jpg,合并jpg的png并保持与php的透明度

热门文章

  1. 社招腾讯,阿里,京东,必问知识点整理,常考知识点全在这里了!
  2. oracle 中explain,oracle执行计划的使用(EXPLAIN)
  3. 基于Jsp+Servlet的在线考试系统
  4. 平均值、中位数、众数等统计特性的matlab求解与示例
  5. 基于codebook背景建模的运动目标检测
  6. diskgenius数据恢复软件,亲测可用!
  7. dell电脑恢复出厂系统(旧电脑如何重装系统)
  8. V-Ray for SketchUp破解版(SketchUp渲染插件)
  9. 第二讲 综合评价分析—TOPSIS法
  10. 前端开发者必会的英语单词