打印
[应用相关]

自定义红外NEC解码,定时器TIM捕获方式

[复制链接]
992|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
硬件准备

首先需要准备一个开发板,这里我准备的是NUCLEO-F030R8的开发板:

选择芯片型号



使用特权

评论回复
沙发
guanjiaer|  楼主 | 2021-8-3 10:50 | 只看该作者
配置时钟源

HSE与LSE分别为外部高速时钟和低速时钟,在本文中使用内置的时钟源,故都选择Disable选项,如下所示:


使用特权

评论回复
板凳
guanjiaer|  楼主 | 2021-8-3 10:51 | 只看该作者
配置时钟树

STM32F0的最高主频到48M,所以配置48即可:


使用特权

评论回复
地板
guanjiaer|  楼主 | 2021-8-3 10:54 | 只看该作者
串口配置

本次实验使用的串口1进行串口通信,波特率配置为115200。


使用特权

评论回复
5
guanjiaer|  楼主 | 2021-8-3 10:55 | 只看该作者
定时器配置

本次使用定时器1的通道2进行检测,配置入下。


使用特权

评论回复
6
guanjiaer|  楼主 | 2021-8-3 10:57 | 只看该作者
红外接收管

这里使用VS838的接收管,如下所示:


使用特权

评论回复
7
guanjiaer|  楼主 | 2021-8-3 11:00 | 只看该作者
红外编码

NEC协议载波:38khz
其逻辑1与逻辑0的表示如图所示:


NEC协议格式:

自定义红外编码

协议如下:


使用特权

评论回复
8
guanjiaer|  楼主 | 2021-8-3 11:01 | 只看该作者
代码
在main.c中,添加头文件,若不添加会出现 identifier “FILE” is undefined报错。

/* USER CODE BEGIN Includes */
#include "stdio.h"
/* USER CODE END Includes */



红外接收口定义

/* USER CODE BEGIN PTD */
#define IR_IN1 HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_9)
/* USER CODE END PTD */


函数声明和串口重定向:

/* USER CODE BEGIN PFP */
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
PUTCHAR_PROTOTYPE
{
    HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);
    return ch;
}
/* USER CODE END PFP */



/* USER CODE BEGIN 0 */
uint32_t OrderData = 0;
uint8_t ReadyFlag = 0;
uint8_t OK = 0;
/* USER CODE END 0 */


定时器配置

  /* USER CODE BEGIN 2 */
        HAL_TIM_Base_Start_IT(&htim1);//启动定时器
        HAL_TIM_IC_Start_IT(&htim1,TIM_CHANNEL_2);//函数用于使能定时器某一通道的输入捕获功能,并使能相应的中断
        printf("IR Capture !! \r\n");
  /* USER CODE END 2 *


使用特权

评论回复
9
guanjiaer|  楼主 | 2021-8-3 11:03 | 只看该作者
红外接收代码

  • [4400,5000]是用于捕获4.5ms的信号
  • [550,700]是用于捕获560us的数据0信号
  • [1100,1250]是用于捕获1120us的数据1信号
  • [2000,2500]是用于捕获2240us的截止位信号



/* USER CODE BEGIN 4 */
// 捕获中断回调函数,每次捕获到信号就会进入这个回调函数
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
        uint32_t fallingCount = 0 ; // 下降沿计数
        uint8_t temp = 0 ;
        // 判断是否是定时器1的外部捕获口2
        if(htim->Instance == TIM1)
        {
                // 捕获到了上升沿
                if(IR_IN1)
                {
                        __HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_2, TIM_INPUTCHANNELPOLARITY_FALLING); // 改变捕获极性为下降沿捕获
                        __HAL_TIM_SET_COUNTER(htim, 0); // 计数清零,从头开始计
                }
                else
                {
                        fallingCount = HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_2); // 读取捕获计数,这个时间即为上升沿持续的时间
                        __HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_2, TIM_INPUTCHANNELPOLARITY_RISING); // 改变捕获极性为上升沿捕获
                        if( ((fallingCount > 4400) && (fallingCount <5000)))
                                OK = 1;/// 4.5ms引导电平
                        else if (((fallingCount > 550) && (fallingCount < 700)))       
                        {
                                temp = 0;//560 us,数据为0
                        }       
                        else if (((fallingCount > 1100) && (fallingCount < 1250)))
                        {
                       
                                temp = 1;//1120 us,数据为1
                        }
                       
                        else if (ReadyFlag==0&& ((fallingCount > 2000) && (fallingCount < 2500)))        //2.240ms截止码
                        {
                          ReadyFlag = 1 ;
                                OK = 0;
                        }
                        if(OK)
                        {
                                OrderData <<= 1 ;
                                OrderData += temp ;
                                KeyCount = 0; // 按键次数
                        }
                }
        }
}
/* USER CODE END 4 */


使用特权

评论回复
10
guanjiaer|  楼主 | 2021-8-3 11:04 | 只看该作者
主函数

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

    /* USER CODE BEGIN 3 */
                if(ReadyFlag)
                {
                        printf("order=%08X , code=%d\r\n",OrderData,OrderData);
                        OrderData = 0;
                        OK = 0;
                        ReadyFlag = 0;               
                }
  }
  /* USER CODE END 3 */


使用特权

评论回复
11
guanjiaer|  楼主 | 2021-8-3 11:05 | 只看该作者
结果演示

红外连续发送5次码值,发送分别为

  • 1011(11)
  • 11 1010(58)
  • 11 0001(49)
  • 11 1111(63)
  • 11 0011(51)

分别如下所示:


使用特权

评论回复
12
香水城| | 2021-8-4 10:06 | 只看该作者
谢谢分享!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

77

主题

4116

帖子

2

粉丝