NEC的红外遥控协议
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实现红外解码源程序如下:
使用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使能了就行。
上一篇:基于STM32的MS5540c压强温度传感器的应用
下一篇:STM32,KEIL,MDK新建一个工程
推荐阅读最新更新时间:2024-03-16 16:16