红外遥控器

红外遥控器

前言

使用外部中断和定时器计数实现红外遥控接受信号的解码,本文采用的是NEC编码

一、红外接收信号的波形图

一个完整的红外接收信号,由地址码、地址反码、命令码、命令反码组成
在这里插入图片描述
在这里插入图片描述

二、STM32CubeMX设置

定时器配置

注意:时钟的晶振非常重要,我使用的是外部8M晶振,经过锁相环翻倍成72M频率,再72分频,即最终是1M频率。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
RCC配置如上

中断配置

在这里插入图片描述
在这里插入图片描述
中断设置成下降沿触发

三、程序

红外c文件

uint32_t receive_Code1;
uint32_t receive_Flag1;

void delay_us(uint16_t us)
{
	uint16_t differ = 0xffff-us-5;				
	__HAL_TIM_SET_COUNTER(&htim2,differ);	//设定TIM2计数器起始值
	HAL_TIM_Base_Start(&htim2);		//启动定时器	
	
	while(differ < 0xffff-5)	//判断
	{
		differ = __HAL_TIM_GET_COUNTER(&htim2);		//查询计数器的计数值
	}
		HAL_TIM_Base_Stop(&htim2);
}


uint8_t IR_HighLevelPeriod(void)	//高电平持续时间函数
{
	uint8_t t=0;
	while(HAL_GPIO_ReadPin(EXTI_GPIO_Port,EXTI_Pin)==1) //高电平
	{ 
		t++;
		delay_us(20);
		if(t>=250) return t;	//超时溢出
	}
	return t;
}
//在中断回调函数中完成红外解码
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)	//红外遥控外部中断回调函数   时钟问题很重要    用8M外部晶振经过锁相环调整到72M外部晶振   再72分频
{	
	uint8_t Tim=0,Ok=0,Data,Num=0;
	while(1)
	{
	  if(HAL_GPIO_ReadPin(EXTI_GPIO_Port,EXTI_Pin)==1)
		{
			 Tim = IR_HighLevelPeriod();	//获得此次高电平时间

			 if(Tim>=250) 
			 	break;		//无用的信号
			 if(Tim>=200 && Tim<250)
			 	Ok=1;		//收到起始信号
			 else if(Tim>=60 && Tim<90)
			 	Data=1;		//收到数据1
			 else if(Tim>=10 && Tim<50)
			 	Data=0;		//收到数据0

			 if(Ok==1)
				{
					receive_Code1 <<= 1;    
					receive_Code1 += Data;
					if(Num>=32)      //总共32位   每一次都是Data的数据给 receive_Code1的最后一位,然后receive_Code1左移一位给Data的下一次留缓存空间
					{
						receive_Flag1=1;
				    break;
					}
				}
			 Num++;
		}
	}
}

红外h文件

#include "stm32f1xx_hal.h"
#ifndef __IR__H_
#define __IR__H_


extern uint32_t receive_Code1;
extern uint32_t receive_Flag1;


#endif

main.c文件

while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
//		if(IR_GetDataFlag() || IR_GetRepeatFlag())	//如果收到数据帧或者收到连发帧
//		{
//			Address=IR_GetAddress();		//获取遥控器地址码
//			Command=IR_GetCommand();		//获取遥控器命令码
//			
//			OLED_ShowHexNum(2,1,Address,2);	//显示遥控器地址码
//			OLED_ShowHexNum(2,7,Command,2);	//显示遥控器命令码
		if(receive_Flag1 == 1)
		{
			receive_Flag1 = 0;
			OLED_ShowHexNum(1, 1, receive_Code1, 6);
		}
	}

总结

需要注意的就是定时器的晶振频率

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值