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

重庆交通大学信息科学与工程学院

《嵌入式系统基础A》课程

作业报告(第十五周)

班 级: 物联网工程2002

姓名-学号 : 吴泽霖-632007060217

实验项目名称: 数字电路基础与Quartus入门

实验项目性质: 设计性

实验所属课程: 《嵌入式系统基础》

实验室(中心): 南岸校区语音大楼

指 导 教 师 : 娄路

完成时间: 2022 12 14


一、实验内容和任务

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

二、实验要求

1. 分组要求:每个学生独立完成,即1人1组。

2. 程序及报告文档要求:具有较好的可读性,如叙述准确、标注明确、截图清晰等。

3.项目代码上传github,同时把项目完整打包为zip文件,与实验报告(Markdown源码及PDF文件)、作业博客地址一起提交到学习通。

三. 实验过程介绍 (此处可以填博客内容)

一、STM32移植RT_THread

CubeMX安装Nano pack

先获取软件包地址:https://www.rt-thread.org/download/cube/RealThread.RT-Thread.pdsc
打开 CubeMX,从菜单栏 help 进入 Manage embedded software packages 界面,点击 From Url 按钮,进入 User Defined Packs Manager 界面,其次点击 new,填入上述网址,然后点击 check请添加图片描述
然后下载安装

keil MDK安装RT_THread

请添加图片描述

CubeMX新建文件

选择 Nano 组件
(1)点击 Softwares Packages->Select Components,进入组件配置界面,选择 RealThread, 然后根3.1.5版本的,然后点击 OK 按钮请添加图片描述这时会新增Software Packs展开就可以看见添加的RealThread.RT_Thread,勾选相应内容
请添加图片描述

RCC配置
请添加图片描述
SYS配置请添加图片描述USART1配置
请添加图片描述
GPIO选择A3,A4串口,用来点亮LED灯
请添加图片描述NVIC选择
请添加图片描述时钟树配置请添加图片描述
生成项目请添加图片描述

请添加图片描述找到 RTOS,勾选 kernel,点击 OK
请添加图片描述
代码修改
找到Middlewares/RT-Thread/RTOS/kernel文件夹下的board.c文件,修改串口USART2为USART1
请添加图片描述在main.c文件中添加代码:

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
extern void MX_RT_Thread_Init(void);
extern void MX_RT_Thread_Process(void);
 
/* USER CODE END PTD */


在main函数里添加如下代码

  MX_RT_Thread_Init();

while循环中添加代码

HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_4);
		rt_thread_delay(1000);


运行结果

请添加图片描述

二、STM32F103C8基于Modbus协议读取温湿度通过CubeMX配置stm32

RCC配置
请添加图片描述
配置时钟请添加图片描述配置串口二波特率4800
请添加图片描述配置串口二DMA请添加图片描述配置串口一请添加图片描述配置中断请添加图片描述
代码编写

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;
}

添加中断处理
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 */
}

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);

}

效果
请添加图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值