STM32 嵌入式系统温湿度检测与控制
// 定时器中断回调函数,每隔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: 串口接收中断回调函数,用于处理串口指令
使用说明:
- 在 CubeMX 中配置定时器、ADC、串口等外设
- 将代码添加到项目中
- 编译并下载到 STM32 开发板
- 使用串口工具发送指令控制水泵
- 按键控制 LED
代码特点:
- 使用中断机制提高系统响应速度
- 使用回调函数简化代码逻辑
- 使用字符串比较函数
strstr处理串口指令 - 使用
HAL_Delay函数实现延时 - 使用
HAL_GPIO_WritePin函数控制 LED 和水泵 - 使用
printf函数输出调试信息
优化建议:
- 可以使用 DMA 传输提高串口通信效率
- 可以添加错误处理机制提高系统稳定性
- 可以使用 RTOS 提高系统并发性能
- 可以使用图形界面工具方便调试和操作
原文地址: https://www.cveoy.top/t/topic/owNq 著作权归作者所有。请勿转载和采集!