HX1838遥控模块:

https://item.taobao.com/item.htm?id=622625521668&mi_id=0000QpKWqx-g_1mLa_V1j5beKJFbtLlXWUBSMujz6AUZ8yY&spm=a21xtw.29978518.0.0&xxc=shop

薄膜键盘:

https://item.taobao.com/item.htm?id=540395671190&mi_id=00002J4yZnpfbH1Kd_6cFrbEoKi7cwZ0cv9bLq9sDG13Jec&spm=a21xtw.29978518.0.0&xxc=shop

1、

2、

3、加一下lcd驱动

4、main.h

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.h
  * @brief          : Header for main.c file.
  *                   This file contains the common defines of the application.
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2026 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MAIN_H
#define __MAIN_H

#ifdef __cplusplus
extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include "stm32f1xx_hal.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */

/* USER CODE END ET */

/* Exported constants --------------------------------------------------------*/
/* USER CODE BEGIN EC */

/* USER CODE END EC */

/* Exported macro ------------------------------------------------------------*/
/* USER CODE BEGIN EM */

/* USER CODE END EM */

/* Exported functions prototypes ---------------------------------------------*/
void Error_Handler(void);

/* USER CODE BEGIN EFP */

/* USER CODE END EFP */

/* Private defines -----------------------------------------------------------*/

/* USER CODE BEGIN Private defines */
#define IR_TIMEOUT 50000

// 4×4
#define KEY_COL1_PIN    GPIO_PIN_0
#define KEY_COL2_PIN    GPIO_PIN_1
#define KEY_COL3_PIN    GPIO_PIN_7
#define KEY_COL4_PIN    GPIO_PIN_8
#define KEY_ROW1_PIN    GPIO_PIN_3
#define KEY_ROW2_PIN    GPIO_PIN_4
#define KEY_ROW3_PIN    GPIO_PIN_5
#define KEY_ROW4_PIN    GPIO_PIN_6
#define KEY_PORT        GPIOB

#define KEY_COUNT       16

/* USER CODE END Private defines */

#ifdef __cplusplus
}
#endif

#endif /* __MAIN_H */

5、main.c

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2026 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h> 
#include <string.h> 
#include "GUI.h"
#include "Lcd_Driver.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */
volatile uint32_t ir_last_capture = 0;
volatile uint8_t ir_data[4] = {0};
volatile uint8_t ir_bit_index = 0;
volatile uint8_t ir_byte_index = 0;
volatile uint8_t ir_edge_flag = 0;
volatile uint8_t ir_ready = 0;
volatile uint16_t ir_key_value = 0;
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* ========== IR Remote Control ========== */
void IR_Process(uint32_t pulse_width)
{
    static uint8_t state = 0;
    
    if(pulse_width == 0)
    {
        state = 0;
        ir_byte_index = 0;
        ir_bit_index = 0;
        return;
    }
    
    /* State 0: Wait for header low pulse */
    if(state == 0)
    {
        if(pulse_width > 8000 && pulse_width < 15000)
        {
            state = 1;
        }
        return;
    }
    
    /* State 1: Wait for header high pulse */
    if(state == 1)
    {
        if(pulse_width > 2000 && pulse_width < 8000)
        {
            state = 2;
            ir_byte_index = 0;
            ir_bit_index = 0;
            ir_data[0] = ir_data[1] = ir_data[2] = ir_data[3] = 0;
        }
        else if(pulse_width > 15000)
        {
            state = 0;
        }
        return;
    }
    
    /* State 2: Receive data */
    if(state == 2)
    {
        if(pulse_width > 500 && pulse_width < 2500)
        {
            if(pulse_width > 1500)
            {
                ir_data[ir_byte_index] |= (1 << (7 - ir_bit_index));
            }
            
            ir_bit_index++;
            if(ir_bit_index >= 8)
            {
                ir_bit_index = 0;
                ir_byte_index++;
            }
            
            if(ir_byte_index >= 2)
            {
                ir_key_value = ir_data[1];
                ir_ready = 1;
                state = 0;
            }
        }
        else if(pulse_width > 10000)
        {
            if(ir_byte_index >= 2)
            {
                ir_key_value = ir_data[1];
                ir_ready = 1;
            }
            state = 0;
        }
        return;
    }
}

uint8_t IR_GetKey(void)
{
    if(ir_ready)
    {
        ir_ready = 0;
        return (uint8_t)ir_key_value;
    }
    return 0xFF;
}

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
    if(htim->Instance == TIM5)
    {
        static uint32_t int_count = 0;
        
        uint32_t current_capture = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);
        uint32_t pulse_width = 0;
        
        if(ir_last_capture != 0)
        {
            if(current_capture >= ir_last_capture)
            {
                pulse_width = current_capture - ir_last_capture;
            }
            else
            {
                pulse_width = (65535 - ir_last_capture) + current_capture;
            }
        }
        
        ir_last_capture = current_capture;
        int_count++;
        
        if(pulse_width > 20000)
        {
            ir_last_capture = 0;
            int_count = 0;
            return;
        }
        
        IR_Process(pulse_width);
    }
}

/* ========== 4x4 Matrix Keypad ========== */

/* Keypad key map (4x4) */
const char keypad44_map[4][4] = {
    {'1', '2', '3', 'A'},
    {'4', '5', '6', 'B'},
    {'7', '8', '9', 'C'},
    {'*', '0', '#', 'D'}
};

/* Initialize 4x4 matrix keypad */
void Keypad44_Init(void)
{
    HAL_GPIO_WritePin(KEY_PORT, 
                      KEY_COL1_PIN|KEY_COL2_PIN|KEY_COL3_PIN|KEY_COL4_PIN, 
                      GPIO_PIN_RESET);
}

/* Scan matrix keypad, return key index (0-15), return 0xFF if no key */
uint8_t Keypad44_Scan(void)
{
    uint8_t row, col;
    uint16_t col_pins[4] = {KEY_COL1_PIN, KEY_COL2_PIN, KEY_COL3_PIN, KEY_COL4_PIN};
    uint16_t row_pins[4] = {KEY_ROW1_PIN, KEY_ROW2_PIN, KEY_ROW3_PIN, KEY_ROW4_PIN};
    
    /* Scan each column */
    for(col = 0; col < 4; col++)
    {
        /* Set all columns high, then set current column low */
        HAL_GPIO_WritePin(KEY_PORT, 
                          KEY_COL1_PIN|KEY_COL2_PIN|KEY_COL3_PIN|KEY_COL4_PIN, 
                          (uint16_t)(0x0F << 0));
        HAL_GPIO_WritePin(KEY_PORT, col_pins[col], GPIO_PIN_RESET);
        
        HAL_Delay(1);  /* Short delay for stability */
        
        /* Read all rows */
        for(row = 0; row < 4; row++)
        {
            if(HAL_GPIO_ReadPin(KEY_PORT, row_pins[row]) == GPIO_PIN_RESET)
            {
                /* Key detected, debounce */
                HAL_Delay(20);
                if(HAL_GPIO_ReadPin(KEY_PORT, row_pins[row]) == GPIO_PIN_RESET)
                {
                    /* Wait for key release */
                    while(HAL_GPIO_ReadPin(KEY_PORT, row_pins[row]) == GPIO_PIN_RESET);
                    
                    return col * 4 + row;  /* Return key index (0-15) - FIXED */
                }
            }
        }
    }
    
    return 0xFF;  /* No key pressed */
}

/* Get keypad character */
char Keypad44_GetChar(void)
{
    uint8_t key = Keypad44_Scan();
    if(key != 0xFF)
    {
        return keypad44_map[key / 4][key % 4];
    }
    return 0;
}

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM5_Init();
  MX_USART1_UART_Init();
	/* USER CODE BEGIN 2 */

	printf("=== Test ===\r\n");
	printf("Starting...\r\n");

	HAL_TIM_IC_Start_IT(&htim5, TIM_CHANNEL_1);

	/* Initialize 4x4 matrix keypad */
	Keypad44_Init();

	/* LCD initialization */
	Lcd_Init();
	Lcd_Clear(GRAY0);
	Gui_DrawFont_GBK24(0, 30, RED, GRAY0, (u8*)"2026/03/04");     
	Gui_DrawFont_GBK24(0, 55, RED, GRAY0, (u8*)"2025000000");     
	Gui_DrawFont_GBK16(0, 85, RED, GRAY0, (u8*)"NAME");

	Gui_DrawFont_GBK24(40, 100, BLUE, GRAY0, (u8*)"Ready");

	/* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
static char last_keypad_char = 0;
static uint8_t last_ir_key = 0xFF;

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

    /* USER CODE BEGIN 3 */
    
    /* Scan 4x4 matrix keypad */
    char keypad44_char = Keypad44_GetChar();
    if(keypad44_char != 0)
    {
        printf("Keypad44: %c\r\n", keypad44_char);
        
        if(keypad44_char != last_keypad_char)
        {
            last_keypad_char = keypad44_char;
            
            /* Clear screen and display key */
            Lcd_Clear(WHITE);

            u8 str[20];
            sprintf((char*)str, "Keypad44: %c", keypad44_char);
            Gui_DrawFont_GBK24(25, 70, RED, WHITE, str);
            
            Gui_DrawFont_GBK16(25, 30, BLUE, WHITE, (u8*)"Keyboard Display");
        }
    }
    
    /* Scan IR remote control */
    uint8_t ir_key = IR_GetKey();
    if(ir_key != 0xFF)
    {
        printf("IR Key: 0x%02X\r\n", ir_key);
        
        if(ir_key != last_ir_key)
        {
            last_ir_key = ir_key;
            
            /* Clear screen and display key */
            Lcd_Clear(WHITE);
            
            u8 str[20];
            sprintf((char*)str, "IR: 0x%02X", ir_key);
            Gui_DrawFont_GBK24(25, 70, GREEN, WHITE, str);
            
            Gui_DrawFont_GBK16(25, 30, BLUE, WHITE, (u8*)"IR Remote");
        }
    }
    
    HAL_Delay(50);
    /* USER CODE END 3 */
}
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */
int fputc(int ch,FILE *f)      //锟截讹拷锟斤拷
{
	HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,HAL_MAX_DELAY);
	return ch;
}
int fgetc(FILE *f)            //锟截讹拷锟斤拷
{
	uint8_t ch;
	HAL_UART_Receive(&huart1,(uint8_t *)&ch,1,HAL_MAX_DELAY);
	return ch;
}
/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

6、连接,

传感器+接3.3V,传感器-接地,另一个接接口PA0

7、结果:按遥控器不同按键,输出的key值不同,由测试结果可以看到每个按键都有自己的十六进制编码。

按键盘不同按键,输出键盘对应值。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐