T527 IR-RX 调试

1、环境介绍

硬件:t527板卡

软件:原厂t527-tina5.0-aiot-v1.4 sdk(buildroot,Linux 5.15)

2、T527 CIR Receiver

t527 有两个独立的 CIR_RX 接口,64×8 位数据缓冲 FIFO,最高支持 1MHz 采样频率,支持 NEC 协议格式的红外数据传输。

3、原理图查看

t527 板卡板载一个 IRM-V838M3-C 红外遥控接收头:

4、设备树配置

&s_irrx {
    pinctrl-names = "default", "sleep";
    pinctrl-0 = <&s_irrx_pins_default>;
    pinctrl-1 = <&s_irrx_pins_sleep>;
    status = "okay";
};

&r_pio {
    s_irrx_pins_default: s_irrx@0 {
        pins = "PM5";
        function = "s_cir";
    };

    s_irrx_pins_sleep: s_irrx@1 {
        pins = "PM5";
        function = "gpio_in";
    };
};

5、内核配置

CONFIG_AW_IR_RX=y

6、验证

root@t527:~ # cat /proc/bus/input/devices
I: Bus=0019 Vendor=0001 Product=0001 Version=0100
N: Name="sunxi_ir_recv"
P: Phys=sunxi_ir_recv/input0
S: Sysfs=/devices/platform/soc@3000000/7040000.s_irrx/rc/rc0/s_cir_rx
U: Uniq=
H: Handlers=kbd event0
B: PROP=20
B: EV=100017
B: KEY=20000000000000 0 0 0 0 0 18000 40000800 1c004000000000 4ffc
B: REL=3
B: MSC=10

7、添加新遥控器

如下是要使用的遥控器,现在为其添加 keymap:

7.1、添加 keymap 文件

进入路径<sdk>/kernel/linux-5.15/drivers/media/rc/keymaps

touch rc-myremote.c
// SPDX-License-Identifier: GPL-2.0+
// myremote.h - Keytable for myremote Remote Controller
//
// Keytable for your custom remote

#include <media/rc-map.h>
#include <linux/module.h>

static struct rc_map_table myremote[] = {
    /* 
    这些数值是按键的扫描码,以 KEY_POWER 为例,
    在开发板执行evtest命令,用红外遥控按下POWER按键,查看扫描码为45:
    Event: time 59120.395400, type 4 (EV_MSC), code 4 (MSC_SCAN), value 45
    每一个按键都是如此操作,自行添加映射关系。
    */
    { 0x45, KEY_POWER },
    { 0x47, KEY_MENU },
    { 0x15, KEY_PLAY },
    { 0x40, KEY_VOLUMEUP },
    { 0x19, KEY_VOLUMEDOWN },
    { 0x09, KEY_FASTFORWARD },
    { 0x07, KEY_FASTREVERSE },
    { 0x0d, KEY_BACKSPACE },
    { 0x43, KEY_BACK },
    { 0x44, KEY_HOME },
    { 0x16, KEY_0 },
    { 0x0c, KEY_1 },
    { 0x18, KEY_2 },
    { 0x5e, KEY_3 },
    { 0x08, KEY_4 },
    { 0x1c, KEY_5 },
    { 0x5a, KEY_6 },
    { 0x42, KEY_7 },
    { 0x52, KEY_8 },
    { 0x4a, KEY_9 },
};

static struct rc_map_list myremote_map = {
    .map = {
        .scan     = myremote,
        .size     = ARRAY_SIZE(myremote),
        .rc_proto = RC_PROTO_NEC, 
        .name     = "rc-myremote",
    }
};

static int __init init_rc_map_myremote(void)
{
    return rc_map_register(&myremote_map);
}

static void __exit exit_rc_map_myremote(void)
{
    rc_map_unregister(&myremote_map);
}

module_init(init_rc_map_myremote);
module_exit(exit_rc_map_myremote);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Cohen0415");

修改 <sdk>/kernel/linux-5.15/drivers/media/rc/keymaps/Makefile

修改<sdk>/kernel/linux-5.15/include/media/rc-map.h

7.2、修改设备树

在设备树中指定要使用的 keymap:

&s_irrx {
    pinctrl-names = "default", "sleep";
    pinctrl-0 = <&s_irrx_pins_default>;
    pinctrl-1 = <&s_irrx_pins_sleep>;
    linux,rc-map-name = "rc-myremote";		// 指定 keymap,这里的名字要和rc_map_list结构体中的name一样
    status = "okay";
};

7.3、驱动注册流程

rc-myremote.c (keymap模块)
       │
       │ module_init(rc_myremote_init)
       ▼
rc_map_register(&rc_myremote_map)
       │
       │ 注册 keymap -> 放入全局 rc_map_list 链表
       ▼
ir 驱动 (sunxi-ir-rx.c: sunxi_irrx_probe)
       │
       │ 解析设备树 linux,rc-map-name = "rc-myremote"
       ▼
rc_dev->map_name = "rc-myremote"
       │
       │ 注册 rc_dev
       ▼
内核遥控子系统根据 map_name 从链表查找并绑定 keymap
       │
       │ 接收到红外扫描码时,查表转换为 input 事件
       ▼
input 子系统上报 KEY_XXX

8、测试

9、总结

参考文章:

《D1_Tina_Linux_红外_开发指南.pdf》

《Linux_IR_RX_开发指南.pdf》

嵌入式Linux学习交流群:424571391

/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : main.c * @brief : Main program body ****************************************************************************** * @attention * * <h2><center>© Copyright (c) 2025 STMicroelectronics. * All rights reserved.</center></h2> * * This software component is licensed by ST under BSD 3-Clause license, * the "License"; You may not use this file except in compliance with the * License. You may obtain a copy of the License at: * opensource.org/licenses/BSD-3-Clause * ****************************************************************************** */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "Lcd_Driver.h" #include "picture.h" #include "DTH11.h" #include "delay.h" #include "stdio.h" #include "string.h" #include "soft_i2c.h" #include "max30102.h" #include "heartRate.h" /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ #define SENSOR_LED_PIN GPIO_PIN_13 // 使用PC13作为传感器状态指示LED #define SENSOR_LED_PORT GPIOC #define DEBUG_PRINT 1 // 启用调试打印 // 声明LCD函数以避免隐式声明警告 void Gui_DrawFont_GBK16(uint16_t x, uint16_t y, uint16_t fc, uint16_t bc, uint8_t *str); /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ ADC_HandleTypeDef hadc1; TIM_HandleTypeDef htim1; UART_HandleTypeDef huart1; /* USER CODE BEGIN PV */ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_USART1_UART_Init(void); static void MX_TIM1_Init(void); static void MX_ADC1_Init(void); /* USER CODE BEGIN PFP */ void calculate_heart_rate_and_spo2(uint32_t *ir_buffer, uint32_t *red_buffer, int16_t *hr, int16_t *spo2); void sensor_init_indicator(void); /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ void USER_UART_CheckFrame(void); static uint16_t ADC_ReadChannel(uint32_t channel); // LED控制宏 #define LED1_ON() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET) #define LED1_OFF() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET) #define LED1_TOGGLE() HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_8) #define LED2_ON() HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET) #define LED2_OFF() HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET) #define LED2_TOGGLE() HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_2) // 传感器状态指示 #define SENSOR_LED_ON() HAL_GPIO_WritePin(SENSOR_LED_PORT, SENSOR_LED_PIN, GPIO_PIN_SET) #define SENSOR_LED_OFF() HAL_GPIO_WritePin(SENSOR_LED_PORT, SENSOR_LED_PIN, GPIO_PIN_RESET) #define SENSOR_LED_TOGGLE() HAL_GPIO_TogglePin(SENSOR_LED_PORT, SENSOR_LED_PIN) // 全局变量定义 uint8_t Temperature=0, Humidity=0; uint16_t readmyDTH11(void); uint8_t label_dth11=0, label=1; char chbuff[32]; #define RX_BUF_LEN 64 uint8_t RxBuf[RX_BUF_LEN]; uint8_t RxCnt = 0; uint8_t RxFrameDone = 0; uint8_t Timlable=0; uint16_t adc_ch1; // 光照传感器 uint16_t adc_ch13; // 雨滴传感器 // 心率血氧计算缓冲区 #define HR_BUFFER_SIZE 10 uint32_t ir_buffer[HR_BUFFER_SIZE]; uint32_t red_buffer[HR_BUFFER_SIZE]; uint8_t buffer_index = 0; uint8_t buffer_filled = 0; // 缓冲区是否填满的标志 // 传感器状态跟踪 uint8_t max30102_data_valid = 0; // 传感器数据是否有效的标志 uint8_t lcd_initialized = 0; // LCD初始化标志 uint8_t system_initialized = 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_USART1_UART_Init(); MX_TIM1_Init(); MX_ADC1_Init(); /* USER CODE BEGIN 2 */ // 初始化顺序:先确保LCD能显示,再初始化传感器 #if DEBUG_PRINT printf("开始系统初始化...\r\n"); #endif // 首先初始化LCD,确保显示功能正常 Lcd_Init(); Lcd_Clear(BLACK); LCD_LED_SET; lcd_initialized = 1; // 显示初始化进度 Gui_DrawFont_GBK16(0, 0, WHITE, BLACK, (u8*)"系统启动中..."); Gui_DrawFont_GBK16(0, 16, WHITE, BLACK, (u8*)"1. 初始化LCD: 完成"); HAL_Delay(500); // 传感器初始化并闪烁指示 sensor_init_indicator(); Gui_DrawFont_GBK16(0, 32, WHITE, BLACK, (u8*)"2. 传感器指示: 完成"); HAL_Delay(500); // 初始化I2C通信 soft_i2c_init(); Gui_DrawFont_GBK16(0, 48, WHITE, BLACK, (u8*)"3. I2C初始化: 完成"); HAL_Delay(500); // 初始化MAX30102传感器 Gui_DrawFont_GBK16(0, 64, WHITE, BLACK, (u8*)"4. 初始化心率传感器..."); max30102_init(); HAL_Delay(500); // 给传感器足够的启动时间 // 检查传感器是否连接 uint8_t id = 0; max30102_read_reg(0x00, &id, 1); // 判断ID是否合理 if(id == 0x15) { max30102_data_valid = 1; Gui_DrawFont_GBK16(0, 64, WHITE, BLACK, (u8*)"4. 心率传感器: 正常"); #if DEBUG_PRINT printf("MAX30102传感器连接正常,ID: 0x%X\r\n", id); #endif } else { Gui_DrawFont_GBK16(0, 64, RED, BLACK, (u8*)"4. 心率传感器: 错误"); #if DEBUG_PRINT printf("MAX30102传感器ID异常: 0x%X\r\n", id); #endif } HAL_Delay(500); // 初始化DHT11传感器 Gui_DrawFont_GBK16(0, 80, WHITE, BLACK, (u8*)"5. 初始化温湿度传感器..."); label = DHT11_Init(); if(label == 0) { Gui_DrawFont_GBK16(0, 80, WHITE, BLACK, (u8*)"5. 温湿度传感器: 正常"); } else { Gui_DrawFont_GBK16(0, 80, RED, BLACK, (u8*)"5. 温湿度传感器: 错误"); } HAL_Delay(500); // 启动定时器和串口 HAL_TIM_Base_Start_IT(&htim1); HAL_UART_Receive_IT(&huart1, &RxBuf[0], 1); // 清除屏幕,准备显示数据 Lcd_Clear(BLACK); // 绘制固定标签 Gui_DrawFont_GBK16(0, 0+32, WHITE, BLACK, (u8*)"温度:"); Gui_DrawFont_GBK16(0, 16+32, WHITE, BLACK, (u8*)"湿度:"); Gui_DrawFont_GBK16(0, 32+32, WHITE, BLACK, (u8*)"光照"); Gui_DrawFont_GBK16(0, 48+32, WHITE, BLACK, (u8*)"雨滴"); Gui_DrawFont_GBK16(0, 64+32, WHITE, BLACK, (u8*)"心率:"); Gui_DrawFont_GBK16(0, 80+32, WHITE, BLACK, (u8*)"血氧:"); // 显示系统状态 Gui_DrawFont_GBK16(0, 120, GREEN, BLACK, (u8*)"系统就绪"); system_initialized = 1; #if DEBUG_PRINT printf("系统初始化完成\r\n"); #endif /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { // 系统状态指示:如果未初始化完成则闪烁LED if(!system_initialized) { LED1_TOGGLE(); HAL_Delay(200); continue; } /* 按键处理 */ if (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_5) == GPIO_PIN_RESET) // KEY1 按下 { HAL_Delay(10); if (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_5) == GPIO_PIN_RESET) { for (int i = 0; i < 3; i++) { LED1_TOGGLE(); HAL_Delay(150); LED1_TOGGLE(); HAL_Delay(150); } while (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_5) == GPIO_PIN_RESET); } } if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_15) == GPIO_PIN_RESET) // KEY2 按下 { HAL_Delay(10); if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_15) == GPIO_PIN_RESET) { for (int i = 0; i < 3; i++) { LED2_TOGGLE(); HAL_Delay(150); LED2_TOGGLE(); HAL_Delay(150); } while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_15) == GPIO_PIN_RESET); } } // 读取温湿度数据 label_dth11 = readmyDTH11(); if(Timlable == 1) { Timlable = 0; SENSOR_LED_TOGGLE(); // 确保LCD已初始化 if(!lcd_initialized) { #if DEBUG_PRINT printf("LCD未初始化,尝试重新初始化...\r\n"); #endif Lcd_Init(); LCD_LED_SET; lcd_initialized = 1; Lcd_Clear(BLACK); // 重新绘制固定标签 Gui_DrawFont_GBK16(0, 0+32, WHITE, BLACK, (u8*)"温度:"); Gui_DrawFont_GBK16(0, 16+32, WHITE, BLACK, (u8*)"湿度:"); // ... 其他标签 } // 处理温湿度数据 if(label_dth11 != 0) { #if DEBUG_PRINT printf("温湿度数据: %d℃, %d%%\r\n", Temperature, Humidity); #endif sprintf(chbuff, "%d℃", Temperature); Gui_DrawFont_GBK16(72, 0+32, WHITE, BLACK, (u8*)chbuff); sprintf(chbuff, "%d%%", Humidity); Gui_DrawFont_GBK16(72, 16+32, WHITE, BLACK, (u8*)chbuff); } else { // 显示错误提示而非空白 Gui_DrawFont_GBK16(72, 0+32, RED, BLACK, (u8*)"--"); Gui_DrawFont_GBK16(72, 16+32, RED, BLACK, (u8*)"--"); } // 处理光照和雨滴传感器 adc_ch1 = ADC_ReadChannel(ADC_CHANNEL_1); adc_ch13 = ADC_ReadChannel(ADC_CHANNEL_13); float v1 = adc_ch1 * 3.3f / 4096.0f; sprintf(chbuff, "%.2fV", v1); Gui_DrawFont_GBK16(72, 32+32, WHITE, BLACK, (u8*)chbuff); float v13 = adc_ch13 * 3.3f / 4096.0f; sprintf(chbuff, "%.2fV", v13); Gui_DrawFont_GBK16(72, 48+32, WHITE, BLACK, (u8*)chbuff); // 处理心率血氧传感器 uint32_t red = 0, ir = 0; int16_t hr = 0, spo2 = 0; // 只有传感器正常时才读取数据 if(max30102_data_valid) { // 读取传感器原始数据 max30102_fifo_read(&red, &ir); // 检查数据是否有效(合理范围内) if(red > 100 && ir > 100) // 排除噪声和无效值 { // 存储数据到缓冲区 ir_buffer[buffer_index] = ir; red_buffer[buffer_index] = red; buffer_index = (buffer_index + 1) % HR_BUFFER_SIZE; // 标记缓冲区是否填满 if(!buffer_filled && buffer_index == 0) { buffer_filled = 1; #if DEBUG_PRINT printf("数据缓冲区已填满,开始计算心率血氧\r\n"); #endif } } // 计算心率血氧(缓冲区填满后才开始计算) if(buffer_filled) { calculate_heart_rate_and_spo2(ir_buffer, red_buffer, &hr, &spo2); } else { // 缓冲区未填满时显示初始值 hr = 70; spo2 = 98; } } else { // 传感器异常时显示固定值 hr = 0; spo2 = 0; } // 显示心率血氧 if(hr == 0 && spo2 == 0) { Gui_DrawFont_GBK16(48, 64+32, RED, BLACK, (u8*)"--"); Gui_DrawFont_GBK16(48, 80+32, RED, BLACK, (u8*)"--"); } else { sprintf(chbuff, "%d bpm", hr); Gui_DrawFont_GBK16(48, 64+32, WHITE, BLACK, (u8*)chbuff); sprintf(chbuff, "%d%%", spo2); Gui_DrawFont_GBK16(48, 80+32, WHITE, BLACK, (u8*)chbuff); } } USER_UART_CheckFrame(); HAL_Delay(30); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } /** * @brief System Clock Configuration * @retval None */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; /** Initializes the CPU, AHB and APB busses clocks */ 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 busses 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(); } PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC; PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) { Error_Handler(); } } /** * @brief ADC1 Initialization Function * @param None * @retval None */ static void MX_ADC1_Init(void) { /* USER CODE BEGIN ADC1_Init 0 */ /* USER CODE END ADC1_Init 0 */ ADC_ChannelConfTypeDef sConfig = {0}; /* USER CODE BEGIN ADC1_Init 1 */ /* USER CODE END ADC1_Init 1 */ /** Common config */ hadc1.Instance = ADC1; hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE; hadc1.Init.ContinuousConvMode = DISABLE; hadc1.Init.DiscontinuousConvMode = DISABLE; hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; hadc1.Init.NbrOfConversion = 1; if (HAL_ADC_Init(&hadc1) != HAL_OK) { Error_Handler(); } /** Configure Regular Channel */ sConfig.Channel = ADC_CHANNEL_1; sConfig.Rank = ADC_REGULAR_RANK_1; sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5; if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN ADC1_Init 2 */ /* USER CODE END ADC1_Init 2 */ } /** * @brief TIM1 Initialization Function * @param None * @retval None */ static void MX_TIM1_Init(void) { /* USER CODE BEGIN TIM1_Init 0 */ /* USER CODE END TIM1_Init 0 */ TIM_ClockConfigTypeDef sClockSourceConfig = {0}; TIM_MasterConfigTypeDef sMasterConfig = {0}; /* USER CODE BEGIN TIM1_Init 1 */ /* USER CODE END TIM1_Init 1 */ htim1.Instance = TIM1; htim1.Init.Prescaler = 7199; htim1.Init.CounterMode = TIM_COUNTERMODE_UP; htim1.Init.Period = 4999; // 50ms触发一次 htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim1.Init.RepetitionCounter = 0; htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; if (HAL_TIM_Base_Init(&htim1) != HAL_OK) { Error_Handler(); } sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN TIM1_Init 2 */ /* USER CODE END TIM1_Init 2 */ } /** * @brief USART1 Initialization Function * @param None * @retval None */ static void MX_USART1_UART_Init(void) { /* USER CODE BEGIN USART1_Init 0 */ /* USER CODE END USART1_Init 0 */ /* USER CODE BEGIN USART1_Init 1 */ /* USER CODE END USART1_Init 1 */ huart1.Instance = USART1; huart1.Init.BaudRate = 115200; huart1.Init.WordLength = UART_WORDLENGTH_8B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Parity = UART_PARITY_NONE; huart1.Init.Mode = UART_MODE_TX_RX; huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart1.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart1) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN USART1_Init 2 */ /* USER CODE END USART1_Init 2 */ } /** * @brief GPIO Initialization Function * @param None * @retval None */ static void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_8|GPIO_PIN_9 |GPIO_PIN_10, GPIO_PIN_RESET); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(GPIOB, GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_7|GPIO_PIN_8, GPIO_PIN_RESET); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8|GPIO_PIN_13, GPIO_PIN_RESET); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET); /*Configure GPIO pins : PC13 PC14 */ GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_14; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); /*Configure GPIO pin : PC5 */ GPIO_InitStruct.Pin = GPIO_PIN_5; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLUP; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); /*Configure GPIO pins : PB11 PB12 PB7 PB8 */ GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_7|GPIO_PIN_8; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /*Configure GPIO pins : PC8 PC9 PC10 */ GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); /*Configure GPIO pins : PA8 PA13 */ GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_13; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /*Configure GPIO pin : PA15 */ GPIO_InitStruct.Pin = GPIO_PIN_15; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLUP; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /*Configure GPIO pin : PD2 */ GPIO_InitStruct.Pin = GPIO_PIN_2; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); } /* USER CODE BEGIN 4 */ // 传感器初始化完成指示:闪烁两次 void sensor_init_indicator(void) { SENSOR_LED_OFF(); HAL_Delay(200); for(int i=0; i<2; i++) { SENSOR_LED_ON(); HAL_Delay(300); SENSOR_LED_OFF(); HAL_Delay(300); } } uint16_t readmyDTH11(void) { if(label != 0) { label = DHT11_Init(); #if DEBUG_PRINT printf("DHT11初始化结果: %d\r\n", label); #endif } if(label == 0) { if (DHT11_Read_Data(&Temperature, &Humidity) == 0) { return 1; } else { #if DEBUG_PRINT printf("DHT11数据读取失败!\r\n"); #endif } } return 0; } /*----------------- 串口重定向 -----------------*/ 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, &ch, 1, HAL_MAX_DELAY); return ch; } /* 串口接收中断回调 */ void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart->Instance != USART1) return; uint8_t c = RxBuf[RxCnt++]; if (c == '\r') { RxFrameDone = 1; RxBuf[RxCnt - 1] = '\0'; } else { if (RxCnt >= RX_BUF_LEN) RxCnt = 0; } HAL_UART_Receive_IT(&huart1, &RxBuf[RxCnt], 1); } void USER_UART_CheckFrame(void) { if (RxFrameDone) { RxFrameDone = 0; if (strcmp((char *)RxBuf, "helloworld") == 0) { char *ack = "good\r\n"; HAL_UART_Transmit(&huart1, (uint8_t *)ack, strlen(ack), HAL_MAX_DELAY); } RxCnt = 0; } } void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { UNUSED(htim); Timlable = 1; } /* ADC读取函数 */ static uint16_t ADC_ReadChannel(uint32_t channel) { ADC_ChannelConfTypeDef sConfig = {0}; sConfig.Channel = channel; sConfig.Rank = 1; sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5; if(HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) { #if DEBUG_PRINT printf("ADC通道配置失败\r\n"); #endif return 0; } HAL_ADC_Start(&hadc1); if(HAL_ADC_PollForConversion(&hadc1, 100) != HAL_OK) { #if DEBUG_PRINT printf("ADC转换超时\r\n"); #endif return 0; } return HAL_ADC_GetValue(&hadc1); } /** * 心率血氧计算函数(简化版,确保基础功能) */ void calculate_heart_rate_and_spo2(uint32_t *ir_buffer, uint32_t *red_buffer, int16_t *hr, int16_t *spo2) { // 计算IR和红光的平均值 uint32_t ir_avg = 0, red_avg = 0; for(uint8_t i = 0; i < HR_BUFFER_SIZE; i++) { ir_avg += ir_buffer[i]; red_avg += red_buffer[i]; } ir_avg /= HR_BUFFER_SIZE; red_avg /= HR_BUFFER_SIZE; // 简单的心率计算:基于IR信号的变化 static uint32_t last_ir_avg = 0; static int16_t current_hr = 70; if(last_ir_avg > 0) { // 根据IR信号变化调整心率 int32_t diff = ir_avg - last_ir_avg; if(abs(diff) > 1000) // 只有明显变化时才调整 { current_hr += (diff > 0) ? 2 : -2; } } last_ir_avg = ir_avg; // 限制心率范围 if(current_hr < 50) current_hr = 50; if(current_hr > 100) current_hr = 100; *hr = current_hr; // 简单的血氧计算 if(ir_avg > 0) { float ratio = (float)red_avg / ir_avg; *spo2 = 95 + (int16_t)((0.5 - ratio) * 10); // 限制血氧范围 if(*spo2 < 90) *spo2 = 90; if(*spo2 > 99) *spo2 = 99; } else { *spo2 = 95; } } /* 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 */ // 错误状态:快速闪烁LED while(1) { LED1_TOGGLE(); HAL_Delay(100); } /* 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) { printf("Assertion failed: file %s on line %d\r\n", file, line); } #endif /* USE_FULL_ASSERT */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 在这上面进行修改
09-17
单片机甲:/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : main.c * @brief : Main program body ****************************************************************************** * @attention * * Copyright (c) 2025 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 <string.h> #include <stdio.h> // 添加stdio.h以支持sprintf函数 /* 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 */ uint8_t rxBuffer1[20]; // USART1接收缓冲区 uint8_t rxBuffer3[20]; // USART3接收缓冲区 uint8_t txBuffer[50]; // 发送缓冲区 uint8_t irStatus = 0; // 红外传感器状态 uint8_t lastIrStatus = 0; // 上一次红外传感器状态 /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); /* USER CODE BEGIN PFP */ void IR_Detection(void); // 添加函数声明 /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 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_TIM2_Init(); MX_USART1_UART_Init(); MX_USART3_UART_Init(); /* USER CODE BEGIN 2 */ HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_2); // 启动USART1接收中断 HAL_UART_Receive_IT(&huart1, rxBuffer1, 1); // 启动USART3接收中断,波特率9600 HAL_UART_Receive_IT(&huart3, rxBuffer3, 1); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ // 调用红外检测函数 IR_Detection(); // 根据红外传感器状态控制PWM输出 if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_15) == GPIO_PIN_SET) { __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_2, 0); } else { __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_2, 180); } // 添加延时以避免过度占用CPU HAL_Delay(100); } /* 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 */ // 统一的UART接收回调函数 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if(huart->Instance == USART1) { // USART1数据处理逻辑 // 例如:可以在这里添加对USART1接收到的数据的处理 // 重新启动接收 HAL_UART_Receive_IT(&huart1, rxBuffer1, 1); } else if(huart->Instance == USART3) { // USART3数据处理逻辑 // 例如:可以在这里添加对USART3接收到的数据的处理 // 重新启动接收 HAL_UART_Receive_IT(&huart3, rxBuffer3, 1); } } // 红外传感器检测函数 void IR_Detection(void) { // 读取红外传感器状态 irStatus = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_15); // 根据当前状态发送对应信息 if(irStatus == GPIO_PIN_SET) { // 障碍物检测到 sprintf((char*)txBuffer, "IR Sensor: No Obstacle\r\n"); } else { // 无障碍物 sprintf((char*)txBuffer, "IR Sensor: Obstacle Detected\r\n"); } // 通过两个串口发送信息 HAL_UART_Transmit(&huart1, txBuffer, strlen((char*)txBuffer), 100); HAL_UART_Transmit(&huart3, txBuffer, strlen((char*)txBuffer), 100); // 添加1秒延时 HAL_Delay(500); } /* 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 */ 单片机乙:/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : main.c * @brief : Main program body ****************************************************************************** * @attention * * Copyright (c) 2025 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 "adc.h" #include "tim.h" #include "usart.h" #include "gpio.h" #include <stdio.h> #include <string.h> /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ /* ??LED?? */ #define LED_PIN GPIO_PIN_13 #define LED_GPIO_PORT GPIOC /* ???? */ #define FILTER_DEPTH 5 // ???????? /* ???? */ #define LIGHT_THRESHOLD_LOW 1000 // ????? #define LIGHT_THRESHOLD_HIGH 3000 // ????? /* ?????? */ #define MOTOR_MIN_SPEED 50 // ??????(????) #define MOTOR_MAX_SPEED 199 // ??????(???????) /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ uint16_t light_value = 0; // ????? uint16_t light_filtered = 0; // ??????? uint16_t motor_speed = 0; // ???? uint16_t filter_buffer[FILTER_DEPTH]; // ????? uint8_t filter_index = 0; // ???? uint8_t led_state = 0; // LED?? char uart_buffer[100]; // ????? uint8_t rxBuffer1[20]; // USART1????? - ???? uint8_t rxBuffer3[20]; // USART3????? - ???? /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); /* USER CODE BEGIN PFP */ uint16_t Read_LightSensor(void); uint16_t ApplyFilter(uint16_t new_value); void Control_Motor(uint16_t light_value); void Send_Data_To_UART(uint16_t light_value, uint16_t motor_speed); /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ /** * ???????? */ uint16_t Read_LightSensor(void) { uint16_t adc_value = 0; /* ??ADC?? */ if(HAL_ADC_Start(&hadc1) != HAL_OK) { Error_Handler(); } /* ?????? */ if(HAL_ADC_PollForConversion(&hadc1, 10) == HAL_OK) { /* ??ADC? */ adc_value = HAL_ADC_GetValue(&hadc1); } return adc_value; } /** * ?????? */ uint16_t ApplyFilter(uint16_t new_value) { uint32_t sum = 0; /* ???????? */ filter_buffer[filter_index] = new_value; filter_index = (filter_index + 1) % FILTER_DEPTH; /* ????? */ for(int i = 0; i < FILTER_DEPTH; i++) { sum += filter_buffer[i]; } return (uint16_t)(sum / FILTER_DEPTH); } /** * ?????? */ void Control_Motor(uint16_t light_value) { // ????????????? // ??ADC????0-4095 // ???????MOTOR_MIN_SPEED-MOTOR_MAX_SPEED // ?????,?????? motor_speed = (light_value * (MOTOR_MAX_SPEED - MOTOR_MIN_SPEED)) / 4095 + MOTOR_MIN_SPEED; // ???????? if(motor_speed > MOTOR_MAX_SPEED) motor_speed = MOTOR_MAX_SPEED; if(motor_speed < MOTOR_MIN_SPEED) motor_speed = 0; // ??????????,???? // ??PWM??? __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_1, motor_speed); } /** * ??????? */ void Send_Data_To_UART(uint16_t light_value, uint16_t motor_speed) { /* ????? */ sprintf(uart_buffer, "Light: %d, Motor Speed: %d\r\n", light_value, motor_speed); /* ???? */ HAL_UART_Transmit(&huart1, (uint8_t *)uart_buffer, strlen(uart_buffer), 100); } /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ /* ???????? */ for(int i = 0; i < FILTER_DEPTH; i++) { filter_buffer[i] = 0; } /* 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_ADC1_Init(); MX_USART1_UART_Init(); MX_USART3_UART_Init(); MX_TIM4_Init(); /* USER CODE BEGIN 2 */ /* ??PWM?? */ HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1); /* ??USART3???? */ HAL_UART_Receive_IT(&huart3, rxBuffer3, 1); /* ??????? */ HAL_UART_Transmit(&huart1, (uint8_t *)"System initialized! Light sensor and motor control enabled.\r\n", 62, 100); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ /* ????? */ light_value = Read_LightSensor(); /* ???? */ light_filtered = ApplyFilter(light_value); /* ?????? */ Control_Motor(light_filtered); /* ??????????? */ Send_Data_To_UART(light_filtered, motor_speed); /* ????????LED - ????????? */ if(light_filtered < LIGHT_THRESHOLD_LOW) { led_state = 1; // ???,LED?? } else if(light_filtered > LIGHT_THRESHOLD_HIGH) { led_state = 0; // ???,LED?? } HAL_GPIO_WritePin(LED_GPIO_PORT, LED_PIN, led_state ? GPIO_PIN_SET : GPIO_PIN_RESET); HAL_Delay(100); // ????,?????? } /* USER CODE END 3 */ } /** * @brief System Clock Configuration * @retval None */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_PeriphCLKInitTypeDef PeriphClkInit = {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(); } PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC; PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) { Error_Handler(); } } /* USER CODE BEGIN 4 */ // UART?????? void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if(huart->Instance == USART1) { // ??USART1?????? // ?????? HAL_UART_Receive_IT(&huart1, rxBuffer1, 1); } else if(huart->Instance == USART3) { // ??USART3?????? // ??:????????????????? // ?????? HAL_UART_Receive_IT(&huart3, rxBuffer3, 1); } } /* 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 */ 串口无法给对方发送信息
06-13
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值