STM32学习笔记一一红外遥控

发布者:shiwanyongbing最新更新时间:2019-08-15 来源: 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学习笔记一一HEX文件和BIN文件格式
下一篇:小熊arm学习总结:iar7.3建立工程报错

推荐阅读最新更新时间:2024-11-11 15:42

STM32中的PWM的频率和占空比的设置
网上看到一篇文章,不是很完整,但是有助于我理解,个人觉得还可以,具体的代码,网上有很多,大家可以参考参考计算一下。 下面的这个是stm32的定时器逻辑图,上来有助于理解: TIM3的ARR寄存器和PSC寄存器, 确定PWM频率。 这里配置的这两个定时器确定了PWM的频率,我的理解是:PWM的周期(频率)就是ARR寄存器值与PSC寄存器值相乘得来,但不是简单意义上的相乘,例如要设置PWM的频率参考上次通用定时器中设置溢出时间的算法,例如输出100HZ频率的PWM,首先,确定TIMx的时钟,除非APB1的时钟分频数设置为1,否则通用定时器TIMx的时钟是APB1时钟的2倍,这时的TIMx时钟为72MHz,用这个TIMx时钟72
[单片机]
<font color='red'>STM32</font>中的PWM的频率和占空比的设置
基于stm32的FSK调制解调器的设计
大致要求:设计一个FSK调制解调器,基带信号码速率为2000B/s,载波速率为4khz和8khz,解调信号要能完整还原基带信号。实现方法多种多样,通信领域内调制解调器的设计大多数用的都是硬件电路,鉴于笔者对编程情有独钟(其实笔者还是懂一点电路设计知识的~),所以最终决定用stm32来设计,纯编程实现。看起来高大上,但实际做起来不难,不过有挺多东西要考虑的。 总的设计思路如下: 首先是基带信号的产生,它也是我们要调制和解调的目标。基带信号由一连串随机的码元序列构成,为了模拟随机的码元序列,笔者用定时器设计8位的PN码序列,码元速率为2000B/s。定时器3定时0.5ms,每进入一次中断,变量num加一,设置一次IO引脚电平,
[单片机]
基于<font color='red'>stm32</font>的FSK调制解调器的设计
STM32 RTC问题
STM32的RTC用纽扣电池供电,本来考虑将电池正极接到一个AD端口,采集电压值,但发现电池很快消耗殆尽,测量电流得到电流竟然高达20mA,而且单片机是工作的,还能驱动外围电路。 下图是设计的电路图: 下面是出现这种问题的原因:I/O接二极管到VCC。 RTC
[单片机]
<font color='red'>STM32</font> RTC问题
解决STM32 不能读RAM 下载的问题
制作了两个ARM-OB下载器,原以为会很快搞定,谁知道,在最后一步出现了如下的问题: ERROR: RAM check failed @ address 0x20000000. - ERROR: Write: 0xE7FEBE00 E07CE062 - ERROR: Read: 0x0000000 000000000 - ERROR: (0 bytes of RAM have been checked successfully) - ERROR: Failed to read back target memory 我感觉好奇怪啊,三个月前我制作ARM-OB下载器的时候还没有这个问题出现,为什么呢? 百度该问
[单片机]
stm32 外部PB8中断
一、初始化该引脚时钟 RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB ,ENABLE); 二、初始化该引脚为外部中断 void GPIO_Config_Init(void) { GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //PB8 dog_wake GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); } 三、初始化外
[单片机]
STM32PWM实现呼吸灯-库函数
最让我头大的是初始化函数的各个参数的设置,在这里给出pwm_init的模板 pwm.h: #include pwm.h void TIM14_PWM_init(u32 arr, u32 psc) //arr为定时器的自动装载值(决定周期),cnt达到arr时io要置0,psc为预分频系数 { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB1PeriphClockCmd(RCC_AP
[单片机]
工程师STM32单片机学习基础手记(4):用PWM实现荧火虫灯(六)
     DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;   DMA_InitStructure.DMA_Priority = DMA_Priority_High;   DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;   以下是stm32f10x_dma.c中有关DMA的初始化设置代码   tmpreg |= DMA_InitStruct-》DMA_DIR | DMA_InitStruct-》DMA_Mode |   DMA_InitStruct-》DMA_PeripheralInc | DMA_InitStruct-》DMA
[模拟电子]
工程师<font color='red'>STM32</font>单片机学习基础手记(4):用PWM实现荧火虫灯(六)
STM32启动代码分析问题
能否讲解一下startup_stm32f10x_cl.s启动代码含义,谢谢! 我现在看反汇编如下 0x08000000 0678 LSLS r0,r7,#25(查看Memory窗口0x08000000 : 78 06 00 20 ---STM32小端缘故) 0x08000002 2000 MOVS r0,#0x00 0x08000004 1105 ASRS r5,r0,#408 0x08000006 0800 LSRS r0,r0,#00A 。。。。。。。。。。。。。。。。。。。。。。 上面应该对应 __Vectors DCD __initial_sp ; Top of Stack DCD Reset_Handler
[单片机]
小广播
设计资源 培训 开发板 精华推荐

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

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

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved