历史上的今天
今天是:2024年10月15日(星期二)
2018年10月15日 | 基于STM32的NEC红外编码解码
2018-10-15 来源:eefocus
NEC的红外遥控协议
![[转载]基于STM32的NEC红外编码解码](https://8.eewimg.cn/news/uploadfile/2018/1015/20181015070156690.gif?imageView2/2/w/550)
The NEC protocol uses pulse distance encoding of thebits. Each pulse is a 560µs long 38kHz carrier burst (about 21 cycles). Alogical "1" takes 2.25ms to transmit, while a logical "0"is only half of that, being 1.125ms. The recommended carrier duty-cycle is 1/4or 1/3.
遥控载波的频率为38KHz,红外发射端发送的编码规则如下:
系统引导码高电平9ms,低电平4.5ms;地址码16位,数据码16位,共32位;0用“高电平0.56ms+低电平0.565ms”来表示,1用“高电平0.56ms+低电平1.6875ms”来表示,结束码用0.5625ms的高电平表示,连发码由9ms高电平+2.5m低电平+0.56ms高电平+97.94ms低电平来表示。
一个简码=引导码+地址码+数据码+结束位。
一个连发码=引导码+地址码+数据码+连发码。
而红外接收端接收到脉冲时为低电平,没有脉冲的时候为高电平,这样在接收端接收到的信号和发射端反相:

当数据发送结束后会加上一个结束码(0.565低电平),若数据发送完后按键仍处于按下状态则以连发码取代结束码,连发码“为由9ms低电平+2.5m高电平+0.56ms低电平+97.94ms高电平”。
![[转载]基于STM32的NEC红外编码解码 [转载]基于STM32的NEC红外编码解码](https://8.eewimg.cn/news/uploadfile/2018/1015/20181015070156199.jpg?imageView2/2/w/550)
![[转载]基于STM32的NEC红外编码解码 [转载]基于STM32的NEC红外编码解码](https://8.eewimg.cn/news/uploadfile/2018/1015/20181015070156288.jpg?imageView2/2/w/550)
上图为红外遥控收发原理图。
用STM32实现红外解码源程序如下:
使用3.5库函数
void TIM2_IRQHandler(void)
{
static u16 IR_LastPluse = 0; // static ±äÁ¿ Ö»µÚÒ»´Îʱ³õʼ»¯
static u8 IR_Sta = 0; //
static u32 IR_Code = 0;
static u8 IR_PluseCnt = 0; //
static u8 IR_Up = 0; //
u16 IR_ThisPluse;
u16 IR_PluseSub;
if ( TIM_GetITStatus( TIM2, TIM_IT_CC4 ) == SET )
{
TIM_ClearFlag( TIM2, TIM_IT_CC4 );
IR_ThisPluse = TIM_GetCapture4( TIM2 );
if ( IR_ThisPluse > IR_LastPluse )
{
IR_PluseSub = IR_ThisPluse - IR_LastPluse;
}
else
{
IR_PluseSub = 0xffff - IR_LastPluse + IR_ThisPluse;
}
IR_LastPluse = IR_ThisPluse;
IR_PluseCnt++;
if ( IR_PluseCnt == 2 )
{
if (( IR_PluseSub > 5000 ) && ( IR_PluseSub < 8000 )) // 10ms~16ms
{
IR_Sta = 0x01;
}
}
else if ( IR_Sta & 0x01 ) // ??????,????
{
if (( IR_PluseSub < 450 ) || ( IR_PluseSub > 1300 )) //less than 0.9ms or more than 2.6ms
{
IR_Sta = 0;
IR_PluseCnt = 0;
IR_Code = 0;
}
else
{
IR_Code <<= 1;
if (( IR_PluseSub > 900 ) && ( IR_PluseSub < 1300 )) // 1.8ms~2.6ms
{
IR_Code |= 0x01;
}
if ( IR_PluseCnt == 34 )
{
CTRL_IR = IR_Code;
IR_Sta = 0x02;
}
}
}
else if ( IR_Sta & 0x02 )
{
switch ( IR_PluseCnt )
{
case 35:
{
if ( ( IR_PluseSub < 4500 ) || ( IR_PluseSub > 7000 ) )// less than 9ms or more than 14ms
{
IR_PluseCnt--;
}
break;
}
case 36:
{
IR_PluseCnt = 34;
if ( ( IR_PluseSub > 45000) && ( IR_PluseSub < 60000 ) ) //90ms~120ms
{
CTRL_IR = IR_Code;
//Á¬·¢Âë
}
break;
}
}
}
}
if ( TIM_GetITStatus( TIM2, TIM_IT_Update ) == SET )
{
TIM_ClearFlag( TIM2, TIM_IT_Update );
IR_Up++;
if ( IR_Up >= 3 )
{
IR_Up=0;
IR_Code = 0;
IR_Sta = 0;
IR_PluseCnt = 0;
IR_PluseSub =0;
Display_Data(CTRL_IR);
}
}
}
void InputCaptureInit( void )
{
TIM_ICInitTypeDef TIM_ICInitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
RCC_Configuration();
NVIC_Configuration();
GPIO_Configuration();
GPIO_ResetBits(GPIOA,T_OE); //disable the chip 4094 output
Turn_Off_All_Red();
Turn_Off_All_Grn();
//GPIO_ResetBits(GPIOC,T_STB); //disable the chip 4094 input
GPIO_SetBits(GPIOA,T_OE); //enable the chip 4094 output
TIM_TimeBaseInitStructure.TIM_Period = 0xffff; // 16???
TIM_TimeBaseInitStructure.TIM_Prescaler = 72*2-1; // 144?? 2us
TIM_TimeBaseInitStructure.TIM_ClockDivision = 0; // ???
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; // ????
TIM_TimeBaseInit( TIM2, &TIM_TimeBaseInitStructure );
TIM_ITConfig( TIM2, TIM_IT_Update, DISABLE );
TIM_ClearFlag(TIM2, TIM_FLAG_Update);
TIM_ICInitStructure.TIM_Channel = TIM_Channel_4; // ????2
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling; // ?????
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStructure.TIM_ICFilter = 0x0;
TIM_ICInit( TIM2, &TIM_ICInitStructure );
TIM_ITConfig( TIM2, TIM_IT_CC4, DISABLE );
TIM_ClearFlag( TIM2, TIM_FLAG_CC4 );
TIM_Cmd( TIM2, ENABLE );
TIM_ITConfig( TIM2,TIM_IT_Update|TIM_IT_CC4 , ENABLE );
}
rcc gpio nvic配置就不写了。记得把用到的挂到时钟线上,tim2用cmd使能了就行。
史海拾趣
|
帮一个网友问的,我也同学习之!希望大家给看看: 如图所示,相当于把电源输出端给短路,请教图中的贴片是什么器件,可以用什么元件代换,还有其他器件损坏吗? … 查看全部问答> |
|
我写的一个USB驱动, 安装后提示, 设备无法启动,代码10 ,一般是什么原因? 我写的一个USB驱动, 安装后提示, 设备无法启动,代码10 ,一般是什么原因? 具体情况是MP3,不成功, 但优盘就可以成功! 请问大家这样的问题怎末解决?… 查看全部问答> |
|
我用单片机做实验,想外接一个键盘和数码管,需要用到BC7281来控制,现在出现一点问题 主要涉及三个口线:DAT,KEY,CLK dat 接了一个20k上拉电阻,KEY,CLK,直接接到CPU上,这和手册是一样的 现在我DAT脚的电压为3.5v,key为1.3v,clk为0v 然后我向clk写 ...… 查看全部问答> |
|
microblaze的FPU貌似开启了,但是计算浮点的时候还是溢出 起初我以为是log函数,没有包含在math。h头文件里面,但是我果断换了一个计算平方根的函数,照样程序溢出,(13.1的ise)。 查看microblaze的属性,发现FPU选择的是 extern,basic我也试过没用,一样溢出。 求大神指点… 查看全部问答> |
|
求教一个问题,我在写彩屏液晶的程序的时候,有16为驱动的程序有8位驱动的程序。有时候都能用,但有时候会就不能用,求分析哈。 TFT彩屏IC:9320 or 9325 接口声明: #define DATAOUT(x) GPIOB->ODR=x; //数据输出 #define DATAOUTH(x) GPIOB-> ...… 查看全部问答> |
|
我是新手 用msp430 timerA想实现一个捕获功能 用一根导线将CCI0A和ACLK连接起来 想测量ACLK的频率 结果进不去中断 以下是代码 求大神帮忙 #include uint ccr[100]; void main( ) { WDTCTL = W ...… 查看全部问答> |
|
智能用电监控、保护系统创意进度帖+自动控制操作演示视频(未带负载) 本帖最后由 ltbytyn 于 2014-1-4 22:40 编辑 $(\'flv_HAb\').innerHTML=(mobileplayer() ? \"\" : AC_FL_RunContent(\'width\', \'500\', \'height\', \'375\', \'allowNetworking\', \'internal\', \'allowScriptAccess\', \'never\', \'src ...… 查看全部问答> |




