STM32F103C8T6红外遥控解码

目录

一、红外遥控

二、输入捕获初始化

捕获两个上升沿或者下降沿得到他们之间一个周期为1US的的波计次数来得到时间

三、NEC解码

四、IC.h函数

红外按键

 五、主函数

六、总结


推荐STM32学习课程:

[6-5] TIM输入捕获_哔哩哔哩_bilibili[6-5] TIM输入捕获是STM32入门教程-2022持续更新中的第17集视频,该合集共计29集,视频收藏或关注UP主,及时了解更多相关视频内容。https://www.bilibili.com/video/BV1th411z7sn?p=17&vd_source=ed36b2700bbc2bac7746c270bc391540

OLED显示屏代码:

STM32F103C8T6延时函数和OLED显示屏代码_HX091624的博客-CSDN博客

一、红外遥控

红外遥控的发射电路是采用红外发光二极管来发出经过调制的红外光波;红外接收电路由红外接收二极管三极管或硅光电池组成,它们将红外发射器发射的红外光转换为相应的电信号,再送后置放大器。以下代码是NEC解码。

接线方式:

二、输入捕获初始化

捕获两个上升沿或者下降沿得到他们之间一个周期为1US的的波计次数来得到时间

#include "stm32f10x.h"                 

uint16_t IR_Time;
uint8_t IR_State=1;
uint8_t IR_Data[4];
uint8_t IR_pData;
uint8_t IR_DataFlag;
uint8_t IR_RepeatFlag;
uint8_t IR_Address;
uint8_t IR_Command;

//初始化
void IC_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	//GPIO
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	//内部时钟
	TIM_InternalClockConfig(TIM1);
	//时基单元 TIM1->高级定时器 1US
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStructure.TIM_Period = 65536 - 1;		//ARR
	TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1;		//PSC
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM1, &TIM_TimeBaseInitStructure);
	//输入捕获
	TIM_ICInitTypeDef TIM_ICInitStructure;
	TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;  //通道1
	TIM_ICInitStructure.TIM_ICFilter = 0xF;
	TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling; //下降沿捕获
	TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
	TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
	TIM_ICInit(TIM1, &TIM_ICInitStructure);
	//主从触发模式  捕获后CNT计数器自动清零
	TIM_SelectInputTrigger(TIM1, TIM_TS_TI1FP1);
	TIM_SelectSlaveMode(TIM1, TIM_SlaveMode_Reset);
	//NVIC
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;  //TIM1中断
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;     //IRQ通道被使能
	NVIC_Init(&NVIC_InitStructure);    	
    //允许CC1IE捕获中断
	TIM_ITConfig(TIM1,TIM_IT_CC1,ENABLE);	
    
    TIM_Cmd(TIM1, ENABLE);
}

//返回时间
uint32_t IC_GetFreq(void)
{
	return (TIM_GetCapture1(TIM1) + 1);
}

三、NEC解码

//以下代码使用了输入捕获来获取两个下降沿之间的时间,使用一个周期为1US的波形作为基准
//通过下降沿捕获得到两个下降沿之间的基准波形的次数,从而得到时间
//再结合NEC解码,即可写出解码过程
//输入捕获中断
void TIM1_CC_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM1,TIM_IT_CC1) == SET)
	{
		if(IR_State==1)		//状态1,等待Start信号或Repeat信号
		{
			IR_Time = IC_GetFreq();
			//如果计时为13.5ms,则接收到了Start信号(判定值在12MHz晶振下为13500,在11.0592MHz晶振下为12442)
			if(IR_Time>13500-500 && IR_Time<13500+500)
			{
				IR_State=2;			//置状态为2
			}
			//如果计时为11.25ms,则接收到了Repeat信号(判定值在12MHz晶振下为11250,在11.0592MHz晶振下为10368)
			else if(IR_Time>11250-500 && IR_Time<11250+500)
			{
				IR_RepeatFlag=1;	//置收到连发帧标志位为1
				IR_State=1;			//置状态为0
			}
			else					//接收出错
			{
				IR_State=1;			//置状态为1
			}
		}
		else if(IR_State==2)		//状态2,接收数据
		{
			IR_Time = IC_GetFreq();
			//如果计时为1120us,则接收到了数据0(判定值在12MHz晶振下为1120,在11.0592MHz晶振下为1032)
			if(IR_Time>1120-500 && IR_Time<1120+500)
			{
				IR_Data[IR_pData/8]&=~(0x01<<(IR_pData%8));	//数据对应位清0
				IR_pData++;			//数据位置指针自增
			}
			//如果计时为2250us,则接收到了数据1(判定值在12MHz晶振下为2250,在11.0592MHz晶振下为2074)
			else if(IR_Time>2240-500 && IR_Time<2240+500)
			{
				IR_Data[IR_pData/8]|=(0x01<<(IR_pData%8));	//数据对应位置1
				IR_pData++;			//数据位置指针自增
			}
			else					//接收出错
			{
				IR_pData=0;			//数据位置指针清0
				IR_State=1;			//置状态为1
			}
			if(IR_pData>=32)		//如果接收到了32位数据
			{
				IR_pData=0;			//数据位置指针清0
                //验证数据是否接收正确 再转存
				if((IR_Data[0] & IR_Data[1])==0 && (IR_Data[2] & IR_Data[3])==0)
				{
					IR_Address=IR_Data[0];	//转存数据
					IR_Command=IR_Data[2];
					IR_DataFlag=1;	//置收到连发帧标志位为1
				}
				IR_State=1;			//置状态为0
			}
		}
	}
	TIM_ClearITPendingBit(TIM1,TIM_IT_CC1);
}

// 红外遥控获取收到数据帧标志位
uint8_t IR_GetDataFlag(void)
{
	if(IR_DataFlag)
	{
		IR_DataFlag=0;
		return 1;
	}
	return 0;
}

// 红外遥控获取收到连发帧标志位
uint8_t IR_GetRepeatFlag(void)
{
	if(IR_RepeatFlag)
	{
		IR_RepeatFlag=0;
		return 1;
	}
	return 0;
}

// 红外遥控获取收到的地址数据
uint8_t IR_GetAddress(void)
{
	return IR_Address;
}

// 红外遥控获取收到的命令数据
uint8_t IR_GetCommand(void)
{
	return IR_Command;
}

四、IC.h函数

红外按键

#ifndef __IC_H
#define __IC_H

//红外按键键码
#define IR_POWER		0x45
#define IR_MODE			0x46
#define IR_MUTE			0x47
#define IR_START_STOP	0x44
#define IR_PREVIOUS		0x40
#define IR_NEXT			0x43
#define IR_EQ			0x07
#define IR_VOL_MINUS	0x15
#define IR_VOL_ADD		0x09
#define IR_0			0x16
#define IR_RPT			0x19
#define IR_USD			0x0D
#define IR_1			0x0C
#define IR_2			0x18
#define IR_3			0x5E
#define IR_4			0x08
#define IR_5			0x1C
#define IR_6			0x5A
#define IR_7			0x42
#define IR_8			0x52
#define IR_9			0x4A

void IC_Init(void);
uint32_t IC_GetFreq(void);
uint8_t IR_GetDataFlag(void);
uint8_t IR_GetRepeatFlag(void);
uint8_t IR_GetAddress(void);
uint8_t IR_GetCommand(void);

#endif

 五、主函数

#include "stm32f10x.h"              
#include "IC.h"

uint8_t Num;
uint8_t Address;
uint8_t Command;

int main(void)
{
	OLED_Init();
	IC_Init();
	//OLED显示屏
	OLED_ShowString(1,1,"ADDR  CMD  NUM");
	OLED_ShowString(2,1,"00    00   000");
	
	while(1)
	{
		if(IR_GetDataFlag() || IR_GetRepeatFlag())	//如果收到数据帧或者收到连发帧
		{
			Address=IR_GetAddress();		//获取遥控器地址码
			Command=IR_GetCommand();		//获取遥控器命令码
			
			OLED_ShowHexNum(2,1,Address,2);	//显示遥控器地址码
			OLED_ShowHexNum(2,7,Command,2);	//显示遥控器命令码
			
			if(Command==IR_VOL_MINUS)		//如果遥控器VOL-按键按下
			{
				Num--;						//Num自减
			}
			if(Command==IR_VOL_ADD)			//如果遥控器VOL+按键按下
			{
				Num++;						//Num自增
			}		
			OLED_ShowNum(2,12,Num,3);		 //显示Num
		}
	}
}

六、总结

参考资料:

舵机控制:https://blog.csdn.net/qq_38824401/article/details/119778153

希望大家多多留言,有任何问题都可评论区留言,需要源代码的评论区留下QQ邮箱

物联沃分享整理
物联沃-IOTWORD物联网 » STM32F103C8T6红外遥控解码

发表评论