【STM32项目开源】STM32单片机充电桩安全监测系统

目录

一、设计背景和意义

1.1设计背景:

1.2设计意义:

二、实物展示

三、硬件功能介绍

[2.1 硬件清单:](#2.1 硬件清单:)

[2.2 功能介绍:](#2.2 功能介绍:)

四、软件设计流程图

五、硬件PCB展示

六、软件主函序展示

七、单片机实物资料

[资料获取 查看主页介绍:兆龙电子单片机设计](#资料获取 查看主页介绍:兆龙电子单片机设计)


一、设计背景和意义

1.1设计背景:

在新能源汽车普及提速的背景下,家用壁挂式充电桩、小区公共充电桩、商用快充桩的日常安全运行、无人值守场景下的异常预警、充电过程全状态监控、故障快速溯源及普通用户简易查看充电状态,成为充电桩使用的核心需求。传统充电桩监测方式存在明显局限:一方面,高端商用充电桩监控系统(如定制化充电桩运维平台、工业级多参数监测网关、品牌成套快充桩监控设备)功能虽全但成本高昂,部署复杂且需专业人员上门调试与后期维护,难以普及到家用充电桩、小型小区配套充电桩及零散布设的便民充电桩等日常场景,且系统生态封闭性强,不同品牌、不同协议的充电桩与监测设备兼容性差,无法与个人移动终端、小区物业监控平台灵活联动,更换或升级成本高,无法满足不同人群(如私家车主、小区物业管理人员、便民充电桩运维人员)的便捷安全监测需求;另一方面,普通简易充电桩监测装置(如传统过载保护开关、单一电压检测模块、基础款指示灯告警装置)虽操作简单、价格低廉,但功能单一,仅能实现单一项安全参数的基础监测或被动保护,缺乏多参数协同监测、异常状态智能判断、充电数据存储、远程状态推送及故障精准定位提醒(如过温报警、漏电故障、充电接口接触不良)等功能,无法满足现代化充电桩使用场景下对全面覆盖、智能响应、便捷高效的安全管控与运维需求。

现有关充电桩安全监测方案还存在功能割裂与集成度低的问题:部分高端商用充电桩监控系统虽具备多维度参数监测与远程运维功能,但依赖复杂的软硬件架构与专属生态维护,后期使用成本高,难以覆盖预算有限的私家车主、小型小区物业或零散便民充电桩的运维场景;而低成本充电桩监测装置又在功能完整性与智能化上存在欠缺,无法实现监测数据与充电桩终端、移动 APP、物业监控平台的实时联动,导致异常预警延迟、参数监测误差偏大、个性化需求(如家用充电桩夜间充电过温提醒、公共充电桩故障远程上报)无法满足等问题,无法为充电桩安全稳定运行(如无人值守场景下的主动预警)及高效运维管理(如精准溯源充电桩故障隐患)提供可靠支撑。基于此,本设计以 STM32 单片机为核心,融合高精度安全监测与辅助模块(如电流电压采集模块、温度湿度监测模块、漏电检测模块、烟雾感应模块)、LCD 显示模块、数据存储模块及蓝牙通信与异常提醒模块,构建低成本、高集成度的物联网充电桩安全监测系统,以解决传统充电桩监测方式操作繁琐、智能化程度低、功能单一及充电桩安全管控效率低的问题。

1.2设计意义:

从使用体验与充电桩安全管控效率角度,该系统突破了传统充电桩监测方式的局限:一是实现了多维度安全监测与全流程充电状态联动(如支持电流电压采集、温湿度实时监测、漏电故障检测、烟雾火情感应,联动蓝牙通信模块、异常声光提醒模块、充电桩安全保护执行模块),无需运维人员或车主现场逐一排查参数与设备状态,减少充电桩监测的繁琐性与异常预警的延迟性;二是配备 OLED 实时显示模块,直观呈现当前充电桩运行参数(电流 / 电压 / 温度)、充电进度、系统运行状态(正常 / 异常)及故障报警类型,同时支持数据自动存储(可通过蓝牙传输至移动 APP / 小区物业监控平台 / 充电桩运维管理平台),方便用户与运维人员长期追溯充电历史数据与设备运行记录,也为优化充电桩安全管控方案、排查设备故障隐患及充电桩集群高效运维提供完整数据支撑;三是新增个性化安全预警与自动保护执行功能,当监测到异常参数(如过流 / 过压 / 过温、漏电故障、烟雾报警、充电接口接触不良),系统根据故障类型自动触发对应执行动作(同时通过声光提醒模块反馈预警信息与设备当前故障状态,蓝牙同步推送至关联移动终端),并联动充电桩执行安全保护操作(如联动过温故障,自动切断充电回路、发送远程预警信息、记录故障发生时间与参数数据),无需人工现场干预即可实现充电桩的智能化安全管控,大幅提升了充电桩监测的便捷性与安全运维的高效性。

从技术实践与成本控制角度,本设计以 STM32 单片机为核心,充分利用其低功耗、高性价比的优势,搭配低成本的高精度安全监测模块及通用外围模块,在保证监测精度(核心参数监测准确率可控制在 98% 以上,异常预警响应时间可控制在 0.5 秒以内)的前提下,有效降低了系统整体成本,相比同功能的高端商用充电桩监控系统成本降低 40%-60%,更易普及到家用壁挂式充电桩、小型小区配套充电桩、零散布设便民充电桩及老旧充电桩安全改造等场景。同时,系统支持模块化扩展(如后续可新增充电桩远程启停功能、多充电桩集群组网监测功能、充电费用统计与异常故障溯源功能),为后续功能升级预留了空间,具备良好的灵活性与可扩展性。

**二、**实物展示

下方为实物演示视频

演示视频https://www.bilibili.com/video/BV1NTHkzNEeC/?spm_id_from=333.1387.upload.video_card.click&vd_source=2a672ca4e8794dca68cbe6d047b42ca5

下方为实物展示图片

三、硬件功能介绍

2.1 硬件清单:

  • STM32F103C8T6

  • OLED显示

  • 温湿度传感器

  • MQ-2烟雾传感器

  • 降压电路

  • 红外对射传感器

  • WIFI 模块

2.2 功能介绍:

(1)利用光电传感器实时监测并统计充电桩车辆数量

(2)通过温湿度传感器采集充电桩环境温湿度数据

(3)借助MQ-7传感器检测充电桩周围危险气体浓度,判断是否超标

(4)在出现异常状态时,触发蜂鸣器进行声光报警

(5)通过OLED显示屏实时显示车辆进出数量及温湿度信息

(6)接入WIFI机智云平台,支持手机App远程监控各项数据

(7)手机App功能,可灵活调节报警阈值及启停报警模式

四、软件设计流程图

五、硬件PCB展示

六、软件主函序展示

复制代码
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
  PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    Error_Handler();
  }
}

/**
  * @brief NVIC Configuration.
  * @retval None
  */
static void MX_NVIC_Init(void)
{
  /* TIM2_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(TIM2_IRQn, 1, 0);
  HAL_NVIC_EnableIRQ(TIM2_IRQn);
  /* USART2_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(USART2_IRQn);
}

/**
  * @brief ADC1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_ADC1_Init(void)
{

  /* USER CODE BEGIN ADC1_Init 0 */

  /* USER CODE END ADC1_Init 0 */

  ADC_ChannelConfTypeDef sConfig = {0};

  /* USER CODE BEGIN ADC1_Init 1 */

  /* USER CODE END ADC1_Init 1 */

  /** Common config
  */
  hadc1.Instance = ADC1;
  hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
  hadc1.Init.ContinuousConvMode = DISABLE;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.NbrOfConversion = 1;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_4;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN ADC1_Init 2 */

  /* USER CODE END ADC1_Init 2 */

}

/**
  * @brief I2C1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_I2C1_Init(void)
{

  /* USER CODE BEGIN I2C1_Init 0 */

  /* USER CODE END I2C1_Init 0 */

  /* USER CODE BEGIN I2C1_Init 1 */

  /* USER CODE END I2C1_Init 1 */
  hi2c1.Instance = I2C1;
  hi2c1.Init.ClockSpeed = 400000;
  hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
  hi2c1.Init.OwnAddress1 = 0;
  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c1.Init.OwnAddress2 = 0;
  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  if (HAL_I2C_Init(&hi2c1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN I2C1_Init 2 */

  /* USER CODE END I2C1_Init 2 */

}

/**
  * @brief TIM2 Initialization Function
  * @param None
  * @retval None
  */
static void MX_TIM2_Init(void)
{

  /* USER CODE BEGIN TIM2_Init 0 */

  /* USER CODE END TIM2_Init 0 */

  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};

  /* USER CODE BEGIN TIM2_Init 1 */

  /* USER CODE END TIM2_Init 1 */
  htim2.Instance = TIM2;
  htim2.Init.Prescaler = 72-1;
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim2.Init.Period = 1000-1;
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM2_Init 2 */

  /* USER CODE END TIM2_Init 2 */

}

/**
  * @brief TIM3 Initialization Function
  * @param None
  * @retval None
  */
static void MX_TIM3_Init(void)
{

  /* USER CODE BEGIN TIM3_Init 0 */

  /* USER CODE END TIM3_Init 0 */

  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};

  /* USER CODE BEGIN TIM3_Init 1 */

  /* USER CODE END TIM3_Init 1 */
  htim3.Instance = TIM3;
  htim3.Init.Prescaler = 7200-1;
  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim3.Init.Period = 10-1;
  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM3_Init 2 */

  /* USER CODE END TIM3_Init 2 */

}

/**
  * @brief USART1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_USART1_UART_Init(void)
{

  /* USER CODE BEGIN USART1_Init 0 */

  /* USER CODE END USART1_Init 0 */

  /* USER CODE BEGIN USART1_Init 1 */

  /* USER CODE END USART1_Init 1 */
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART1_Init 2 */

  /* USER CODE END USART1_Init 2 */

}

/**
  * @brief USART2 Initialization Function
  * @param None
  * @retval None
  */
static void MX_USART2_UART_Init(void)
{

  /* USER CODE BEGIN USART2_Init 0 */

  /* USER CODE END USART2_Init 0 */

  /* USER CODE BEGIN USART2_Init 1 */

  /* USER CODE END USART2_Init 1 */
  huart2.Instance = USART2;
  huart2.Init.BaudRate = 9600;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart2) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART2_Init 2 */

  /* USER CODE END USART2_Init 2 */

}

/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOC, LED_Pin|GPIO_PIN_14|GPIO_PIN_15, GPIO_PIN_RESET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5|GPIO_PIN_6|BEEP_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10|GPIO_PIN_11, GPIO_PIN_RESET);

  /*Configure GPIO pins : LED_Pin PC14 PC15 */
  GPIO_InitStruct.Pin = LED_Pin|GPIO_PIN_14|GPIO_PIN_15;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  /*Configure GPIO pins : PA0 PA1 */
  GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*Configure GPIO pins : PA5 PA6 BEEP_Pin */
  GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6|BEEP_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*Configure GPIO pins : PB10 PB11 */
  GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  /*Configure GPIO pin : KEY1_Pin */
  GPIO_InitStruct.Pin = KEY1_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  HAL_GPIO_Init(KEY1_GPIO_Port, &GPIO_InitStruct);

}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
    /* User can add his own implementation to report the HAL error return state */
    while(1) 
    {
    }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
    /* User can add his own implementation to report the file name and line number,
        ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

七、单片机实物资料

资料获取 查看主页介绍:兆龙电子单片机设计

相关推荐
麒qiqi2 小时前
51 单片机入门详解:从基础概念到实战开发
单片机·嵌入式硬件
@good_good_study2 小时前
STM32 C语言函数
stm32
周周记笔记11 小时前
ESP32 初识:WiFi MCU 新时代与国产芯片生态(一)
单片机·嵌入式硬件
驴友花雕12 小时前
【花雕学编程】Arduino BLDC 之群体机器人协同探索
c++·单片机·嵌入式硬件·arduino bldc·群体机器人协同探索
@LetsTGBot搜索引擎机器人12 小时前
2025 Telegram 最新免费社工库机器人(LetsTG可[特殊字符])搭建指南(含 Python 脚本)
数据库·搜索引擎·机器人·开源·全文检索·facebook·twitter
驴友花雕12 小时前
【花雕学编程】Arduino BLDC 之仿人机器人膝关节稳定系统
c++·单片机·嵌入式硬件·arduino bldc·仿人机器人膝关节稳定系统
Zeku12 小时前
20260110 - Linux 驱动开发学习笔记:上下文、中断与休眠
stm32·freertos·linux驱动开发·linux应用开发
大厂技术总监下海15 小时前
根治LLM胡说八道!用 Elasticsearch 构建 RAG,给你一个“有据可查”的AI
大数据·elasticsearch·开源
星浩AI15 小时前
Google 官方发布:让你的 AI 编程助手"边写、边看、边调",像人类开发者一样工作
人工智能·后端·开源