STM32学习笔记一一红外遥控

发布者:心有归属最新更新时间:2019-01-09 来源: eefocus关键字:STM32  红外遥控 手机看文章 扫描二维码
随时随地手机看文章

1. 简述

红外遥控是一种无线、非接触控制技术,具有抗干扰能力强,信息传输可靠,低功耗,低成本。


红外遥控的编码方式目前广泛使用的是: PWM (脉冲宽度调制)的 NEC 协议和 Philips PPM(脉冲位置调制) 的 RC-5 协议的。


1.1 NEC 协议定义

NEC 码的位定义: 一个脉冲对应 560us 的连续载波,一个逻辑 1 传输需要2.25ms(560us 脉冲+1680us 低电平),一个逻辑 0 的传输需要1.125ms(560us 脉冲+560us 低电平)。而遥控接收头在收到脉冲的时候为低电平,在没有脉冲的时候为高电平,这样,我们在接收头端收到的信号为:逻辑 1 应该是 560us 低+1680us 高,逻辑 0 应该是 560us 低 + 560us 高。


发射端逻辑:


在这里插入图片描述

在这里插入图片描述

遥控接收头逻辑:

在这里插入图片描述

在这里插入图片描述


1.2 NEC 协议特点

(1) 8 位地址和 8 位指令长度;

(2)地址和命令 2 次传输(确保可靠性);

(3) PWM 脉冲位置调制,以发射红外载波的占空比代表“0”和“1”;

(4)载波频率为 38Khz;

(5)位时间为 1.125ms 或 2.25ms;


1.3 NEC 遥控指令的数据格式


在这里插入图片描述


采用反码是为了增加传输的可靠性。NEC 码规定的连发码(由 9ms 低电平+2.5m 高电平+0.56ms 低电平+97.94ms 高电平组成),如果在一帧数据发送完毕之后,按键仍然没有放开,则发射重复码,即连发码。


2. 软件实现

上面我们基本了解了 NEC 格式的红外发码和收码的格式,就可以根据通信的协议来完成对应的程序。


程序逻辑:


在这里插入图片描述


2.1 初始化

void Remote_Init(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

NVIC_InitTypeDef NVIC_InitStructure;

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

TIM_ICInitTypeDef TIM_ICInitStructure;


RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE);


GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //下拉输入

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOA,&GPIO_InitStructure);

GPIO_SetBits(GPIOA,GPIO_Pin_1);


TIM_TimeBaseStructure.TIM_Period = 10000;//设定自动重装值,10ms溢出

TIM_TimeBaseStructure.TIM_Prescaler = (72-1);//预分频器,1MHz的计数频率,1us加一

TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//时钟分割

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上计数模式

TIM_TimeBaseInit(TIM5,&TIM_TimeBaseStructure);


TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;//IC2映射到TI5

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(TIM5,&TIM_ICInitStructure);//初始化定时器输入捕获通道

TIM_Cmd(TIM5,ENABLE);//使能定时器5


NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;//TIM5中断

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级1

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;//从优先级3

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);


TIM_ITConfig(TIM5,TIM_IT_Update|TIM_IT_CC2,ENABLE);//允许更新中断,允许CC2IE捕获中断

}



2.2 中断捕获

u8 RmtSta=0;

u16 Dval;

u32 RmtRec=0;

u8 RmtCnt=0;

void TIM5_IRQHandler(void)

{

if(TIM_GetITStatus(TIM5,TIM_IT_Update)!= RESET)

{

if(RmtSta&0x80)//数据接收到标志位

{

RmtSta &= ~0x10;//取消上升沿捕获标记

if((RmtSta&0x0F)==0x00)

RmtSta |= 1<<6;

if((RmtSta&0x0F)<14)

RmtSta++;

else

{

RmtSta &= ~(1<<7);//清空引导标志位

RmtSta &= 0xF0;//清空计数器

}

}

}

if(TIM_GetITStatus(TIM5,TIM_IT_CC2)!=RESET)

{

if(RDATA)//上升沿已经捕获

{

TIM_OC2PolarityConfig(TIM5,TIM_ICPolarity_Falling);//CC1P=1,设置为下降沿捕获

TIM_SetCounter(TIM5,0);//清空定时器数值

RmtSta |= 0x10;//标记上升沿已经被捕获

}

else

{

Dval = TIM_GetCapture2(TIM5);//读取CCR1的值

TIM_OC2PolarityConfig(TIM5,TIM_ICPolarity_Rising);//设置为上升沿捕获

if(RmtSta&0x10)

{

if(RmtSta&0x80)//接收到引导码

{

if(Dval>300&&Dval<800)//高电平为560us

{

RmtRec <<= 1;

RmtRec |= 0;//接收到0码

}

else if(Dval>1400&&Dval<1800)//高电平为1680us

{

RmtRec <<= 1;

RmtRec |= 1;//接收到1码

}

else if(Dval>2200&&Dval<2600)//连发码判断

{

RmtCnt++;

RmtSta &= 0xF0;//清空计数器

}

}

else if(Dval>4200&&Dval<4700)

{

RmtSta |= 1<<7;//记录接收到引导码

RmtCnt = 0;

}

}

RmtSta &= ~(1<<4);

}

}

TIM_ClearFlag(TIM5,TIM_IT_Update|TIM_IT_CC2);

}


2.3 遥控键值扫描

u8 Remote_Scan(void)

{

u8 sta=0;

u8 t1,t2;


if(RmtSta&(1<<6))//得到一个按键的信息

{

t1 = RmtRec>>24;//地址码

t2 = (RmtRec>>16) &  0xFF;//地址反码

if((t1==(u8)~t2)&&t1==REMOTE_ID)//校验遥控识别码以及遥控接收地址

{

t1 = RmtRec >> 8;//控制码

t2 = RmtRec;//控制反码

if(t1==(u8)~t2)

sta = t1;

}

if((sta==0)||((RmtSta&0x80)==0))//接收错误或者按键没有按下

{

RmtSta &= ~(1<<6);//清除接收按键有效标志位

RmtCnt = 0;

}

}

return sta;

}


关键字:STM32  红外遥控 引用地址:STM32学习笔记一一红外遥控

上一篇:stm32按键轮循点灯
下一篇:STM32学习笔记一一待机唤醒

推荐阅读最新更新时间:2024-03-16 16:22

一步一步实现STM32-FOTA系列教程之FLASH静态区读写
前言 在上一篇文章《一步一步实现STM32-FOTA系列教程之STM32-FLASH分区说明》中,对STM32的FLASH进行了人为了分区,分成了 Bootloader分区、主分区、备份分区和静态区四个区域。其中静态区是用来存放系统一些参数信息的,该分区的内容可以通过编程进行读写,如果不人为的破坏该分区,分区里面的信息会一直保存,掉电不丢失,也就是所谓的FLASH模拟EEPROM的功能。 这篇文章就来说说如何在程序中进行FLASH静态区的读写操作,以方便后续的使用。 FLASH静态区使用 我们在FLASH中给静态区分配了32KB大小的空间,即从0x0803 8000 ~ 0x0804 0000 一共 32 * 1024 字节。
[单片机]
STM32的便携式手机蓝牙考勤机系统设计
摘要:在研究各种考勤系统的基础上,提出了一种手机蓝牙实现考勤的方法。该系统采用STM32F103RBT6微处理器作为核心,利用蓝牙模块搜索手机蓝牙设备与本地数据库进行匹配,通过语音播报和液晶显示两种方式给出考勤结果。该设计可以改变传统的被动式考勤方式,且成本低、操作简便。 引言 目前,大部分考勤系统还是磁卡考勤系统,这类系统不仅签到速度慢,而且终端设备和磁卡也造成一定成本和浪费;指纹考勤、人脸识别考勤、视网膜考勤等新一代考勤技术虽然大大地提高了考勤效率和准确率,但是这类考勤机的费用较高、操作比较麻烦。以上几种都是采用被动式的考勤机制,科技的发展和生活节奏的加快为被动式考勤方式带来了新的挑战,手机蓝牙考勤机就是针对以上考勤机的缺
[单片机]
<font color='red'>STM32</font>的便携式手机蓝牙考勤机系统设计
stm32定时器输入捕获pwm
花了两天时间终于把stm32f103的定时器输入捕获弄懂了,这里以TIM3的通道ch1为例,要实现输入捕获需要配置一下寄存器,TIMx_ARR,TIMx_PSC,TIMx_CCMR1,TIMx_CCER,TIMx_DIER,TIMx_CR1,TIMx_CCR1.这里抓取了一些收据手册中寄存器描述的图 下面一一介绍: TIMx_ARR寄存器为自动重装载的值 TIMx_CR1这里了只要用到它的第0位即使能位。 TIMx_CCMR可以配置对应通道映射到那个IC,TI。 这里我们是第一通道故只需配置低8位,cc1s为配置ch1映射到那个TI,IC1PSC为配置是否分频,1c1f为配置是否滤波。 TIMx_psc寄存器 T
[单片机]
STM32之JScope调试
J-Scope是SEGGER公司推出的,可以在目标MCU运行时,实时分析数据并图形化显示的软件。我们一起来了解一下J-Scope吧。 我们在前四篇的文档中介绍了MCU向调试终端输出信息的方法。今天就介绍一个更炫更酷、可以图形化显示数据的调试法宝—JScope。 J-Scope是SEGGER公司推出的,可以在目标MCU运行时,实时分析数据并图形化显示的软件。它不需要像SWO那样需要MCU上面额外的引脚,而是使用标准的调试接口。J-Link驱动4.90之后的版本都有这个软件哦。 J-Scope可以像示波器一样显示多个变量的值,通过读取一个ELF文件,允许选择一定数量的变量可视化,如图 1所示。你可以简单的将目标MCU连接到
[单片机]
<font color='red'>STM32</font>之JScope调试
STM32单片机的原理详解 STM32时钟系统的配置方法
1.概述 时钟 是单片机的脉搏,是单片机的驱动源,使用任何一个外设都必须打开相应的时钟。这样的好处是,如果不使用一个外设的时候,就把它的时钟关掉,从而可以降低系统的功耗,达到节能,实现低功耗的效果。 每个时钟 ti ck,系统都会处理一步数据,这样才能让工作不出现紊乱。 2.原理 首先,任何外设都需要时钟, 51单片机 , STM32 ,430等等,因为 寄存器 是由D触发器组成的,往触发器里面写东西,前提条件是有时钟输入。 51单片机不需要配置时钟,是因为一个时钟开了之后所有的功能都可以用了,而这个时钟是默认开启的,比如有一个水库,水库有很多个门,这些门默认是开启的,所以每个门都会出水,我们需要哪个门的水的时候可以直接用,
[单片机]
<font color='red'>STM32</font>单片机的原理详解 <font color='red'>STM32</font>时钟系统的配置方法
stm32用ucos还是linux
  常见的嵌入式操作系统有两种:用MMU的和不用MMU的。 用MMU的是Windows、 MacOS 、Linux、 Android,不用MMU的是FreeRTOS VxWorks ucOS。 CPU有两种:带MMU的和不带MMU的,带MMU的有Cortex-A系列ARM9、 ARM11系列,不带MMU的有Cortex-M系列。 stm32用ucos还是linux STM32是M系列,不带MMU控制器,不可能运行Linux,当然, STM32能够跑μClinux,但是严格来说,μClinux是不算Linux的。所以对于很多网友有疑问的stm32用ucos还是linux这个问题,我们就知道答案了,stm32是用
[单片机]
一步步写STM32 OS【三】PendSV与堆栈操作
一、什么是PendSV PendSV是可悬起异常,如果我们把它配置最低优先级,那么如果同时有多个异常被触发,它会在其他异常执行完毕后再执行,而且任何异常都可以中断它。更详细的内容在《Cortex-M3 权威指南》里有介绍,下面我摘抄了一段。 OS 可以利用它“缓期执行”一个异常——直到其它重要的任务完成后才执行动 作。悬起 PendSV 的方法是:手工往 NVIC的 PendSV悬起寄存器中写 1。悬起后,如果优先级不够 高,则将缓期等待执行。 PendSV的典型使用场合是在上下文切换时(在不同任务之间切换)。例如,一个系统中有两个就绪的任务,上下文切换被触发的场合可以是: 1、执行一个系统调用 2、系统滴答定时器(SYSTIC
[单片机]
一步步写<font color='red'>STM32</font> OS【三】PendSV与堆栈操作
STM32如何收发float类型数据?
在之前文章里提到了共用体用来传输浮点数的用法,但那篇笔记中没有详细介绍,这篇笔记我们一起来看一看具体实例。 实际应用中,我们可能需要两个设备通过串口传输浮点数据: 本篇笔记为了方便演示,使用串口助手模拟其中一个设备,本篇笔记内容如下: 我们创建一个用于管理float类型数据的共用体: unionfloat_data { floatf_data; uint8_tbyte ; }; 数据的流向如: 本次使用串口助手模拟发送设备,省略了第一步,主要看第②、③步。 创建两个共用体变量,用于发送与接收: unionfloat_datarx_float_data,tx_float_data; 收发相关代码: 左
[单片机]
<font color='red'>STM32</font>如何收发float类型数据?
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved