[STM32G4] STM32G431 MCU使用示例:基于CAN通信的温度监控系统

[复制链接]
1815|11
 楼主| 帛灿灿 发表于 2024-12-17 07:51 | 显示全部楼层 |阅读模式
在现代嵌入式系统中,STM32系列微控制器(MCU)以其强大的性能和丰富的外设支持成为了很多开发者的首选。STM32G431是ST公司推出的基于Arm Cortex-M4核心的MCU,具备高速性能和丰富的外围接口,尤其在CAN(Controller Area Network)总线应用中具有优势。本文将通过一个基于STM32G431的温度监控系统示例,来展示如何利用STM32G431的CAN接口进行多控制器通信,并实现温度数据的实时采集与传输。
系统概述在本示例中,我们将设计一个简单的温度监控系统。该系统包含一个PC端主机和多个STM32G431 MCU作为从设备。每个从设备都会通过CAN总线定期向主机报告其所在位置的温度数据。通过这种方式,主机能够收集所有从设备的数据,并进行集中处理。
主要硬件配置
  • 主机:PC,负责接收来自各个STM32G431从设备的温度数据。
  • 从设备:多个STM32G431微控制器,每个控制器都连接一个温度传感器(如DS18B20)。
  • 通信接口:CAN总线,用于主机和各个从设备之间的数据传输。
开发环境
  • 硬件平台:STM32G431开发板
  • 软件工具:STM32CubeIDE,STM32CubeMX,Keil uVision(可选)
  • 编程语言:C语言
  • 温度传感器:DS18B20(数字温度传感器)
代码实现1. STM32G431 MCU的初始化首先,使用STM32CubeMX配置STM32G431的基本外设。启用CAN接口并配置为标准模式。对于温度传感器的读取,可以通过I/O端口进行控制,或使用一个适当的库来读取DS18B20的数据。
以下是STM32G431主机和从机的基本初始化代码:
  1. #include "stm32g4xx_hal.h"
  2. #include "cmsis_os.h"
  3. #include "can.h"
  4. #include "ds18b20.h"

  5. CAN_HandleTypeDef hcan1;
  6. UART_HandleTypeDef huart2;
  7. DS18B20_HandleTypeDef htemp_sensor;

  8. void SystemClock_Config(void);
  9. static void MX_GPIO_Init(void);
  10. static void MX_CAN1_Init(void);
  11. static void MX_USART2_UART_Init(void);
  12. static void MX_DS18B20_Init(void);
  13. void CAN_Transmit(uint8_t* data, uint8_t len);
  14. void CAN_Receive(uint8_t* buffer, uint8_t len);

  15. int main(void)
  16. {
  17.   HAL_Init();
  18.   SystemClock_Config();
  19.   MX_GPIO_Init();
  20.   MX_CAN1_Init();
  21.   MX_USART2_UART_Init();
  22.   MX_DS18B20_Init();

  23.   uint8_t temp_data[8];  // Temperature data buffer
  24.   
  25.   while (1)
  26.   {
  27.     // Read temperature from DS18B20
  28.     float temperature = DS18B20_ReadTemperature(&htemp_sensor);
  29.    
  30.     // Convert temperature to byte data
  31.     temp_data[0] = (uint8_t)(temperature);  // Temperature low byte
  32.     temp_data[1] = (uint8_t)(temperature >> 8);  // Temperature high byte
  33.    
  34.     // Transmit temperature data over CAN
  35.     CAN_Transmit(temp_data, sizeof(temp_data));
  36.    
  37.     HAL_Delay(1000);  // Delay for 1 second
  38.   }
  39. }

  40. static void MX_CAN1_Init(void)
  41. {
  42.   hcan1.Instance = CAN1;
  43.   hcan1.Init.Prescaler = 16;
  44.   hcan1.Init.Mode = CAN_MODE_NORMAL;
  45.   hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
  46.   hcan1.Init.TimeSeg1 = CAN_BS1_8TQ;
  47.   hcan1.Init.TimeSeg2 = CAN_BS2_3TQ;
  48.   hcan1.Init.AutoBusOff = CAN_AUTOBUSOFF_DISABLE;
  49.   hcan1.Init.AutoWakeUp = CAN_AUTOWAKEUP_DISABLE;
  50.   hcan1.Init.TransmitFifoPriority = CAN_TXFIFO_PRIORITY_HIGH;
  51.   
  52.   if (HAL_CAN_Init(&hcan1) != HAL_OK)
  53.   {
  54.     Error_Handler();
  55.   }
  56. }

  57. static void MX_DS18B20_Init(void)
  58. {
  59.   DS18B20_Init(&htemp_sensor, GPIOB, GPIO_PIN_0);
  60. }

  61. void CAN_Transmit(uint8_t* data, uint8_t len)
  62. {
  63.   CAN_TxHeaderTypeDef TxHeader;
  64.   uint32_t TxMailbox;

  65.   TxHeader.StdId = 0x321;
  66.   TxHeader.ExtId = 0x01;
  67.   TxHeader.RTR = CAN_RTR_DATA;
  68.   TxHeader.IDE = CAN_ID_STD;
  69.   TxHeader.DLC = len;
  70.   TxHeader.TransmitGlobalTime = DISABLE;

  71.   if (HAL_CAN_AddTxMessage(&hcan1, &TxHeader, data, &TxMailbox) != HAL_OK)
  72.   {
  73.     Error_Handler();
  74.   }
  75. }

  76. void CAN_Receive(uint8_t* buffer, uint8_t len)
  77. {
  78.   CAN_RxHeaderTypeDef RxHeader;
  79.   
  80.   if (HAL_CAN_GetRxMessage(&hcan1, CAN_RX_FIFO0, &RxHeader, buffer) != HAL_OK)
  81.   {
  82.     Error_Handler();
  83.   }
  84. }
2. PC端接收数据在PC端,您可以使用CAN总线的USB转接模块与PC进行通信,并使用相应的CAN驱动程序读取来自STM32G431从设备的数据。这里展示的是如何在PC端使用Python通过CAN接口接收数据:
  1. import can
  2. import time

  3. def receive_can_data(channel):
  4.     bus = can.interface.Bus(channel=channel, bustype='socketcan')
  5.     while True:
  6.         message = bus.recv()
  7.         print(f"ID: {message.arbitration_id}, Data: {message.data.hex()}")
  8.         time.sleep(1)

  9. if __name__ == '__main__':
  10.     receive_can_data('can0')  # 根据实际的CAN接口名称选择
系统测试与验证完成上述代码编写后,您可以进行系统测试。确保温度传感器正确连接,并且所有STM32G431控制器通过CAN总线与PC进行通信。PC端应该能够接收到每个控制器发送的温度数据并实时显示。
总结本文介绍了如何使用STM32G431微控制器,通过CAN总线实现温度监控系统的设计。STM32G431具备丰富的外设接口,适用于各种通信协议,尤其是CAN总线应用。通过实际代码的示例,我们展示了如何在嵌入式开发中实现温度数据的采集、处理和传输。

公羊子丹 发表于 2024-12-17 07:51 | 显示全部楼层
这个项目看起来不错,CAN总线真的很适合多设备通信,STM32G431性价比也高!
周半梅 发表于 2024-12-17 07:51 | 显示全部楼层
这篇文章对我很有帮助,能否再详细说明一下DS18B20的驱动部分?
童雨竹 发表于 2024-12-17 07:51 | 显示全部楼层
代码写得很清晰,感谢分享!我在用STM32F4的开发板,改一下应该就能用吧。
万图 发表于 2024-12-17 07:52 | 显示全部楼层
使用CAN总线感觉很靠谱,特别是处理多个设备时,稳定性强。
Wordsworth 发表于 2024-12-17 07:52 | 显示全部楼层
这类项目我也做过,CAN总线确实是工业自动化中常用的技术。
Pulitzer 发表于 2024-12-17 07:52 | 显示全部楼层
请问PC端如何通过CAN设备接收数据?有更多资料可以推荐吗?
Bblythe 发表于 2024-12-17 07:53 | 显示全部楼层
看了你的代码,觉得DS18B20的部分可以优化,是否考虑过多线程来做?
Uriah 发表于 2024-12-17 07:53 | 显示全部楼层
这个项目的应用场景很广泛,可以做为温湿度监控系统的一部分,真不错。
Clyde011 发表于 2024-12-17 07:53 | 显示全部楼层
STM32G431这个芯片真的是不错,CAN通信的性能很好,集成度高。
申小林一号 发表于 2024-12-31 17:04 | 显示全部楼层
感谢分享,学习一下
515192147 发表于 2025-3-11 19:33 | 显示全部楼层
推荐 用我们的CANWeb 现场总线,改几个函数几 可以了接口也比较标准,还是 开源的
这 是我们 在电厂的 应用
下图为浙能1个大型电厂的温度采集系统,分2路CANWeb总线,每路带62个8路热电偶IO模块,共992个温度采集点,CAN总线冗余,网关模块冗余,通过2路冗余Profibus DP送电厂国电智深DCS(每路DP总线有10个DP从站地址,但只使用2个DP接口),数据刷新周期小于500毫秒。
054.JPG
048.JPG
开源冗余CANWeb现场总线详细介绍


01CANWeb冗余现场总线介绍.pdf (4.57 MB, 下载次数: 0)
您需要登录后才可以回帖 登录 | 注册

本版积分规则

170

主题

6240

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部