定时输入捕获(红外遥控密码锁)(hal库)

目录

定时输入捕获(红外遥控密码锁)

红外遥控

NEC编码

cubemx配置

​编辑

代码实现

密码锁

代码实现


定时输入捕获(红外遥控密码锁)

红外遥控

NEC编码

  1. 引导码

    • 包含一个9ms的高电平,后跟一个4.5ms的低电平。
  2. 数据位

    • 每个数据位由一个560µs的高电平和一个特定时长的低电平组成:
      • 逻辑‘0’:560µs高电平 + 560µs低电平
      • 逻辑‘1’:560µs高电平 + 1690µs低电平
  3. 重发码

    • 通常以约9ms的低电平 + 2.25ms高电平表示。

cubemx配置

复制工程模板,文件名尽量不取中文

打开cubemx文件并配置

 

更新文件 ,添加IR.h和IR.c文件

代码实现

IR.h

#ifndef __IR_H__
#define __IR_H__

#include <main.h>
#include "stdio.h"

#define IR_IN1   HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_9) // 定义宏,读取GPIOE口第9引脚的电平状态

uint8_t GetIR_DataFlag(void); // 声明函数,返回数据接收标志
uint8_t GetIR_RepeatFlag(void); // 声明函数,返回重发信号标志
uint8_t GetIR_Address(void); // 声明函数,返回红外地址
uint8_t GetIR_Command(void); // 声明函数,返回红外命令
void IR_Init(void); // 声明函数,用于初始化红外接收

#endif

 IR.c

#include "IR.h"

uint8_t IR_State = 0; // 红外接收状态
uint8_t IR_Data[4]; // 存储接收到的数据
uint32_t IR_pData = 0; // 数据位计数器
uint8_t IR_DataFlag = 0; // 数据接收标志
uint8_t IR_RepeatFlag = 0; // 重发信号标志
uint8_t IR_Address = 0; // 存储红外地址
uint8_t IR_Command = 0; // 存储红外命令

extern TIM_HandleTypeDef htim1; // 定义外部定时器句柄

uint8_t GetIR_DataFlag(void) // 获取数据接收标志
{
	if(IR_DataFlag) // 如果数据标志为真
	{
		IR_DataFlag = 0; // 重置数据标志
		return 1; // 返回1表示有数据
	}
	return 0; // 返回0表示没有数据
}

uint8_t GetIR_RepeatFlag(void) // 获取重发信号标志
{
	if(IR_RepeatFlag) // 如果重发标志为真
	{
		IR_RepeatFlag = 0; // 重置重发标志
		return 1; // 返回1表示有重发信号
	}
	return 0; // 返回0表示没有重发信号
}

uint8_t GetIR_Address(void) // 获取红外地址
{
	return IR_Address; // 返回当前红外地址
}

uint8_t GetIR_Command(void) // 获取红外命令
{
	return IR_Command; // 返回当前红外命令
}

void IR_Init(void) // 初始化红外接收
{
	HAL_TIM_Base_Start_IT(&htim1); // 启动定时器基础功能
	HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_1); // 启动输入捕获功能
}

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) // 定时器输入捕获回调函数
{
	uint32_t IR_Time = 0; // 存储捕获到的时间
	if(htim->Instance == TIM1) // 判断是否是定时器1的外部捕获口
	{
		// 捕获到了上升沿
		if(IR_IN1) // 如果检测到上升沿
		{
			__HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_FALLING); // 改变捕获极性为下降沿捕获
			__HAL_TIM_SET_COUNTER(htim, 0); // 计数清零,从头开始计
		}
		else // 检测到下降沿
		{
			IR_Time = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1); // 读取捕获计数,这个时间即为上升沿持续的时间
			__HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_RISING); // 改变捕获极性为上升沿捕获
			if ((IR_Time > 4300) && (IR_Time < 4700)) // 判断4.5ms引导电平
			{
				IR_State = 1; // 设置状态为1,表示已经接收到引导信号
			}
			else if (((IR_Time > 2050) && (IR_Time < 2450))) // 判断2.25ms重发电平
			{
				IR_RepeatFlag = 1; // 设置重发标志
			}
			if(IR_State) // 如果接收到引导信号
			{
				if (((IR_Time > 360) && (IR_Time < 860))) // 判断560us数据为0
				{
					IR_Data[IR_pData / 8] &= ~(0x01 << IR_pData % 8); // 清除对应位
					IR_pData++; // 计数器加1
				}	
				else if (((IR_Time > 1490) && (IR_Time < 1990))) // 判断1690us数据为1
				{
					IR_Data[IR_pData / 8] |= (0x01 << IR_pData % 8); // 设置对应位
					IR_pData++; // 计数器加1
				}
				if(IR_pData >= 32) // 如果接收到32位数据
				{
					IR_pData = 0; // 重置数据位计数器
					IR_State = 0; // 重置状态
					if((IR_Data[0] == (uint8_t)~IR_Data[1]) && (IR_Data[2] == (uint8_t)~IR_Data[3])) // 校验数据
					{
						IR_Address = IR_Data[0]; // 存储地址
						IR_Command = IR_Data[2]; // 存储命令
						IR_DataFlag = 1; // 设置数据接收标志
					}
				}
			}
		}
	}
}

测试,添加OLED进来验证

 

main.c添加头文件

#include "IR.h"
#include "OLED.h"

添加变量

    uint32_t Address = 0;
	uint32_t Command = 0;

 初始化

    OLED_Init();
	OLED_Clear(0);
	IR_Init();
/* USER CODE BEGIN WHILE */
  while (1)
  {
		if(GetIR_DataFlag()|| GetIR_RepeatFlag())
		{
			Address = GetIR_Address();
			Command = GetIR_Command();
			OLED_Clear(0);
			OLED_ShowNum(0,0,Address,2,16);
			OLED_ShowNum(0,2,Command,2,16);
		}
    /* USER CODE END WHILE */
		
    /* USER CODE BEGIN 3 */
  }

密码锁


0-22

1-12        2-24        3-94

4-8        5-28        6-90

7-66        8-82        9-74

确认(45)-69

删除(44)-68

归零(07)-7

代码实现

while (1)
  {
		if(GetIR_DataFlag())//不要重发部分|| GetIR_RepeatFlag()
		{
			Address = GetIR_Address();
			Command = GetIR_Command();
			if(Command == 22)//0
			{
				numflag = 1;
				Keynum = 0;
			}
			else if(Command == 12)//1
			{
				numflag = 1;
				Keynum = 1;
			}
			else if(Command == 24)//2
			{
				numflag = 1;
				Keynum = 2;
			}
			else if(Command == 94)//3
			{
				numflag = 1;
				Keynum = 3;
			}
			else if(Command == 8)//4
			{
				numflag = 1;
				Keynum = 4;
			}
			else if(Command == 28)//5
			{
				numflag = 1;
				Keynum = 5;
			}
			else if(Command == 90)//6
			{
				numflag = 1;
				Keynum = 6;
			}
			else if(Command == 66)//7
			{
				numflag = 1;
				Keynum = 7;
			}
			else if(Command == 82)//8
			{
				numflag = 1;
				Keynum = 8;
			}
			else if(Command == 74)//9
			{
				numflag = 1;
				Keynum = 9;
			}
			
			if(numflag)//密码
			{
				numflag = 0;
				if(count<4)
				{
					password *= 10;
					password += Keynum%10;
					count++;
				}
				OLED_Clear(0);
				OLED_ShowString(0,0,(uint8_t *)"password",16);
				OLED_ShowNum(0,2,password,4,16);
			}
			if(Command == 69)//确认
			{
				if(password==1314)//密码正确
				{
					password=0;
					count=0;
					OLED_Clear(0);
					OLED_ShowCHinese(0,0,0);
					OLED_ShowCHinese(16,0,1);
				}
				else//密码错误
				{
					password=0;
					count=0;
					OLED_Clear(0);
					OLED_ShowString(0,0,(uint8_t *)"error",16);
				}
			}
			if(Command == 68)//取消
			{
				password -=(password%10);
				password /=10;
				count--;
				OLED_Clear(0);
				OLED_ShowString(0,0,(uint8_t *)"password",16);
				OLED_ShowNum(0,2,password,4,16);
			}
			if(Command == 7)//归零
			{
				password=0;
				count=0;
				OLED_Clear(0);
				OLED_ShowString(0,0,(uint8_t *)"password",16);
				OLED_ShowNum(0,2,password,4,16);
			}
		}
    /* USER CODE END WHILE */
		
    /* USER CODE BEGIN 3 */
  }

  • 9
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Hal库是一个用于嵌入式系统的硬件访问层库。该库提供了一些函数和接口,用于与硬件设备进行交互。在使用Hal库进行输入捕获测量占空比时,可以按照以下步骤进行操作。 首先,需要选择一个支持输入捕获功能的硬件定时器。然后,需要使用Hal库的相关函数来配置定时器的工作模式和输入捕获功能。 接下来,设置输入捕获的触发源。可以选择外部输入引脚或其他事件作为触发源,当触发事件发生时,定时器会记录下当前的计数值。 然后,启动定时器,开始计数。当触发事件发生时,Hal库会自动记录下当前的计数值,并触发一个输入捕获事件。 在输入捕获事件中,可以通过Hal库提供的接口,获取到输入捕获值。输入捕获值表示两个连续触发事件之间的定时器计数差值。 通过计算输入捕获值与定时器周期的比值,可以得到占空比。占空比表示高电平信号在一个周期内的持续时间占整个周期的比例。 最后,可以根据需求进行进一步的处理,比如计算平均占空比或根据占空比值做一些控制操作。 总之,使用Hal库进行输入捕获测量占空比的步骤包括选择定时器、配置工作模式和输入捕获功能、设置触发源、启动定时器、获取输入捕获值并计算占空比。这样就可以实现对占空比的测量和处理。 ### 回答2: Hal库是一个用于嵌入式系统的硬件抽象层。它提供了一组API,用于管理和访问硬件资源。在使用Hal库时,我们可以使用输入捕获功能来测量信号的占空比。 输入捕获是一种用于测量和记录信号占空比的技术。在嵌入式系统中,我们通常会遇到需要测量某个信号的占空比的情况,例如PWM信号或时钟信号等。通过使用Hal库提供的输入捕获功能,我们可以方便地进行这些测量。 使用Hal库进行输入捕获测量占空比的步骤如下: 1. 初始化输入捕获功能:首先,我们需要初始化Hal库输入捕获功能,以准备开始测量。通常,我们需要设置输入捕获的参数,如计数模式、采样频率等。 2. 开始捕获信号:一旦输入捕获功能初始化完成,我们就可以开始捕获需要测量的信号了。通过调用Hal库提供的相应API函数,我们可以开始记录信号的时间信息。 3. 停止捕获信号:在信号捕获到一定的时间间隔后,我们可以停止捕获。通过调用Hal库提供的停止捕获的函数,我们在此时停止记录时间信息。 4. 计算占空比:一旦停止捕获信号,我们可以使用记录的时间信息计算信号的占空比。通常,我们可以通过测量信号高电平和低电平的持续时间来计算占空比。 总的来说,Hal库输入捕获功能提供了一种方便的方式来测量信号的占空比。通过使用Hal库,我们可以轻松地进行这些测量,并且可以根据需要调整捕获的参数。这使得我们能够更好地理解和控制我们的嵌入式系统中的信号。 ### 回答3: HAL库是一种有助于开发嵌入式系统的开源库。它提供了丰富的功能和API,能够简化硬件驱动和应用程序开发的过程。 在HAL库中,输入捕获是一种测量占空比的功能。占空比是指周期性信号中高电平所占的比例。输入捕获能够准确地测量信号的上升沿和下降沿的时间间隔,并计算出占空比。 在使用HAL库进行输入捕获测量时,首先需要通过初始化GPIO引脚和定时器等外设来配置输入捕获功能。然后,可以使用HAL库提供的API函数来启动输入捕获测量并获取测量结果。 例如,可以使用hal_input_capture_start()函数来启动输入捕获测量,并通过hal_input_capture_get_duty_cycle()函数获取测量结果。这个函数返回一个浮点数,表示输入信号的占空比。 使用HAL库进行输入捕获测量还可以通过设置回调函数来实时获取测量结果。可以使用hal_input_capture_register_callback()函数注册回调函数,在每次捕获到输入信号边沿时,HAL库会调用这个回调函数,并把测量结果作为参数传递给回调函数。 总之,HAL库提供了输入捕获功能,能够帮助开发人员方便地测量信号的占空比。通过合理配置和调用HAL库的API函数,可以实现准确的输入捕获测量,并获取测量结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值