STM32F407+Cubemx学习&应用[4]——DMA收发ModbusRS485数据——RS485温度传感器

  • 硬件
  • 串口参数
  • Cubemx配置工程
  • Keil中代码
  • 测试

本《STM32F407+Cubemx学习&应用系列》是自己在做工程时学习和琢磨的总结,还有诸多不足希望能够指出。本系列主要针对串口通信的一些应用,和TCP、CAN通信的一些简单应用。

本例程的目的:用RS485通过modus协议读取西星科技非接触式RS485红外线温度传感器测的温度,并用串口打印出来。

本例程的基础例程:https://blog.csdn.net/LW_12345/article/details/121453986《STM32F407+Cubemx学习&应用[2]——时间中断中处理任务(相当于多了个线程,能够处理多任务)》

参考:硬石例程《YSF4_HAL_Modbus_004. 基于Modbus主从机的温湿度数据获取》

硬件

硬石开发板:YS-F4Pro(用于工业控制~~~师兄选的哈)
西星科技非接触式RS485红外线温度传感器一个

串口参数

波特率:9600
数据位:8
校 验:noparity
停止位:1

Cubemx配置工程

时钟配置
STLink下载配置
USART1配置及串口打印
TIM6时间中断配置
USART3配置




注意:我这个版本的PB10和PB11的GPIO Pull-up/Pull-down选项不可选再代码中应该改为GPIO_NOPULL。
GPIO配置

用于RS485的收发数据控制。

其他配置默认

Keil中代码

增加了bsp_MB_host.h,bsp_MB_host.c两个文件,是关于modbus协议的相关文件。

main.c中添加

/* USER CODE BEGIN Includes */
#include "bsp_MB_host.h"
/* USER CODE END Includes */
/* USER CODE BEGIN 0 */
float humidity,temperature;
typedef struct
{uint16_t DATA_01H;uint16_t DATA_02H;uint16_t DATA_03H;uint16_t DATA_04H;uint16_t DATA_05H;uint16_t DATA_06H;uint8_t DATA_10H[64];
}REG_DATA;#define MSG_ERR_FLAG  0xFFFF    // 接收错误 字符间超时
#define MSG_IDLE      0x0000    // 空闲状态
#define MSG_RXING     0x0001    // 正在接收数据
#define MSG_COM       0x0002    // 接收完成
#define MSG_INC       0x8000    // 数据帧不完整(两字符间的空闲间隔大于1.5个字符时间)
#define TIME_OVERRUN  100       // 定义超时时间 ms
/* 私有变量 ------------------------------------------------------------------*/
__IO uint16_t Rx_MSG = MSG_IDLE;   // 接收报文状态
__IO uint8_t rx_flag=0;
__IO uint8_t data_length=0;
#define RX_BUFFSIZE                                  256
REG_DATA reg_value;
__IO uint8_t tmp_Rx_Buf;             // 临时接收缓存
__IO uint16_t RxCount = 0;      // 接收字符计数
#define MB_SLAVEADDR        0x0010 //从机地址 0x0001
#define HoldingReg          0x0000 //保持寄存器 0x0010
int test_count;
/* USER CODE END 0 */
  /* USER CODE BEGIN 2 */__HAL_UART_ENABLE_IT(&huart3,UART_IT_IDLE);HAL_UART_Receive_DMA(&huart3,(uint8_t *)Rx_Buf,RX_BUFFSIZE);Rx_MSG = MSG_IDLE;reg_value.DATA_03H=0x02;      //2个保持寄存器 0x02/* USER CODE END 2 */
   /* USER CODE BEGIN 3 */test_count++;if(test_count==6500000){test_count=0;Rx_MSG = MSG_IDLE;/* 读取线圈状态 */MB_ReadHoldingReg_03H(MB_SLAVEADDR, HoldingReg, reg_value.DATA_03H);rx_flag=1;/* 等待从机响应 */ }/* 接收到一帧的数据,对缓存提取数据 */if(Rx_MSG == MSG_COM){              /* 收到非期望的从站反馈的数据 */if(Rx_Buf[0] != MB_SLAVEADDR){Rx_MSG = MSG_IDLE;continue;}if(rx_flag==1){humidity=(Rx_Buf[3]<<8|Rx_Buf[4]);printf("环境温度:%.1f %RH\n",humidity/100);temperature=(Rx_Buf[5]<<8|Rx_Buf[6]);printf("物体温度:%.1f ℃\n",temperature/100);}static uint16_t crc_check = 0;crc_check = ( (Rx_Buf[RxCount-1]<<8) | Rx_Buf[RxCount-2] );/* CRC 校验正确 */if(crc_check == MB_CRC16((uint8_t*)&Rx_Buf,RxCount-2)) {/* 通信错误 */if(Rx_Buf[1]&0x80){printf("通信错误\n");}}elseprintf("校验错误\n");Rx_MSG = MSG_IDLE;}}/* USER CODE END 3 */
/* USER CODE BEGIN 4 */
void USER_UART_IDLECallback(UART_HandleTypeDef *huart)
{if(huart->Instance ==USART3){if(__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) !=RESET)   {   // 清除空闲中断标志(否则会一直不断进入中断)__HAL_UART_CLEAR_IDLEFLAG(huart);                    // 调用中断处理函数if(Rx_MSG ==MSG_IDLE){// 停止本次DMA传输HAL_UART_DMAStop(huart);                                                         // 计算接收到的数据长度data_length  = RX_BUFFSIZE - __HAL_DMA_GET_COUNTER(&hdma_usart3_rx);// 清零接收缓冲区 Rx_MSG =MSG_COM;      // 重启开始DMA传输 每次255字节数据            }HAL_UART_Receive_DMA(huart, (uint8_t *)Rx_Buf, RX_BUFFSIZE); }}
}
void USER_DMATransmitCplt(DMA_HandleTypeDef *hdma)
{if(hdma->Instance ==DMA1_Stream3){if(__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_TCIF3_7) !=RESET)   {  // 清除空闲中断标志(否则会一直不断进入中断)__HAL_DMA_CLEAR_FLAG(hdma,DMA_FLAG_TCIF3_7);   RS485_RX_MODE();}}
}
/* USER CODE END 4 */

stm32f4xx_it.c添加

/* USER CODE BEGIN EV */
void USER_UART_IDLECallback(UART_HandleTypeDef *huart);
void USER_DMATransmitCplt(DMA_HandleTypeDef *hdma);
/* USER CODE END EV */
  /* USER CODE BEGIN DMA1_Stream3_IRQn 0 */USER_DMATransmitCplt(&hdma_usart3_tx);/* USER CODE END DMA1_Stream3_IRQn 0 */
  /* USER CODE BEGIN USART3_IRQn 1 */USER_UART_IDLECallback(&huart3);  /* USER CODE END USART3_IRQn 1 */

usart.c中添加

/* USER CODE BEGIN 0 */
#include "gpio.h"
/* USER CODE END 0 */

注意对PB10,PB11的GPIO_InitStruct.Pull配置变换为:

    GPIO_InitStruct.Pull = GPIO_NOPULL;
void UART_Tx(uint8_t *Tx_Buf,uint16_t TxCount)
{RS485_TX_MODE();HAL_UART_Transmit_DMA(&huart3, Tx_Buf, TxCount);
}
/* USER CODE END 1 */

测试


RS485总线可以挂多个设备,如果波特率需要切换的请参考:https://blog.csdn.net/LW_12345/article/details/120638654?spm=1001.2014.3001.5502

源码下载:
https://gitee.com/Luweizhiyuan2020/stm32-f407_-cubemx.git
(cubemx_485_1.0)

STM32F407+Cubemx学习应用[4]——DMA收发ModbusRS485数据——RS485温度传感器相关推荐

  1. STM32f407与STM32F103 串口采用DMA收发数据配置方法的异同

    最近有个项目需要用到STM32F407ZET6这款芯片,其中有一个串口收发数据的应用.因为之前有用过STMF32F103ZET6通过DMA收发数据的方案,所以我打算移植之前的代码实现这个功能,STM3 ...

  2. STM32F407霸天虎HAL库CubeMX学习笔记——DS18B20

    STM32F407霸天虎HAL库CubeMX学习笔记--DS18B20 一.软件准备 二.硬件准备 三.CubeMX配置 四.Keil printf重写 tim.c DS18B20.h DS18B20 ...

  3. STM32学习之串口采用DMA收发数据:需要利用状态机加DMA加串口

    写在前面 在学习这一节知识点的时候,真的是感觉太抽象了,没有一个合适的视频讲的我有那种豁然开朗的感觉,直到我看到了这篇文章,大家可以去看看,里面的描述特别形象. 链接:https://blog.csd ...

  4. STM32 CubeMX学习:7. ADC模数转化

    STM32 CubeMX学习:7. ADC模数转化 系列文章目录 前期的准备 点亮 LED 闪烁 LED 定时器闪烁LED PWM控制LED亮度 常见的PWM设备 按键的外部中断 ADC模数转换 串口 ...

  5. 《STM32从零开始学习历程》——DMA直接存储区访问实验例程

    <STM32从零开始学习历程>@EnzoReventon DMA-直接存储区访问实验例程 本章节为DMA直接存储区访问的实验例程讲解,以"正点原子"的例程为基础进行讲解 ...

  6. STM32CUBEIDE(8)----USART通过DMA收发

    STM32CUBEIDE.8----USART收发配置 概述 样品申请 视频教学 csdn课程 生成例程 STM32CUBEIDE配置 串口重定向 串口发送接收函数 HAL_UART_Transmit ...

  7. 【华大测评】+串口DMA收发数据

    串口传输用中断实现的话,要频繁的进入中断函数,这样无疑增加MCU的负担,干扰正常程序的运行,对于一些实时性强的应用,如数字显示应用中,液晶屏显示可能受影响而不能正常显示.用DMA实现串口收发数据,进行 ...

  8. STM32F407ZG 实现DMA收发数据

    正点原子的DMA测试实验,代码只包含了DMA发送数据,而没有接收数据,而我需要实现DMA收发数据,经过查找资料,以及验证,终于实现了DMA发送和接收数据. 本人将dma的驱动代码写入了dma.c和dm ...

  9. Cubemx配置STM32H7串口DMA

    stm32h7串口配置DMA的坑有很多,卡了我一个晚上去解决它,在csdn上找到了可以解决的办法,在此记录一下. cubemx对于串口和DMA的配置并没有过于严格的要求,按照正常去配置即可,主要是以下 ...

最新文章

  1. Java 7代码层面上的更新
  2. 【工具篇】抓包中的王牌工具—Fiddler (1-环境搭建)
  3. SD-WAN如何简化企业网络并节省资金
  4. thymeleaf依赖_玩转SpringBoot集成 Thymeleaf 模版引擎
  5. dart系列之:在dart中使用packages
  6. java 得到checkbox_【JavaWeb】获得选中的checkbox的value
  7. Q104:怎么用ray tracing画基于磨边楔形的“花环(Rosette)”
  8. c语言程序分数化简,C ++中的简化分数
  9. DevOps使用教程 华为云(13)接口测试 怎么编辑设置 批量测试 测试套件
  10. 大型网站技术架构核心原理与案例分析(李智慧)学习笔记2--大型网站架构五大核心要素
  11. XYNUOJ-2139 德莱联盟
  12. cocos2d-x的初步学习二十八之爱消除一
  13. P2973 [USACO10HOL]赶小猪
  14. 之江实验室牵手国科大杭高院 重磅启动全方位合作
  15. JS中.foucus()方法给入力框赋上焦点后,将焦点移动到入力值后面
  16. LinkedIn领英账号达到一周添加好友邀请上限后怎么办?学会这四式三招,你也能解决LinkedIn领英账号添加好友的每周数量限制...
  17. 【最新可用】Oracle官网下载Oracle 11g XE
  18. MissionPlanner日志保存方法
  19. ntp时间同步,各种配置方法
  20. mysql中sql中统计结果四舍五入保留两位小数

热门文章

  1. [问题已处理]-kubernetes中2次不同的oom处理
  2. 苹果阻止升级插件ios12_苹果推出iOS 14,具有小部件和多项应用程序升级
  3. 阿斯汤加瑜伽(Ashtanga Yoga)第一序列学习与实践笔记(一)
  4. java heap space 什么意思_Java heap space 解决方法(转)
  5. Java实现绩点计算
  6. mxgraph进阶(五)搭建mxGraph简单应用
  7. 会计基础(2) - 会计要素与会计科目
  8. 高频电子之EMC电磁兼容
  9. Matlab的感应电动机的动态分析simulink仿真
  10. 搜狗权重批量查询 批量查询搜狗权重的方法