红外遥控器的代码实现方法有两种:
一种是外部中断实现,一种是定时器外部捕获方法实现,外部中断和定时器捕获两种实现方法各有千秋。根据实际的硬件需求进行选择,其中外部中断的实现的方法对应的.c文件如下:
static REMOTE_CTRL remote_ctrl = {0};
#define pRemote_ctrl (&remote_ctrl)
void delay_us(uint32_t microseconds)
{
// SystemCoreClock holds the system clock frequency.
uint32_t loops = (SystemCoreClock / 1000000L) * microseconds / 6; // 每次循环大约4个时钟周期
while (loops > 0)
{
loops--;
__asm("NOP"); // 调用一个NOP汇编指令,确保循环体不会被优化掉
}
}
//读取引脚的电平
#define IrDa_DATA_IN() HAL_GPIO_ReadPin(IR_RECEIVER_GPIO_Port,IR_RECEIVER_Pin)
void Driver_remote_init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/*Configure GPIO pins :IR_RECEIVER_PORT IR_RECEIVER_PIN */
GPIO_InitStruct.Pin = IR_RECEIVER_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(IR_RECEIVER_GPIO_Port, &GPIO_InitStruct);
HAL_NVIC_SetPriority(EXTI4_15_IRQn,3,3);
HAL_NVIC_EnableIRQ(EXTI4_15_IRQn);
memset(pRemote_ctrl, 0, sizeof(REMOTE_CTRL));
}
static uint8_t Infrared_Remote_Delay(void)
{
uint8_t tim = 0;
while(IrDa_DATA_IN())
{
tim++;
delay_us(20);//20us
if(tim == 250)
{
return tim;
}
}
return tim;
}
void HAL_GPIO_EXTI_Falling_Callback(uint16_t GPIO_Pin)
{
uint8_t pulse_time = 0; //脉冲时间
uint8_t leader_code_flag = 0; //引导码标志位
uint8_t irda_data = 0; //红外数据
while(1)
{
if(IrDa_DATA_IN())
{
pulse_time = Infrared_Remote_Delay();
// SEGGER_RTT_printf(0,"pulse_time:%d\r\n",pulse_time);
/* >=5ms 不是有用信号 当出现干扰或者连发码时,也会break跳出while(1)循环 */
if( pulse_time >= 250 )
{
break; /* 跳出while(1)循环 */
}
if(pulse_time >= 145 && pulse_time < 200) /* 获得前导位 4ms~4.5ms */
{
leader_code_flag = 1;
}
else if(pulse_time >= 15 && pulse_time < 25) /* 0.56ms: 0.2ms~1ms */
{
irda_data = 0;
}
else if(pulse_time >= 50 && pulse_time < 65) /* 1.68ms:1ms~2ms */
{
irda_data =1 ;
}
else if( pulse_time >= 75 && pulse_time <= 85 ) /* 2.1ms:2ms~4ms */
{/* 连发码,在第二次中断出现 */
pRemote_ctrl->frame_flag = 1; /* 一帧数据接收完成 */
pRemote_ctrl->frame_cnt++; /* 按键次数加1 */
break; /* 跳出while(1)循环 */
}
if( leader_code_flag == 1 )
{/* 在第一次中断中完成 */
pRemote_ctrl->frame_data <<= 1;
pRemote_ctrl->frame_data += irda_data;
pRemote_ctrl->frame_cnt = 0;
}
}
}
}
/*
* 帧数据有4个字节,第一个字节是遥控的ID,第二个字节是第一个字节的反码
* 第三个数据是遥控的真正的键值,第四个字节是第三个字节的反码
*/
uint8_t IrDa_Process(void)
{
uint8_t first_byte, sec_byte, tir_byte, fou_byte;
uint8_t res = 0;
first_byte = pRemote_ctrl->frame_data >> 24;
sec_byte = (pRemote_ctrl->frame_data>>16) & 0xff;
tir_byte = pRemote_ctrl->frame_data >> 8;
fou_byte

最低0.47元/天 解锁文章
4579

被折叠的 条评论
为什么被折叠?



