// 定时器中断回调函数,每隔1秒获取一次温湿度数据
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if (htim->Instance == TIM2)
    {
        call_sht11(&Tem, &Hum);
        printf('%d℃  %d%%RH\r\n', Tem, Hum);
    }
}

// 按键中断回调函数,处理按键事件
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    if (GPIO_Pin == KEY1_Pin)
    {
        HAL_Delay(300);
        HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);
        if (HAL_GPIO_ReadPin(LED1_GPIO_Port, LED1_Pin) == GPIO_PIN_SET)
            printf('OUT');
        else
            printf('ENTER');
    }
    else if (GPIO_Pin == KEY2_Pin)
    {
        HAL_Delay(300);
        HAL_GPIO_TogglePin(LED2_GPIO_Port, LED2_Pin);
        if (HAL_GPIO_ReadPin(LED2_GPIO_Port, LED2_Pin) == GPIO_PIN_SET)
            printf('STOP');
        else
            printf('FIRE');
    }
}

// 串口接收中断回调函数,处理串口指令
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if (huart->Instance == USART1)
    {
        if (strstr((const char *)uart1RxBuff, cmdLightupStr) != NULL) // 判断串口是否有发送'LIGHT UP'指令
        {
            HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, GPIO_PIN_RESET);
            printf('LIGHT UP OK');
        }
        else if (strstr((const char *)uart1RxBuff, cmdLightoffStr) != NULL)
        {
            HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, GPIO_PIN_SET);
            printf('LIGHT OFF OK');
        }
        if (strstr((const char *)uart1RxBuff, cmdWaterONStr) != NULL)
        {
            HAL_GPIO_WritePin(LED4_GPIO_Port, LED4_Pin, GPIO_PIN_RESET);
            printf('WATER ON OK');
        }
        else if (strstr((const char *)uart1RxBuff, cmdWateroffStr) != NULL)
        {
            HAL_GPIO_WritePin(LED4_GPIO_Port, LED4_Pin, GPIO_PIN_SET);
            printf('WATER OFF OK');
        }
        uart1RxState = 0;
        uart1RxCounter = 0;
        memset(uart1RxBuff, 0, 128);
        HAL_UART_Receive_IT(&huart1, uart1RxBuff, 1); // 重新启动接收中断
    }
}

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_TIM2_Init();
    MX_ADC1_Init();
    /* USER CODE BEGIN 2 */
    HAL_TIM_Base_Start_IT(&htim2);             // 启动定时器
    HAL_UART_Receive_IT(&huart1, uart1RxBuff, 1); // 启动串口接收中断
    /* USER CODE END 2 */

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

        /* USER CODE BEGIN 3 */

    }
    /* USER CODE END 3 */
}

注意,需要在 CubeMX 中对定时器、ADC、串口等外设进行配置,生成代码后才能使用。同时,需要在对应的 .h 文件中声明以上回调函数。

通过定时器中断来获取温湿度数据,可以避免阻塞主线程,提高按键响应速度。

功能:

  • 使用 SHT11 传感器获取温湿度数据
  • 使用按键控制 LED
  • 使用串口指令控制水泵

主要代码:

  • HAL_TIM_PeriodElapsedCallback: 定时器中断回调函数,用于获取温湿度数据
  • HAL_GPIO_EXTI_Callback: 按键中断回调函数,用于处理按键事件
  • HAL_UART_RxCpltCallback: 串口接收中断回调函数,用于处理串口指令

使用说明:

  1. 在 CubeMX 中配置定时器、ADC、串口等外设
  2. 将代码添加到项目中
  3. 编译并下载到 STM32 开发板
  4. 使用串口工具发送指令控制水泵
  5. 按键控制 LED

代码特点:

  • 使用中断机制提高系统响应速度
  • 使用回调函数简化代码逻辑
  • 使用字符串比较函数 strstr 处理串口指令
  • 使用 HAL_Delay 函数实现延时
  • 使用 HAL_GPIO_WritePin 函数控制 LED 和水泵
  • 使用 printf 函数输出调试信息

优化建议:

  • 可以使用 DMA 传输提高串口通信效率
  • 可以添加错误处理机制提高系统稳定性
  • 可以使用 RTOS 提高系统并发性能
  • 可以使用图形界面工具方便调试和操作
STM32 嵌入式系统温湿度检测与控制

原文地址: https://www.cveoy.top/t/topic/owNq 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录