通过CubeMX配置Stm32+AHT20模块通过Modbus协议读取温湿度

前言

本篇博客用stm32最小​​​​​​核心板+AHT20模块,完成一modbus接口的温湿度Slave设备,能够让上位机PC通过modbus协议获取温湿度。主程序采用多任务框架,比如RT-thread Nano。

一、CubeMX配置

1、配置RCC
在这里插入图片描述
2、配置串口二波特率4800
在这里插入图片描述
3、配置串口二DMA
在这里插入图片描述
4、配置串口一
在这里插入图片描述
5、配置中断
在这里插入图片描述
6、配置时钟
在这里插入图片描述

二、keil配置代码

1、重定向输出串口一

usart.c

#include <stdio.h>
int fputc(int ch,FILE *f)
 
{
    
    
    HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,0xFFFF);    
        //等待发送结束    
    while(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_TC)!=SET){
    
    
    }        
 
    return ch;
}

2、添加中断

stm32f1xx_it.c的串口2中断处理函数
 
void USART2_IRQHandler(void)
{
    
    
  /* USER CODE BEGIN USART2_IRQn 0 */
    uint32_t tmp = 0;
    tmp =__HAL_UART_GET_FLAG(&huart2,UART_FLAG_IDLE); //获取IDLE标志位
    if((tmp != RESET))//idle标志被置位
    {
    
     
        //清除标志位
        //__HAL_UART_CLEAR_IDLEFLAG(&huart2);
        //清除状态寄存器SR,读取SR寄存器可以实现清除SR寄存器的功能
        huart2.Instance->SR;  
        //读取数据寄存器中的数据
        huart2.Instance->DR; 
        HAL_UART_DMAStop(&huart2); //
        // 获取DMA中未传输的数据个数
        dataLength=hdma_usart2_rx.Instance->CNDTR;
        // 接受完成
        isDataEnd = 1;    
        //清除标志位
        __HAL_UART_CLEAR_IDLEFLAG(&huart2);
    }
 
  /* USER CODE END USART2_IRQn 0 */
  HAL_UART_IRQHandler(&huart2);
  /* USER CODE BEGIN USART2_IRQn 1 */
 
  /* USER CODE END USART2_IRQn 1 */
}

3、main.c

添加变量

extern DMA_HandleTypeDef hdma_usart2_rx;
 
//modbus问询帧
uint8_t commands[3][8]={
    
    
{
    
    0x01,0x03,0x00,0x00,0x00,0x02,0xC4,0x38},
{
    
    0x02,0x03,0x00,0x00,0x00,0x02,0xC4,0x38},
{
    
    0x03,0x03,0x00,0x00,0x00,0x02,0xC5,0xE9},
}; 
//modbus应答帧
uint8_t dataBuff[20];
//中断完成标志
uint8_t isDataEnd=0;
//应答帧长度
uint8_t dataLength;
 
//温度
uint16_t temperature;
//湿度
uint16_t humidity;

main函数

int main(void)
{
    
    
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  MX_DMA_Init();
  MX_USART2_UART_Init();
  /* USER CODE BEGIN 2 */
  //使能idle中断
  __HAL_UART_ENABLE_IT(&huart2, UART_IT_IDLE);
  //打开串口DMA接收
  HAL_UART_Receive_DMA(&huart2,dataBuff,sizeof(dataBuff));
  //传感器地址
  uint8_t i=0;
  while (1)
  {
    
    
 
      //中断完成,解析应答帧
    if(isDataEnd){
    
    
        //提取湿度
        humidity=(dataBuff[3] << 8) + (dataBuff[4]);
        //提取温度
        temperature=(dataBuff[5] << 8) + (dataBuff[6]);
        //串口一发送解析结果
        printf("温度: %.1f\t 湿度: %.1f\r\n",temperature/10.0,humidity/10.0);
        memset(dataBuff,0,sizeof(dataBuff));//清空接收数组
        isDataEnd=0;//清除接收结束标志位
    }
    //发送第 i 个传感器的 modbus 问询帧
    HAL_UART_Transmit(&huart2,commands[i],sizeof(commands),0xFFFF);
    //轮询读取三个传感器
    i=(i+1)%3;
    //打开串口DMA接收
    HAL_UART_Receive_DMA(&huart2,dataBuff,sizeof(dataBuff));
    
    //程序运行标志,闪灯
    HAL_Delay(1000);
    HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_13);
 
}

三、结果

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/asdhnkhn/article/details/128446250