STM32输入捕获,实现红外解码,支持长按

2019-07-21 06:57发布

原子哥的板,实测可以超过10米的接收范围,其它的不说了,直接上程序:

硬件初始化部分


static void RCC_Configuration( void ); static void GPIO_Configuration( void ); static void NVIC_Configuration( void );

void InputCaptureInit( void ) { TIM_ICInitTypeDef TIM_ICInitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; RCC_Configuration(); NVIC_Configuration(); GPIO_Configuration(); 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_2; // 选择通道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_CC2, DISABLE ); TIM_ClearFlag( TIM2, TIM_FLAG_CC2 ); TIM_Cmd( TIM2, ENABLE ); TIM_ITConfig( TIM2, TIM_IT_CC2 | TIM_IT_Update, ENABLE ); }
// 使能TIM2和GPIOA的时钟 static void RCC_Configuration( void ) { RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM2, ENABLE ); RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE ); }
// 设置PA1 static void GPIO_Configuration( void ) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin      = GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode   = GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure); }
// 设置NVIC
static void NVIC_Configuration( void ) { NVIC_InitTypeDef NVIC_InitStructure;
/* Enable the TIM2 global Interrupt */ NVIC_InitStructure.NVIC_IRQChannel                          = TIM2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority      = 10; NVIC_InitStructure.NVIC_IRQChannelCmd                    = ENABLE; NVIC_Init(&NVIC_InitStructure); }
解码部分:键值存放在IR_Key
extern volatile INT32U IR_Key; void TIM2_IRQHandler( void ) { static INT16U IR_LastPluse = 0; static INT8U  IR_Sta         = 0; static INT32U IR_Code      = 0; static INT8U  IR_PluseCnt  = 0; static INT8U  IR_Up          = 0; INT16U IR_ThisPluse; INT16U IR_PluseSub;
if ( TIM_GetITStatus( TIM2, TIM_IT_CC2 ) == SET ) { TIM_ClearFlag( TIM2, TIM_IT_CC2 ); IR_Up = 0; IR_ThisPluse = TIM_GetCapture2( 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 )) { IR_Sta = 0x01; } } else if ( IR_Sta & 0x01 ) // 如果引导成功,开始接码 { if (( IR_PluseSub < 450 ) || ( IR_PluseSub > 1300 )) { IR_Sta      = 0; IR_PluseCnt = 0; IR_Code     = 0; } else { IR_Code <<= 1; if (( IR_PluseSub > 900 ) && ( IR_PluseSub < 1300 )) { IR_Code |= 0x01; } if ( IR_PluseCnt == 34 ) { IR_Key = IR_Code; IR_Sta = 0x02; printf( "IR Down is : 0x%8x ", IR_Key ); } } } else if ( IR_Sta & 0x02 ) { switch ( IR_PluseCnt ) { case 35: { if ( ( IR_PluseSub < 4500 ) || ( IR_PluseSub > 7000 ) ) { IR_PluseCnt--; } break; } case 36: { IR_PluseCnt = 34; if ( ( IR_PluseSub > 45000) && ( IR_PluseSub < 60000 ) ) { IR_Key = IR_Code; printf( "IR continue is : 0x%8x ", IR_Key ); } break; } } } } if ( TIM_GetITStatus( TIM2, TIM_IT_Update ) == SET ) { TIM_ClearFlag( TIM2, TIM_IT_Update ); if ( GPIO_ReadInputDataBit( GPIOA, GPIO_Pin_1 ) == SET ) { IR_Up++; if ( IR_Up >= 2 ) { IR_Code     = 0; IR_Sta      = 0; IR_PluseCnt = 0; } } }











友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。