这里没有解析红外的函数,毕竟考虑到学习的红外有几种协议(如:NEC).同时代码存在一些问题(有部分遥控是学习不了的(如:空调、DVD)).

红外数据接收:定时器捕获红外信号(还有一个是通过外部中断的,这里不列出)
红外数据发射:使用PWM输出
下面直接上代码

remote.c

/*remote.c*/
#include "remote.h"
#include "delay.h"
#include "usart.h"/**
发射:PA7-TIM3-CH2
接收:PC8-TIM8-CH3TIM8:
下面代码中捕获中断和定时中断分开,不在同一中断函数,所以需要配置两次中断优先级(应该可以合在一起配置)
*//***  @name          void Remote_Init(void) *    @description   红外遥控初始化 设置IO以及定时器8的输入捕获*                  Infrared remote initializer sets IO and timer 8 input capture*  @notice          */
void Remote_Init(void)
{  GPIO_InitTypeDef GPIO_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;TIM_ICInitTypeDef  TIM_ICInitStructure;  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO,ENABLE); //使能PORTB时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8,ENABLE);                      //TIM8 时钟使能 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;                                //PC8 输入 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;                    //浮空输入 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOC, &GPIO_InitStructure);GPIO_SetBits(GPIOC,GPIO_Pin_8);                                          //初始化GPIOC.8TIM_TimeBaseStructure.TIM_Period = 9999;                                 //设定计数器自动重装值 最大10ms溢出  TIM_TimeBaseStructure.TIM_Prescaler =(72-1);                             //预分频器,1M的计数频率,1us加1.      TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;                  //设置时钟分割:TDTS = Tck_timTIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;              //TIM向上计数模式TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);                          //根据指定的参数初始化TIMxTIM_ICInitStructure.TIM_Channel = TIM_Channel_3;                         // 选择输入端 IC4映射到TI4上TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;              //上升沿捕获TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;                    //配置输入分频,不分频 TIM_ICInitStructure.TIM_ICFilter = 0x03;                                 //IC4F=0011 配置输入滤波器 8个定时器时钟周期滤波TIM_ICInit(TIM8, &TIM_ICInitStructure);                                  //初始化定时器输入捕获通道TIM_Cmd(TIM8,ENABLE );                                                   //使能定时器4NVIC_InitStructure.NVIC_IRQChannel = TIM8_CC_IRQn;                       //TIM8TIM8捕获比较中断NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;                //先占优先级0级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;                       //从优先级3级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                          //IRQ通道被使能NVIC_Init(&NVIC_InitStructure);                                          //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器    TIM_ITConfig( TIM8,TIM_IT_CC3,ENABLE);                                   //允许更新中断 ,允许CC4IE捕获中断      NVIC_InitStructure.NVIC_IRQChannel = TIM8_UP_IRQn;                       //TIM3中断NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;                //先占优先级0级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;                       //从优先级3级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                          //IRQ通道被使能NVIC_Init(&NVIC_InitStructure);                                          //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器   TIM_ITConfig( TIM8,TIM_IT_Update,ENABLE);                                //允许更新中断 ,允许CC4IE捕获中断
}
/***  @name            void TIM3_PWM_Init(u16 arr,u16 psc)*    @description   初始化定时器3的设置,将定时器3用于PWM调制,PWM输出口为 PA.7* @param         arr --  u16,定时器重装值psc --    u16,定时器分频值                          *   @return        *  @notice         PWM频率 = 72M/((arr+1)*(psc+1)),这里用作红外发射的载波,需要生成38kHz的方波,故取arr = 1895,psc = 0。*/
void TIM3_PWM_Init(u16 arr,u16 psc)
{/* 初始化结构体定义 */GPIO_InitTypeDef GPIO_InitStructure;TIM_TimeBaseInitTypeDef  TIM_TimeBaseInitStructure;                        //定时器基本设置TIM_OCInitTypeDef    TIM_OCInitStructure;                                  //定时器比较输出配置/* 使能相应端口的时钟 */RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);                      //使能定时器2时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE); //使能GPIO外设时钟/* GPIOA.7初始化 */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;                                 // TIM3 CH2GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;                           // PA.7 复用推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_SetBits(GPIOA,GPIO_Pin_7);/* TIM3 初始化*/TIM_TimeBaseInitStructure.TIM_Period = arr;                               //下一个更新事件装入活动的自动重装载寄存器周期的值TIM_TimeBaseInitStructure.TIM_Prescaler = psc;                            //作为TIMx时钟频率除数的预分频值 TIM_TimeBaseInitStructure.TIM_ClockDivision = 0;                          //时钟分割:TDTS = Tck_timTIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;           //TIM向上计数模式TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);/* 定时器TIM3 Ch2 PWM模式初始化 */TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;                         //选择定时器模式:TIM PWM1   TIM_OCMode_PWM1TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;             //比较输出使能TIM_OCInitStructure.TIM_Pulse = (arr+1)/3;                                //占空比1:3 (arr+1)/10  3TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;                 //输出极性:TIM输出比较极性高   TIM_OCPolarity_HighTIM_OC2Init(TIM3, &TIM_OCInitStructure);/* 使能TIM3在CCR1上的预装载寄存器 */TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
}u8     RmtSta=0;                    //红外学习上升或下降标志位
u16 Dval;                        //上升沿、下降沿的计数器的值
u8  RmtCnt=0;                    //定时器红外学习计数超时标志位
u8  PulseTabCnt=0;               //上升沿下降沿计数器的值
u16 PulseTab[MAX_PULSE_LEN]={0}; //红外学习存储数据
u8  Flag_LearnState = 0;         //红外学习标志位/***@name  void TIM8_UP_IRQHandler(void)*@brief TIM8的定时计数中断函数*       The timing count interrupt function of TIM8*@note*/
void TIM8_UP_IRQHandler(void)
{if(TIM_GetITStatus(TIM8,TIM_IT_Update)!=RESET){if(RmtCnt++>50){RmtCnt = 0;if(RmtSta){RmtSta = 0;Flag_LearnState = 1;}}}TIM_ClearITPendingBit(TIM8,TIM_IT_Update);
}/***@name  void TIM8_CC_IRQHandler(void)*@brief 捕获红外载波的高低电平宽度,记录到数组PulseTab*       Capture the high and low level width of the infrared carrier and record it to the array PulseTab*@note*/
void TIM8_CC_IRQHandler(void)
{                if(TIM_GetITStatus(TIM8,TIM_IT_CC3)!=RESET)                 //获取上升沿或下降沿状态{      if(RDATA)                                               //上升沿捕获{Dval=TIM_GetCapture3(TIM8);                         //读取CCR4也可以清CC4IF标志位TIM_OC3PolarityConfig(TIM8,TIM_ICPolarity_Falling); //CC4P=1    设置为下降沿捕获TIM_SetCounter(TIM8,0);                             //清空定时器值if(RmtSta&0X01){PulseTab[PulseTabCnt++] = Dval;RmtSta = 0x10;}else{RmtSta = 0X10;                                  //标记上升沿已经被捕获}}else                                                    //下降沿捕获{Dval=TIM_GetCapture3(TIM8);                         //读取CCR4也可以清CC4IF标志位TIM_OC3PolarityConfig(TIM8,TIM_ICPolarity_Rising);  //CC4P=0    设置为上升沿捕获TIM_SetCounter(TIM8,0);                             //清空定时器值if(RmtSta&0X10)                                     //完成一次高电平捕获 {PulseTab[PulseTabCnt++] = Dval;RmtSta = 0x01;}else {RmtSta = 0x01;}}                                                         }TIM_ClearITPendingBit(TIM8,TIM_IT_CC3);
}/***@name            void Infrared_Send_IR1(u16 *irdata,u32 irlen)*@description     红外信号发射函数*@param           irdata --   u16,红外数据irlen  --   u32,红外数据长度                            *@return       *@notice           */
void Infrared_Send(u16 *irdata,u32 irlen)
{u32 i;                                      //用于下面的for循环for(i=0; i<irlen && irdata[i]!=0xffff; i++) //循环,从i=0开始,当i<irlen 并且 irdata[i] != 0xffff 时成立,当其中一个不成立,退出循环{if(i%2 == 0)                            //偶数的下标的数组成员延时拉高电平{TIM_Cmd(TIM3,ENABLE);delay_us(irdata[i]);TIM_Cmd(TIM3,DISABLE);GPIO_SetBits(GPIOA,GPIO_Pin_7);          }else{GPIO_SetBits(GPIOA,GPIO_Pin_7);delay_us(irdata[i]);}}delay_us(555);GPIO_ResetBits(GPIOA,GPIO_Pin_7);return ;
}

remote.h

/*remote.h*/
#ifndef __RED_H
#define __RED_H
#include "sys.h"   #define RDATA  PCin(8)     //红外数据输入脚//红外遥控识别码(ID),每款遥控器的该值基本都不一样,但也有一样的.
//我们选用的遥控器识别码为0
#define REMOTE_ID 0
#define MAX_PULSE_LEN 400 //500  300extern u8  RmtCnt;          //按键按下的次数
extern u16 PulseTab[MAX_PULSE_LEN];
extern u8  Flag_LearnState ;
extern u8  PulseTabCnt;//上升沿下降沿计数器的值void Remote_Init(void);     //红外传感器接收头引脚初始化
void TIM3_PWM_Init(u16 arr,u16 psc);
void Infrared_Send(u16 *irdata,u32 irlen);#endif

main.c

/*main.c*/
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "remote.h"
#include "string.h"/***@name   int main(void)*@brief*@retval return 0*@note*/
int main(void)
{    delay_init();                                   //延时函数初始化  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置中断优先级分组为组2:2位抢占优先级,2位响应优先级uart_init(115200);                              //串口初始化为115200Remote_Init();                                  //红外接收初始化         TIM3_PWM_Init(1895,0);                          //tim3 pwm initializeprintf("init ok\r\n");while(1){if(Flag_LearnState){printf("%s\r\n",(char *)PulseTab);Infrared_Send(PulseTab,PulseTabCnt);PulseTabCnt = 0;Flag_LearnState=0;memset((void *)PulseTab,0,MAX_PULSE_LEN);}}
}

最后
实验现象:
本实验开机之后,即进入等待红外触发,如过接收到正确的红外信号,则500ms后自动从红外发射棒发射红外,同时通过串口1,将接受的红外信号以16进制打印出来.

注意事项:
1,可以用最小开发板调试,红外接收头和发射棒可以外接.
2,当使用的接收或发射引脚不一样是,注意将定时器修改.
3,本实验为万能学习红外遥控器,属于半成品,未做存储处理,需要储存需使用芯片的flash或外接eeprom.

STM32——红外接收和红外发射相关推荐

  1. thinkphp6 接收不到数据_单片机红外接收与红外发射

    1. 红外接收1.1 说明1.2 NEC协议1.3 关于红外接收的波形1.4 解码1.4 红外对射思考2. 红外发射2.1 红外发射管参数2.2 红外发射电路搭建2.3 程序设计2.5 实验结果2.4 ...

  2. Arduino 红外模块 红外接收 红外发射

    需要用到IRremote库文件 红外遥控按键16进制编码,使用时添加前缀 0X 红外接收 .源代码 //***************** //红外接收模块测试 //***************** ...

  3. 基于STM32的万能红外遥控器

    本博客介绍一种基于STM32的可学习和存储已有红外发射设备的万能红外遥控器的设计思路. 一.首先需要了解设计一款这功能的遥控器需要什么硬件设备支持. 1.3.3V,5V电源模块,用作给系统模块供电和单 ...

  4. 红外遥控实现回充原理红外发射与调制信号

    遥控红外通信原理 在实际的通信领域,发出来的信号一般有较宽的频谱,而且都是在比较低的频率段分布大量的能量,所以称之为基带信号,这种信号是不适合直接在信道中传输的.为便于传输.提高抗干扰能力和有效的利用 ...

  5. 浅谈38K红外发射接受编码(非常好)

    若不允许转载,请联系我删除. 之前做接触过一次红外遥控器,现在有空想用简单的话来聊一聊,下面有错误的地方欢迎改正指出: 1:红外的概念不聊,那是一种物理存在.以下聊38K红外发射接收,主要讲可编程的红 ...

  6. 【扫盲贴】浅谈38K红外发射接受编码(非常好)

    呃,最初的原文好像已经消失了,,,我担心以后会看不到,转载一下,如不允许转载请站内短信通知我,,谢谢! 之前做接触过一次红外遥控器,现在有空想用简单的话来聊一聊,下面有错误的地方欢迎改正指出: 1:红 ...

  7. ESP32实现红外遥控 红外发射与接收实现原理

    文章目录 一,原理 1.1 概括 1.2,时钟 1.3,认识 item 1.4,发射/接收器 1.5 电路原理图 1.5.1,发射电路 1.5.2 ,接收电路 二,红外发射 2.1 整体的思路 2.2 ...

  8. Arduino红外发射实验

    相关资料链接 链接:https://pan.baidu.com/s/1eE0rkaSJsKJMU_RUorS5OA 提取码:3ujh 1.1 介绍: 传感器主要由红外发射管等组成,它是可将电能直接转换 ...

  9. 浅谈38K红外发射接收编码

    浅谈38K红外发射接收编码 https://blog.csdn.net/gmdjmawy/article/details/47129989 http://blog.sina.com.cn/s/blog ...

  10. s8050三极管经典电路_曝光一个产品级的红外发射电路

    作者:瑞生,来源:科技老顽童微信公众号:芯片之家(ID:chiphome-dy今天给大家一个产品级的红外发射电路.为什么说是产品级的?因为这个电路我已经在各类产品上见过多次!很多小伙伴学电子有一个误区 ...

最新文章

  1. 判断一个序列是不是堆的方法
  2. vue router html,vue-router.html
  3. Python中的异常(Exception)处理
  4. 算法分析股票类型的相关题型
  5. 6 redhat 查看rtc时间_Linux EasyStack-Redhat安装Docker
  6. java换水_java-交流灌水之谁是水王?
  7. ISP DSP的不同
  8. 25个学习要点帮助你从java菜鸟成为Java高手
  9. db2离线备份_DB2高危操作LOAD命令风险详解
  10. 怎样用代码方式退出IOS程序
  11. 最好用的五大服装进销存管理软件,强推第一个
  12. 关于查询FileNet PE中用户Inbox信息
  13. pytho_抓取下载音乐歌曲
  14. 逻辑回归实现文本分类
  15. 赵小楼《天道》《遥远的救世主》深度解析(144)问题本身就是答案。需要强调的东西不是本来的那个东西。
  16. 安卓 解析软件包时出现问题
  17. ROB 第一篇 DFS BFS (寻迹算法)
  18. 《2019全国互联网行业程序员就业报告》出炉,程序员平均月薪为1.8W
  19. 加州大学计算机硕士,加州大学伯克利分校cs专业
  20. 王童:知行合一 · 当大数据遇到生物学 | 优秀毕业生专访

热门文章

  1. Speedoffice(word)怎么撤回上一步的操作
  2. linux硬盘异响,完美解决Ubuntu Linux关机异响[SATA硬盘]
  3. word技巧-分节符和连续页码,页眉页脚加线
  4. python主页面_使用Wagtail CMS使用Python检测父页面和子页面...
  5. steam无法连接至计算机,无法连接至steam网络怎么办 无法连接至steam网络解决方法【图文】...
  6. java浅_浅谈Java浅层复制和深层复制
  7. python环境下skimage处理高通道tif图片(10通道)
  8. android studio umake,Android Studio中NDK开发傻瓜教程(CMake)
  9. WebRTC 概念介绍--一篇读懂source、track、sink、mediastream
  10. 解决谷歌disabled状态下操作问题