fix:更新注释等

This commit is contained in:
2026-05-21 12:19:01 +08:00
parent fd65e9c6a2
commit 8ee0849831
54 changed files with 1145 additions and 683 deletions

View File

@@ -44,13 +44,13 @@ local function handleCmd01(subCmd, payload)
local socketId = subCmd
if socketId < 1 or socketId > 6 then
log.error("Invalid socket id in cmd 0x01:", socketId)
sendResponse(0x01, socketId, 1)
sendResponse(0x03, socketId, 1)
return
end
local success = linksocket.sendToSocket(socketId, payload)
if not success then
log.warn("Send failed, socket", socketId, "not connected")
sendResponse(0x01, socketId, 1)
sendResponse(0x03, socketId, 1)
else
log.info("Data sent to socket", socketId, "len=", #payload)
end

View File

@@ -72,7 +72,6 @@ virtualFolder:
folders: []
- name: Global
files:
- path: ../User/Global/g_runtime.c
- path: ../User/Global/g_dcpile.c
- path: ../User/Global/g_init.c
folders: []

View File

@@ -1,11 +1,11 @@
/**
* @file udp_manager.c
* @brief UDP管理模块
* @details 处理充电桩与服务器之间的UDP通信提供数据发送功能。
* 支持向指定充电桩发送数据以及向上位机服务器发送数据。
* @date 2025-01-09 14:32:15
* @version 1.0.0
* @copyright Copyright (c) 2026
******************************************************************************
* @file User\App\task_air724.c
* @author 路淮
* @version v0.1
* @date 2026-05-21
* @brief 4G模块通信任务处理模块
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
@@ -40,10 +40,6 @@ void air724_recv_task_function(void const *argument)
/**/
while (1)
{
/*---------------------------------------------------获取任务运行状态---------------------------------------------------*/
TaskRunTimeStat.DownLinkTask.threads_runtime = GetTask_RunTime(DownLinkTaskID);
TaskRunTimeStat.DownLinkTask.threads_counter = GetTask_Beatcnt(DownLinkTaskID);
TaskRunTimeStat.DownLinkTask.threads_freestack = Get_Free_Stack(DownLinkTaskID);
if (xQueueReceive(Air724_Message_Queue, &air724_rx_msg, 10) == pdPASS)
{
@@ -80,7 +76,7 @@ void air724_recv_task_function(void const *argument)
case 0x86:
case 0x87:
{
drv_air724_parse_response(air724_rx_msg, UART1_RX_BUFFER_SIZE);
drv_air724_parse_response(air724_rx_msg, UART1_RX_BUFFER_SIZE);// 4G模块回传命令数据解析
}
break;
}

View File

@@ -1,8 +1,18 @@
/**
******************************************************************************
* @file User\App\task_air724.h
* @author 路淮
* @version v0.1
* @date 2026-05-21
* @brief 4G模块通信任务头文件
******************************************************************************
*/
#ifndef __AIR724_RECV_TASK_H
#define __AIR724_RECV_TASK_H
/* includes ----------------------------------------------------------------------------------------------*/
/* includes ------------------------------------------------------------------*/
#include "global.h"
/* macro ------------------------------------------------------------------------------------------------*/

View File

@@ -1,10 +1,10 @@
/**
******************************************************************************
* @file user\task\HeartBeatTask.c
* @author luhuaishuai
* @file User\App\task_sys.c
* @author 路淮
* @version v0.1
* @date 2026-1-12
* @brief 心跳任务,负责发送心跳包和处理云快充的响应
* @date 2026-05-21
* @brief 系统任务
******************************************************************************
*/
@@ -13,20 +13,16 @@
void HeartBeat_Sign(void);
/**
* @funNm : HeartbeatTask_Function
* @brief : 心跳
* @param : argument
* @retval: void
* @brief sys_task_function:系统任务
* @note none
* @param none
* @retval none
*/
void sys_task_function(void const *argument)
{
while (1)
{
TaskRunTimeStat.HeartBeatTask.threads_runtime = GetTask_RunTime(HeartBeatTaskID);
TaskRunTimeStat.HeartBeatTask.threads_counter = GetTask_Beatcnt(HeartBeatTaskID);
TaskRunTimeStat.HeartBeatTask.threads_freestack = Get_Free_Stack(HeartBeatTaskID);
HeartBeat_Sign(); // 指示灯、蜂鸣器

View File

@@ -1,7 +1,17 @@
/**
******************************************************************************
* @file User\App\task_sys.h
* @author 路淮
* @version v0.1
* @date 2026-05-21
* @brief 系统任务头文件
******************************************************************************
*/
#ifndef __TASK_SYS_H
#define __TASK_SYS_H
/* includes ----------------------------------------------------------------------------------------------*/
/* includes ------------------------------------------------------------------*/
#include "global.h"
#include "cmsis_os.h" // 或使用 HAL_GetTick() 等

View File

@@ -1,26 +1,21 @@
/**
* @file task_udp.c
* @brief UDP通信任务处理模块
* @details 处理充电桩与服务器之间的UDP通信协议包括UDP数据接收、数据解析和路由分发等功能。
* 支持JSON格式的数据交互通过FreeRTOS任务和队列机制实现异步数据处理。
* 包含两个主要任务UDP数据接收任务(udp_recv_task_function)和UDP数据解析任务(udp_parse_task_function)。
* @date 2025-01-09 14:32:15
* @version 1.0.0
* @copyright Copyright (c) 2026
******************************************************************************
* @file User\App\task_udp.c
* @author 路淮
* @version v0.1
* @date 2026-05-21
* @brief UDP通信任务处理模块
******************************************************************************
*/
#include "task_udp.h"
/**
* @brief udp_recv_taskUDP 数据接受任务
*
* @brief udp_recv_task_functionUDP 数据接受任务
* @note none
*
* @param taskID : 任务ID
*
* @retval runtime : 任务周期
* @param none
* @retval none
*/
void udp_recv_task_function(void const *argument)
{
err_t recv_err;
@@ -35,11 +30,6 @@ void udp_recv_task_function(void const *argument)
while (1)
{
/*获取任务运行状态*/
TaskRunTimeStat.UPLinkTask.threads_runtime = GetTask_RunTime(UPLinkTaskID);
TaskRunTimeStat.UPLinkTask.threads_counter = GetTask_Beatcnt(UPLinkTaskID);
TaskRunTimeStat.UPLinkTask.threads_freestack = Get_Free_Stack(UPLinkTaskID);
recv_err = netconn_recv(datalink_conn, &datalink_buf);
if (recv_err == ERR_OK && datalink_buf != NULL)
@@ -78,13 +68,10 @@ void udp_recv_task_function(void const *argument)
}
/**
* @brief UDP_ParseTask_FunctionUDP 数据解析任务
*
* @brief udp_parse_task_functionUDP 数据解析任务
* @note none
*
* @param taskID : 任务ID
*
* @retval runtime : 任务周期
* @param none
* @retval none
*/
void udp_parse_task_function(void const *argument)
{

View File

@@ -1,8 +1,18 @@
/**
******************************************************************************
* @file User\App\task_udp.h
* @author 路淮
* @version v0.1
* @date 2026-05-21
* @brief UDP通信任务头文件
******************************************************************************
*/
#ifndef __UDP_TASK_H
#define __UDP_TASK_H
/* includes ----------------------------------------------------------------------------------------------*/
/* includes ------------------------------------------------------------------*/
#include "global.h"
#include "board_config.h"
#include "udp_router.h"

View File

@@ -1,10 +1,10 @@
/**
******************************************************************************
* @file user\task\HeartBeatTask.c
* @author luhuaishuai
* @file User\App\task_ykc.c
* @author 路淮
* @version v0.1
* @date 2026-1-12
* @brief Briefly describe the function of your function
* @date 2026-05-21
* @brief 云快充平台交互主任务
******************************************************************************
*/
@@ -19,10 +19,9 @@
/**
* @funNm : ykc_task_function
* @brief : 云快充平台交互主任务
* @param : argument
* @retval: void
* @param : none
* @retval: none
*/
void ykc_task_function(void const *argument)
{
uint32_t now;
@@ -32,9 +31,6 @@ void ykc_task_function(void const *argument)
osDelay(5000);
while (1)
{
TaskRunTimeStat.YkcTask.threads_runtime = GetTask_RunTime(YkcTaskID);
TaskRunTimeStat.YkcTask.threads_counter = GetTask_Beatcnt(YkcTaskID);
TaskRunTimeStat.YkcTask.threads_freestack = Get_Free_Stack(YkcTaskID);
now = HAL_GetTick();
@@ -52,8 +48,7 @@ void ykc_task_function(void const *argument)
{
case 0: // 等待桩上电 + 连接本桩4G通道
{
// if (pile->is_udp_online)
if(1)
if (pile->is_udp_online)
{
if (!g_air724_info.socket_connected[i])
{
@@ -68,8 +63,7 @@ void ykc_task_function(void const *argument)
}
else
{
USB_Printf("网关:等待桩%d上电指令\r\n", i + 1);
drv_air724_query_iccid();
//drv_air724_query_iccid();
pile->step_tick = now + 1000;
}
}
@@ -146,52 +140,12 @@ void ykc_task_function(void const *argument)
}
/**
* @brief 云快充平台状态检查回调
* @note 每 500ms 触发一次,遍历 1-6 号桩检查状态
* @param xTimer 定时器句柄
* @retval none
* @funNm : ykc_timer_callback_function
* @brief : 云快充平台状态检查回调
* @param : xTimer 定时器句柄
* @retval: none
*/
void ykc_timer_callback_function(TimerHandle_t xTimer)
{
for (int i = 0; i < MAX_CHARGER_COUNT; i++)
{
for (int g = 0; g < MAX_GUN_PER_CHARGER; g++)
{
ChargerGun *gun = &g_charger_manager.charger_piles[i].guns[g];
if (gun->charger_state == REDAY_CHARGER_START_STATE)
{
USB_Printf("状态机:[info] 桩%d 枪%d 查询中,等待启动回复.... \r\n", i + 1, g + 1);
}
else if (gun->charger_state == SUCCESS_CHARGER_STATE)
{
USB_Printf("状态机:[success] 桩%d 枪%d 启动成功.... \r\n", i + 1, g + 1);
gun->charger_state = CHARGER_STATE_CHARGING;
}
else if (gun->charger_state == FAIL_CHARGER_STATE)
{
USB_Printf("状态机:[error] 桩%d 枪%d 启动失败.... \r\n", i + 1, g + 1);
}
else if (gun->charger_state == CHARGER_STATE_CHARGING)
{
USB_Printf("状态机:[info] 桩%d 枪%d 充电中.... \r\n", i + 1, g + 1);
}
else if (gun->charger_state == REDAY_CHARGER_STOP_STATE)
{
USB_Printf("状态机:[info] 桩%d 枪%d 查询中,等待停止回复.... \r\n", i + 1, g + 1);
}
else if (gun->charger_state == SUCCESS_CHARGER_STOP_STATE)
{
USB_Printf("状态机:[success] 桩%d 枪%d 停止成功.... \r\n", i + 1, g + 1);
}
else if (gun->charger_state == FAIL_CHARGER_STOP_STATE)
{
USB_Printf("状态机:[error] 桩%d 枪%d 停止失败.... \r\n", i + 1, g + 1);
}
else if (gun->charger_state == CHARGER_STATE_CHARGE_DONE)
{
printf("状态机:[success] 桩%d 枪%d 计费数据已发送,充电完成.... \r\n", i + 1, g + 1);
}
}
}
}

View File

@@ -1,7 +1,17 @@
/**
******************************************************************************
* @file User\App\task_ykc.h
* @author 路淮
* @version v0.1
* @date 2026-05-21
* @brief 云快充平台交互任务头文件
******************************************************************************
*/
#ifndef __TASK_YKC_H
#define __TASK_YKC_H
/* includes ----------------------------------------------------------------------------------------------*/
/* includes ------------------------------------------------------------------*/
#include "global.h"
#include "drv_air724.h"

View File

@@ -1,8 +1,11 @@
/**
* @file drv_air724.c
* @brief 4G模块(AIR724)驱动
* @details 提供通道连接/断开、设置服务器地址、查询SIM/信号/链路状态的接口,
* 以及统一解析4G模块上行响应帧的入口。
******************************************************************************
* @file User\Driver\drv_air724.c
* @author 路淮
* @version v0.1
* @date 2026-05-21
* @brief 4G模块(AIR724)驱动
******************************************************************************
*
* 协议55 AA mainCmd subCmd [payload] AA 55
*
@@ -25,7 +28,15 @@
Air724_Info_t g_air724_info = {0};
/* ── 内部:构造并发送命令帧 ──────────────────────────── */
/**
* @brief send_cmd发送命令帧函数
* @note none
* @param main_cmd 主命令 主命令字节
* @param sub_cmd 子命令 子命令字节
* @param payload 数据 数据指针
* @param payload_len 数据长度 数据长度
* @retval none
*/
static void drv_air724_send_cmd(uint8_t main_cmd, uint8_t sub_cmd,
const uint8_t *payload, uint16_t payload_len)
{
@@ -48,8 +59,14 @@ static void drv_air724_send_cmd(uint8_t main_cmd, uint8_t sub_cmd,
Air724_Message_Send(frame, idx);
}
/* ── 发送函数 ──────────────────────────────────────── */
/**
* @brief set_server设置服务器函数
* @note none
* @param ip 服务器IP地址 字符串指针
* @param port 服务器端口 十进制整数
* @retval none
*/
void drv_air724_set_server(const char *ip, uint16_t port)
{
if (!ip) return;
@@ -66,16 +83,28 @@ void drv_air724_set_server(const char *ip, uint16_t port)
drv_air724_send_cmd(0x04, 0, payload, 3 + ip_len);
}
/**
* @brief connect_channel连接通道函数
* @note none
* @param channel 通道号 通道-1-6
* @retval none
*/
void drv_air724_connect_channel(uint8_t channel)
{
if (channel < 1 || channel > AIR724_SOCKET_MAX) {
printf("4G: 通道 %d 无效\r\n", channel);
printf("4G: 通道 %d 无效 \r\n", channel);
return;
}
drv_air724_send_cmd(0x03, 0x01, &channel, 1);
printf("4G: 通道 %d 连接请求已发送\r\n", channel);
printf("4G: 通道 %d 连接请求已发送 \r\n", channel);
}
/**
* @brief disconnect_channel断开通道函数
* @note none
* @param channel 通道号 通道-1-6
* @retval none
*/
void drv_air724_disconnect_channel(uint8_t channel)
{
if (channel < 1 || channel > AIR724_SOCKET_MAX) {
@@ -86,33 +115,59 @@ void drv_air724_disconnect_channel(uint8_t channel)
printf("4G: 通道 %d 断开请求已发送\r\n", channel);
}
/**
* @brief query_iccid查询ICCID函数
* @note none
* @retval none
*/
void drv_air724_query_iccid(void)
{
drv_air724_send_cmd(0x05, 0x01, NULL, 0);
}
/**
* @brief query_imsi查询IMSI函数
* @note none
* @retval none
*/
void drv_air724_query_imsi(void)
{
drv_air724_send_cmd(0x05, 0x02, NULL, 0);
}
/**
* @brief query_imei查询IMEI函数
* @note none
* @retval none
*/
void drv_air724_query_imei(void)
{
drv_air724_send_cmd(0x05, 0x03, NULL, 0);
}
/**
* @brief query_signal查询信号函数
* @note none
* @retval none
*/
void drv_air724_query_signal(void)
{
drv_air724_send_cmd(0x06, 0x00, NULL, 0);
}
/**
* @brief query_link_status查询链路函数
* @note none
* @retval none
*/
void drv_air724_query_link_status(void)
{
drv_air724_send_cmd(0x07, 0x00, NULL, 0);
}
/* ── 统一解析入口 ───────────────────────────────────── */
/**
* @brief parse_response解析响应帧函数
* @note none
* @param frame 响应帧 响应帧指针
* @param len 响应帧长度 响应帧长度
* @retval none
*/
void drv_air724_parse_response(const uint8_t *frame, uint16_t len)
{
if (!frame || len < 7) return;

View File

@@ -1,7 +1,17 @@
/**
******************************************************************************
* @file User\Driver\drv_air724.h
* @author 路淮
* @version v0.1
* @date 2026-05-21
* @brief 4G模块(AIR724)驱动头文件
******************************************************************************
*/
#ifndef __DRVAIR724_H
#define __DRVAIR724_H
/* includes ----------------------------------------------------------------------------------------------*/
/* includes ------------------------------------------------------------------*/
#include "global.h"
/* macro ------------------------------------------------------------------------------------------------*/

View File

@@ -1,3 +1,13 @@
/**
******************************************************************************
* @file User\Driver\drv_flash.c
* @author 路淮
* @version v0.1
* @date 2026-05-21
* @brief Flash驱动
******************************************************************************
*/
#include "drv_flash.h"
/* flash数据帧格式 */
@@ -18,6 +28,12 @@ uint8_t erase_flag = 0;
uint32_t i = 0;
/**
* @brief flash_manage_init初始化flash管理函数
* @note none
* @param flash_manage 指向flash管理结构体的指针
* @retval none
*/
int8_t flash_manage_init(flash_manage_t *flash_manage)
{
uint8_t buff[4] = {0}; /* 存放帧头,帧大小,帧类型 */
@@ -58,6 +74,14 @@ int8_t flash_manage_init(flash_manage_t *flash_manage)
return 1;
}
/**
* @brief update_readable_frame更新可读帧表函数
* @note none
* @param flash_manage 指向flash管理结构体的指针
* @param addr 可读帧地址 可读帧地址
* @param frame_type 可读帧类型 可读帧类型
* @retval none
*/
void update_readable_frame(flash_manage_t *flash_manage, uint32_t addr, uint8_t frame_type)
{
uint8_t buff[4] = {0}; /* 存放帧头,帧大小,帧类型 */
@@ -88,6 +112,14 @@ void update_readable_frame(flash_manage_t *flash_manage, uint32_t addr, uint8_t
}
}
/**
* @brief flash_manage_read读取flash函数
* @note none
* @param flash_manage 指向flash管理结构体的指针
* @param pbuf 指向要读取数据的指针
* @param frame_type 要读取数据的类型
* @retval none
*/
int8_t flash_manage_read(flash_manage_t *flash_manage, uint8_t *pbuf, uint8_t frame_type)
{
if (flash_manage->manage_sector_num == 0 || flash_manage->sector_size == 0 || flash_manage->read_flash == 0 ||
@@ -116,6 +148,15 @@ int8_t flash_manage_read(flash_manage_t *flash_manage, uint8_t *pbuf, uint8_t fr
return 0;
}
/**
* @brief flash_manage_write写入flash函数
* @note none
* @param flash_manage 指向flash管理结构体的指针
* @param pbuf 指向要写入数据的指针
* @param size 要写入数据的大小
* @param frame_type 要写入数据的类型
* @retval none
*/
int8_t flash_manage_write(flash_manage_t *flash_manage, uint8_t *pbuf, uint16_t size, uint8_t frame_type)
{
uint8_t buff[size + 5];

View File

@@ -1,3 +1,13 @@
/**
******************************************************************************
* @file User\Driver\drv_flash.h
* @author 路淮
* @version v0.1
* @date 2026-05-21
* @brief Flash驱动头文件
******************************************************************************
*/
#ifndef __DRV_FLASH_H__
#define __DRV_FLASH_H__

View File

@@ -1,10 +1,10 @@
/**
******************************************************************************
* @file user\driver\drv_init.c
* @author luhuaishuai
* @file User\Driver\drv_init.c
* @author 路淮
* @version v0.1
* @date 2026-1-12
* @brief Briefly describe the function of your function
* @date 2026-05-21
* @brief 驱动层初始化
******************************************************************************
*/
/* Includes -------------------------------------------------------------------*/
@@ -14,16 +14,12 @@
/* code -----------------------------------------------------------------------*/
/**
* @brief drv_all_Init所有传感器、外设芯片、外部设备初始化
*
/**
* @brief drv_all_init所有传感器、外设芯片、外部设备初始化
* @note none
*
* @param none
*
* @retval none
*/
void drv_all_init(void)
{
AIR724_RESET(); /* AIR724 复位 */

View File

@@ -1,13 +1,23 @@
/**
******************************************************************************
* @file User\Driver\drv_init.h
* @author 路淮
* @version v0.1
* @date 2026-05-21
* @brief 驱动层初始化头文件
******************************************************************************
*/
#ifndef __DRVINIT_H
#define __DRVINIT_H
/* includes ----------------------------------------------------------------------------------------------*/
/* includes ------------------------------------------------------------------*/
#include "global.h"
/* Exported functions prototypes ------------------------------------------------------------------------*/
/* function prototype --------------------------------------------------------*/
void drv_all_init(void);
#endif /* __DRVINIT_H */

View File

@@ -1,10 +1,10 @@
/**
******************************************************************************
* @file user\hal\_hal_usart.c
* @author luhuaishuai
* @file User\Driver\drv_usart.c
* @author 路淮
* @version v0.1
* @date 2026-1-12
* @brief Briefly describe the function of your function
* @date 2026-05-21
* @brief 串口驱动
******************************************************************************
*/
@@ -12,25 +12,24 @@
#include "drv_usart.h"
/* variables ------------------------------------------------------------------*/
uint8_t uart1_rx_buffer[UART1_RX_BUFFER_SIZE];
uint8_t uart1_tx_buffer[UART1_TX_BUFFER_SIZE];
uint8_t uart1_rx_buffer[UART1_RX_BUFFER_SIZE];// 4G模块接收缓冲区
uint8_t uart1_tx_buffer[UART1_TX_BUFFER_SIZE];// 4G模块发送缓冲区
uint8_t uart3_rx_buffer[UART3_RX_BUFFER_SIZE];
uint8_t uart3_tx_buffer[UART3_TX_BUFFER_SIZE];
uint8_t uart3_rx_buffer[UART3_RX_BUFFER_SIZE];// RS485模块接收缓冲区
uint8_t uart3_tx_buffer[UART3_TX_BUFFER_SIZE];// RS485模块发送缓冲区
static SemaphoreHandle_t air724_tx_mutex = NULL;// 4G模块发送互斥信号量
static SemaphoreHandle_t air724_tx_mutex = NULL;
/* code -----------------------------------------------------------------------*/
/**
* @brief fputcprintf映射
*
* @brief fputcprintf映射函数
* @note none
*
* @param none
*
* @param ch字符
* @param f文件指针
* @retval none
*/
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart6, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
@@ -39,11 +38,9 @@ int fputc(int ch, FILE *f)
/**
* @brief Air724_Message_Send4G数据发送
*
* @note none
*
* @param none
*
* @param data数据指针
* @param len数据长度
* @retval none
*/
void Air724_Message_Send(uint8_t *data, uint16_t len)
@@ -62,6 +59,13 @@ void Air724_Message_Send(uint8_t *data, uint16_t len)
}
}
/**
* @brief Rs485_Message_SendRS485数据发送
* @note none
* @param data数据指针
* @param len数据长度
* @retval none
*/
void Rs485_Message_Send(uint8_t *data, uint16_t len)
{
RS485_EN(1);
@@ -71,14 +75,10 @@ void Rs485_Message_Send(uint8_t *data, uint16_t len)
/**
* @brief drv_usart_init所有串口初始化
*
* @note none
*
* @param none
*
* @retval none
*/
void drv_usart_init(void)
{
air724_tx_mutex = xSemaphoreCreateMutex();
@@ -98,11 +98,9 @@ void drv_usart_init(void)
/**
* @brief HAL_UARTEx_RxEventCallback串口接收完成中断处理函数
*
* @note none
*
* @param none
*
* @param huart串口句柄
* @param Size接收数据大小
* @retval none
*/
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
@@ -123,11 +121,9 @@ void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
/**
* @brief air724_callback_fun4G数据接收回调函数
*
* @note none
*
* @param none
*
* @param huart串口句柄
* @param Size接收数据大小
* @retval none
*/
void air724_callback_fun()
@@ -138,6 +134,13 @@ void air724_callback_fun()
memset(uart1_rx_buffer, 0, UART1_RX_BUFFER_SIZE);
}
/**
* @brief rs485_callback_funRS485数据接收回调函数
* @note none
* @param huart串口句柄
* @param Size接收数据大小
* @retval none
*/
void rs485_callback_fun()
{
BaseType_t xHigherPriorityTaskWoken = pdFALSE;

View File

@@ -1,4 +1,14 @@
/**
******************************************************************************
* @file User\Driver\drv_usart.h
* @author 路淮
* @version v0.1
* @date 2026-05-21
* @brief 串口驱动头文件
******************************************************************************
*/
#ifndef __DRV_USART_H
#define __DRV_USART_H
@@ -10,7 +20,7 @@
#elif defined(__GNUC__)
#endif
/* includes ----------------------------------------------------------------------------------------------*/
/* includes ------------------------------------------------------------------*/
#include "global.h"
/* macro ------------------------------------------------------------------------------------------------*/

View File

@@ -1,8 +1,26 @@
/**
******************************************************************************
* @file User\Driver\flash_config.c
* @author 路淮
* @version v0.1
* @date 2026-05-21
* @brief Flash读写配置
******************************************************************************
*/
#include "flash_config.h"
#include "stm32h7xx_hal.h"
#include "FreeRTOS.h"
#include "task.h"
/**
* @brief stmflash_read_data读取Flash数据
* @note none
* @param pbuf数据缓冲区指针
* @param addrFlash地址
* @param datalen数据长度
* @retval none
*/
void stmflash_read_data(uint8_t *pbuf, uint32_t addr, uint16_t datalen)
{
if (pbuf == NULL || datalen == 0) {

View File

@@ -1,3 +1,13 @@
/**
******************************************************************************
* @file User\Driver\flash_config.h
* @author 路淮
* @version v0.1
* @date 2026-05-21
* @brief Flash读写配置头文件
******************************************************************************
*/
#ifndef _FLASH_CONFIG_H__
#define _FLASH_CONFIG_H__

View File

@@ -1,10 +1,10 @@
/**
******************************************************************************
* @file user\global\board_config.h
* @author luhuaishuai
* @file User\Global\board_config.h
* @author 路淮
* @version v0.1
* @date 2023-10-11
* @brief Briefly describe the function of your function
* @date 2026-05-21
* @brief 板级配置头文件
******************************************************************************
*/
#ifndef __BOARD_CONFIG_H
@@ -16,4 +16,6 @@
#define LINK_APP_PORT 6002 // 桩通讯端口
#define LINK_STAKE_PORT 6001 // 桩通讯端口
#define DEBUG 1 // 调试模式
#endif /* __BOARD_CONFIG_H */

View File

@@ -1,3 +1,13 @@
/**
******************************************************************************
* @file User\Global\g_dcpile.c
* @author 路淮
* @version v0.1
* @date 2026-05-21
* @brief 充电桩管理器
******************************************************************************
*/
#include "g_dcpile.h"
/*全局充电桩管理器*/
@@ -15,8 +25,9 @@ const uint8_t piles_serial[6][7] = {
};
/**
* @brief 初始化充电桩管理器
* @brief init_chargers初始化充电桩管理器
* @note 初始化充电桩管理器,设置充电桩数量和每个充电桩的初始状态
* @retval none
*/
void init_chargers(void)
{

View File

@@ -1,8 +1,18 @@
/**
******************************************************************************
* @file User\Global\g_dcpile.h
* @author 路淮
* @version v0.1
* @date 2026-05-21
* @brief 充电桩管理头文件
******************************************************************************
*/
#ifndef __DC_PILE_H
#define __DC_PILE_H
/* includes ----------------------------------------------------------------------------------------------*/
/* includes ------------------------------------------------------------------*/
#include "global.h"
#define MAX_CHARGER_COUNT 2 // 充电桩数量
@@ -37,7 +47,6 @@ typedef struct
PACK_DATA_0X3B fee_data; // 计费数据
PACK_DATA_0X23 bms_demand; // 充电过程BMS需求、充电机输出
PACK_DATA_0X25 bms_info; // 充电过程BMS信息
} ChargerGun;
/* 单个充电桩结构体*/

View File

@@ -1,12 +1,12 @@
/**
******************************************************************************
* @file user\global\g_init.c
* @author luhuaishuai
* @version v0.1
* @date 2026-1-12
* @brief Briefly describe the function of your function
******************************************************************************
*/
******************************************************************************
* @file User\Global\g_init.c
* @author 路淮
* @version v0.1
* @date 2026-05-21
* @brief 全局初始化
******************************************************************************
*/
#include "g_init.h"

View File

@@ -1,3 +1,13 @@
/**
******************************************************************************
* @file User\Global\g_init.h
* @author 路淮
* @version v0.1
* @date 2026-05-21
* @brief 全局初始化头文件
******************************************************************************
*/
#ifndef __GINIT_H
#define __GINIT_H

View File

@@ -1,12 +1,12 @@
/**
******************************************************************************
* @file user\global\g_runtime.c
* @author luhuaishuai
* @version v0.1
* @date 2026-1-12
* @brief Briefly describe the function of your function
******************************************************************************
*/
******************************************************************************
* @file User\Global\g_runtime.c
* @author 路淮
* @version v0.1
* @date 2026-05-21
* @brief 运行时统计
******************************************************************************
*/
/* Includes -------------------------------------------------------------------*/
#include "g_runtime.h"

View File

@@ -1,9 +1,19 @@
/**
******************************************************************************
* @file User\Global\g_runtime.h
* @author 路淮
* @version v0.1
* @date 2026-05-21
* @brief 运行时统计头文件
******************************************************************************
*/
#ifndef __GRUNTIME_H
#define __GRUNTIME_H
/* includes ----------------------------------------------------------------------------------------------*/
/* includes ------------------------------------------------------------------*/
#include "global.h"

View File

@@ -1,10 +1,10 @@
/**
******************************************************************************
* @file user\global\global.h
* @author liangky
* @file User\Global\global.h
* @author 路淮
* @version v0.1
* @date 2023-10-11
* @brief Briefly describe the function of your function
* @date 2026-05-21
* @brief 全局头文件
******************************************************************************
*/
#ifndef __GLOBAL_H
@@ -62,17 +62,8 @@
#define TRUE 1
#define FALSE 0
#define PI 3.1415926f
#define SOFTWARE_VERSION "JSBRv1.2" // 软件版本
#define YKC_VERSION 0x10 // YKC 协议版本 v1.6
#define NET_CONN_TYPE 0 // 0: 4G, 1: LAN
#define DEBUG 1 // 调试模式
/*- I/O 输出-*/

View File

@@ -1,11 +1,11 @@
/**
* @file udp_manager.c
* @brief UDP管理模块
* @details 处理充电桩与服务器之间的UDP通信提供数据发送功能。
* 支持向指定充电桩发送数据以及向上位机服务器发送数据。
* @date 2025-01-09 14:32:15
* @version 1.0.0
* @copyright Copyright (c) 2026
******************************************************************************
* @file User\Network\udp_manager.c
* @author 路淮
* @version v0.1
* @date 2026-05-21
* @brief UDP管理模块
******************************************************************************
*/
#include "udp_manager.h"
@@ -15,6 +15,7 @@ struct netconn *datalink_conn; // 数据链路句柄
/**
* @brief 桩IP地址
* @note 桩IP地址从10.12.19.101开始递增
* @retval none
*/
static ip4_addr_t s_point_ip[6] = {
IPADDR4_INIT_BYTES(10, 12, 19, 101), /* 桩1 */
@@ -28,11 +29,11 @@ static ip4_addr_t s_point_ip[6] = {
static ip4_addr_t s_server_ip = IPADDR4_INIT_BYTES(10, 12, 19, 107); /* 上位机 */
/**
* @brief UDP发送
* @note 发送数据指定桩
* @param point_id 目标桩ID
* @param data 数据指针
* @param len 数据长度
* @brief udp_send_to_point发送数据到指定桩
* @note 指定桩,数据指定桩,数据指针和长度
* @param point_id目标桩ID1-6表示桩ID
* @param data数据指针
* @param len数据长度
* @return err_t 错误码
*/
err_t udp_send_to_point(uint8_t point_id, uint8_t *data, u16_t len)
@@ -71,6 +72,13 @@ err_t udp_send_to_point(uint8_t point_id, uint8_t *data, u16_t len)
return err;
}
/**
* @brief udp_send_to_server发送数据到上位机
* @note 发送数据到上位机,数据指针和长度
* @param data数据指针
* @param len数据长度
* @return err_t 错误码
*/
err_t udp_send_to_server(uint8_t *data, uint16_t len)
{
struct netbuf *buf = netbuf_new();

View File

@@ -1,10 +1,10 @@
/**
******************************************************************************
* @file user\network\udp_manager.h
* @author luhuaishuai
* @file User\Network\udp_manager.h
* @author 路淮
* @version v0.1
* @date 2023-10-11
* @brief Briefly describe the function of your function
* @date 2026-05-21
* @brief UDP管理模块头文件
******************************************************************************
*/
#ifndef __UDP_MANAGER_H

View File

@@ -1,11 +1,11 @@
/**
* @file udp_router.c
* @brief UDP路由分发模块
* @details 处理充电桩与服务器之间的UDP通信路由分发根据指令字符串匹配对应的处理函数。
* 支持充电桩南向通信和上位机控制两类路由,通过静态路由表实现高效的指令分发。
* @date 2025-01-09 14:32:15
* @version 1.0.0
* @copyright Copyright (c) 2026
******************************************************************************
* @file User\Network\udp_router.c
* @author 路淮
* @version v0.1
* @date 2026-05-21
* @brief UDP路由分发模块
******************************************************************************
*/
#include "udp_router.h"
@@ -32,16 +32,29 @@ static const route_entry_t ROUTE_TABLE[] = {
#define ROUTE_TABLE_SIZE (sizeof(ROUTE_TABLE) / sizeof(ROUTE_TABLE[0]))
/**
* @brief 路由分发入口
* @param id 指令发送的充电桩ID
* @param cmd 指令字符串
* @param json_pack JSON格式的指令参数
* @brief udp_route_dispatch路由分发入口
* @note 路由分发入口根据指令ID和指令字符串调用对应的回调函数
* @param id指令发送的充电桩ID1-6表示桩ID7表示上位机
* @param cmd指令字符串
* @param json_packJSON格式的指令参数
* @retval none
*/
void udp_route_dispatch(uint8_t id, const char *cmd, cJSON *json_pack)
{
if (!cmd)
return;
/* 除 "online"(上电)外,其他所有桩指令都需要桩已上电 */
if (strcmp(cmd, "online") != 0 && id != 7)
{
if (id < 1 || id > MAX_CHARGER_COUNT ||
!g_charger_manager.charger_piles[id - 1].is_udp_online)
{
printf("[ UDP 路由拦截 ] 桩ID: %d 未上电,忽略指令: %s\r\n", id, cmd);
return;
}
}
for (size_t i = 0; i < ROUTE_TABLE_SIZE; i++)
{
if (strcmp(cmd, ROUTE_TABLE[i].cmd) == 0)

View File

@@ -1,8 +1,18 @@
/**
******************************************************************************
* @file User\Network\udp_router.h
* @author 路淮
* @version v0.1
* @date 2026-05-21
* @brief UDP路由分发模块头文件
******************************************************************************
*/
#ifndef __UDP_ROUTER_H
#define __UDP_ROUTER_H
/* includes ----------------------------------------------------------------------------------------------*/
/* includes ------------------------------------------------------------------*/
#include "global.h"
#include "board_config.h"
#include "point_protocol.h"

View File

@@ -1,12 +1,12 @@
/**
******************************************************************************
* @file user\os\os_init.c
* @author luhuaishuai
* @version v0.1
* @date 2026-1-12
* @brief Briefly describe the function of your function
******************************************************************************
*/
******************************************************************************
* @file User\Os\os_init.c
* @author 路淮
* @version v0.1
* @date 2026-05-21
* @brief 系统初始化
******************************************************************************
*/
/* Includes -------------------------------------------------------------------*/
@@ -15,14 +15,11 @@
/* code -----------------------------------------------------------------------*/
/**
* @brief Os_Init所有系统相关初始化
*
* @note none
*
* @param none
*
* @retval none
*/
* @brief os_init系统初始化
* @note 初始化信号量、任务、软件定时器等系统相关组件
* @param none
* @retval none
*/
void os_init(void)
{

View File

@@ -1,3 +1,13 @@
/**
******************************************************************************
* @file User\Os\os_init.h
* @author 路淮
* @version v0.1
* @date 2026-05-21
* @brief 系统初始化头文件
******************************************************************************
*/
#ifndef __OSINIT_H
#define __OSINIT_H

View File

@@ -1,10 +1,10 @@
/**
******************************************************************************
* @file user\os\os_queue.c
* @author luhuaishuai
* @file User\Os\os_queue.c
* @author 路淮
* @version v0.1
* @date 2026-1-12
* @brief Briefly describe the function of your function
* @date 2026-05-21
* @brief 队列管理
******************************************************************************
*/
@@ -18,7 +18,12 @@ QueueHandle_t RS485_Message_Queue = NULL; /* RS485数据接收队列 */
QueueHandle_t UDP_Message_Queue = NULL; /* UDP数据接收队列 */
/* code --------------------------------------------------------------------------------------------------------*/
/**
* @brief Air724_Message_Queue_Init4G数据接收队列初始化
* @note 初始化4G数据接收队列队列大小为20每个元素大小为UART1_RX_BUFFER_SIZE
* @param none
* @retval none
*/
void Air724_Message_Queue_Init(void)
{
Air724_Message_Queue = xQueueCreate(20, UART1_RX_BUFFER_SIZE);
@@ -29,7 +34,12 @@ void Air724_Message_Queue_Init(void)
Error_Handler();
}
}
/**
* @brief RS485_Message_Queue_InitRS485数据接收队列初始化
* @note 初始化RS485数据接收队列队列大小为5每个元素大小为UART3_RX_BUFFER_SIZE
* @param none
* @retval none
*/
void RS485_Message_Queue_Init(void)
{
RS485_Message_Queue = xQueueCreate(5, UART3_RX_BUFFER_SIZE);
@@ -40,7 +50,12 @@ void RS485_Message_Queue_Init(void)
Error_Handler();
}
}
/**
* @brief UDP_Message_Queue_InitUDP数据接收队列初始化
* @note 初始化UDP数据接收队列队列大小为20每个元素大小为UdpMsg_t
* @param none
* @retval none
*/
void UDP_Message_Queue_Init(void)
{
UDP_Message_Queue = xQueueCreate(20, sizeof(UdpMsg_t));

View File

@@ -1,3 +1,13 @@
/**
******************************************************************************
* @file User\Os\os_queue.h
* @author 路淮
* @version v0.1
* @date 2026-05-21
* @brief 队列管理头文件
******************************************************************************
*/
#ifndef __OSQUEUE_H
#define __OSQUEUE_H

View File

@@ -1,12 +1,12 @@
/**
******************************************************************************
* @file user\os\os_queue.c
* @author luhuaishuai
* @version v0.1
* @date 2026-1-12
* @brief Briefly describe the function of your function
******************************************************************************
*/
******************************************************************************
* @file User\Os\os_semaphore.c
* @author 路淮
* @version v0.1
* @date 2026-05-21
* @brief 信号量管理
******************************************************************************
*/
/* Includes -------------------------------------------------------------------*/
#include "os_semaphore.h"
@@ -22,30 +22,22 @@ void xMutex_Semaphore_Create(void);
/* code -----------------------------------------------------------------------*/
/**
* @brief Os_Semaphore_Init所有信号量相关初始化
*
* @note none
*
* @param none
*
* @retval none
*/
* @brief Os_Semaphore_Init所有信号量相关初始化
* @note 初始化互斥信号量
* @param none
* @retval none
*/
void Os_Semaphore_Init(void)
{
}
/**
* @brief xMutex_Semaphore_Create互斥信号量初始化
*
* @note none
*
* @param none
*
* @retval none
*/
* @brief xMutex_Semaphore_Create互斥信号量初始化
* @note 初始化互斥信号量
* @param none
* @retval none
*/
void xMutex_Semaphore_Create(void)
{

View File

@@ -1,3 +1,13 @@
/**
******************************************************************************
* @file User\Os\os_semaphore.h
* @author 路淮
* @version v0.1
* @date 2026-05-21
* @brief 信号量管理头文件
******************************************************************************
*/
#ifndef __OSSEMAPHORE_H
#define __OSSEMAPHORE_H

View File

@@ -1,10 +1,10 @@
/**
******************************************************************************
* @file user\os\os_task.c
* @author luhuaishuai
* @file User\Os\os_task.c
* @author 路淮
* @version v0.1
* @date 2026-1-12
* @brief Briefly describe the function of your function
* @date 2026-05-21
* @brief 任务管理
******************************************************************************
*/
@@ -37,14 +37,10 @@ void air724_recv_task_function(void const *argument); // 云快充 TCP 消息解
/**
* @brief Os_Task_Init所有任务的创建
*
* @note definition and creation of xxxTask
*
* @param none
*
* @retval none
*/
void Os_Task_Init(void) /*任务入口函数、任务名字、任务栈大小、任务入口函数参数、任务优先级、任务控制块指针*/
{
BaseType_t xReturn = pdPASS;

View File

@@ -1,3 +1,13 @@
/**
******************************************************************************
* @file User\Os\os_task.h
* @author 路淮
* @version v0.1
* @date 2026-05-21
* @brief 任务管理头文件
******************************************************************************
*/
#ifndef __OSTASK_H
#define __OSTASK_H

View File

@@ -1,9 +1,9 @@
/**
******************************************************************************
* @file user\os\os_timer.c
* @author luhuaishuai
* @file User\Os\os_timer.c
* @author 路淮
* @version v0.1
* @date 2026-1-12
* @date 2026-05-21
* @brief 软件定时器管理
******************************************************************************
*/
@@ -20,7 +20,7 @@ TimerHandle_t YkcTimerHandle = NULL;
/**
* @brief 软件定时器初始化
* @note 需要在 FreeRTOS 启动前调用
* @note 初始化YkcTimerHandle
* @param none
* @retval none
*/

View File

@@ -1,3 +1,13 @@
/**
******************************************************************************
* @file User\Os\os_timer.h
* @author 路淮
* @version v0.1
* @date 2026-05-21
* @brief 软件定时器管理头文件
******************************************************************************
*/
#ifndef __OSTIMER_H
#define __OSTIMER_H

View File

@@ -1,16 +1,22 @@
/**
* @file host_computer_protocol.c
* @brief 上位机通信协议处理模块
* @details 处理上位机与充电桩之间的通信协议,包括登录验证、状态查询、
* 数据上报等功能。支持JSON格式的数据交互通过UDP协议与服务器通信。
* @date 2025-01-09 14:32:15
* @version 1.0.0
* @copyright Copyright (c) 2026
******************************************************************************
* @file User\Protocol\Host Computer\host_computer_protocol.c
* @author 路淮
* @version v0.1
* @date 2026-05-21
* @brief 上位机通信协议处理
******************************************************************************
*/
#include "host_computer_protocol.h"
#include "point_protocol.h"
/**
* @brief host_computer_on_login登录指令处理
* @note 处理登录指令,验证用户名和密码
* @param id任务ID
* @param json_packJSON指令指针
*/
void host_computer_on_login(uint8_t id, cJSON *json_pack)
{
(void) id;
@@ -48,7 +54,12 @@ void host_computer_on_login(uint8_t id, cJSON *json_pack)
cJSON_Delete(root);
}
// 处理获取状态查询指令
/**
* @brief host_computer_on_get_status获取状态查询指令处理
* @note 处理获取状态查询指令,返回所有桩的状态
* @param id任务ID
* @param json_packJSON指令指针
*/
void host_computer_on_get_status(uint8_t id, cJSON *json_pack)
{
(void) id;
@@ -125,6 +136,13 @@ void host_computer_on_get_status(uint8_t id, cJSON *json_pack)
cJSON_Delete(root);
printf("get_status 回复已发送 \r\n");
}
/**
* @brief host_computer_on_reboot重启指令处理
* @note 处理重启指令,重启系统
* @param id任务ID
* @param json_packJSON指令指针
*/
void host_computer_on_reboot(uint8_t id, cJSON *json)
{
(void) id;
@@ -135,8 +153,8 @@ void host_computer_on_reboot(uint8_t id, cJSON *json)
/**
* @brief 主动上报充电桩数据
* @note 模拟并上报充电桩实时数据,符合协议格式要求
* @brief host_computer_report_data上报充电桩数据指令处理
* @note 上报充电桩实时数据,符合协议格式要求
* @param stake_index 桩索引 (1~6)
* @param gun_id 枪编码 (1~N)
*/

View File

@@ -1,3 +1,13 @@
/**
******************************************************************************
* @file User\Protocol\Host Computer\host_computer_protocol.h
* @author 路淮
* @version v0.1
* @date 2026-05-21
* @brief 上位机通信协议头文件
******************************************************************************
*/
#ifndef HOST_COMPUTER_HANDLER_H
#define HOST_COMPUTER_HANDLER_H
#include "global.h"

View File

@@ -1,19 +1,19 @@
/**
* @file point_protocol.c
* @brief 充电桩通信协议处理模块
* @details 处理充电桩与充电桩之间的通信协议,包括登录验证、心跳指令、
* 数据上报等功能。支持JSON格式的数据交互通过UDP协议与充电桩通信。
* @date 2025-01-09 14:32:15
* @version 1.0.0
* @copyright Copyright (c) 2026
******************************************************************************
* @file User\Protocol\Point\point_protocol.c
* @author 路淮
* @version v0.1
* @date 2026-05-21
* @brief 充电桩南向通信协议处理
******************************************************************************
*/
#include "point_protocol.h"
/**
* @brief 解析充电桩上电指令
* @brief point_callback_power_on解析充电桩上电指令处理
* @note 设置桩为本地在线状态,发送上电应答
* @param stake_index 桩索引
* @param json_pack json数据包
* @param stake_index 桩索引 (1~6)
* @param json_pack JSON指令指针
*/
void point_callback_power_on(uint8_t stake_index, cJSON *json_pack)
{
@@ -57,13 +57,14 @@ void point_callback_power_on(uint8_t stake_index, cJSON *json_pack)
}
/**
* @brief 解析充电桩心跳指令
* @brief point_callback_heartbeat解析充电桩心跳指令处理
* @note 回复心跳应答
* @param stake_index 桩索引
* @param json_pack json数据包
* @param stake_index 桩索引 (1~6)
* @param json_pack JSON指令指针
*/
void point_callback_heartbeat(uint8_t stake_index, cJSON *json_pack)
{
if (stake_index > MAX_CHARGER_COUNT)
{
return;
@@ -121,10 +122,10 @@ void point_callback_heartbeat(uint8_t stake_index, cJSON *json_pack)
}
/**
* @brief 解析充电桩启动充电回复指令APP控制启动
* @brief point_callback_start_charging解析充电桩启动充电回复指令处理
* @note 回复启动充电应答
* @param stake_index 桩索引
* @param json_pack json数据包
* @param stake_index 桩索引 (1~6)
* @param json_pack JSON指令指针
*/
void point_callback_start_charging(uint8_t stake_index, cJSON *json_pack)
{
@@ -174,10 +175,10 @@ void point_callback_start_charging(uint8_t stake_index, cJSON *json_pack)
}
/**
* @brief 解析充电桩停止充电回复指令APP控制停止
* @brief point_callback_end_charging解析充电桩停止充电回复指令处理
* @note 回复停止充电应答
* @param stake_index 桩索引
* @param json_pack json数据包
* @param stake_index 桩索引 (1~6)
* @param json_pack JSON指令指针
*/
void point_callback_end_charging(uint8_t stake_index, cJSON *json_pack)
@@ -210,6 +211,7 @@ void point_callback_end_charging(uint8_t stake_index, cJSON *json_pack)
else
gun->charger_state = FAIL_CHARGER_STOP_STATE;
charger_to_server_0X19(stake_index, gun_id);
/*向云快充服务器上报停止充电结果*/
charger_to_server_0X35(stake_index, gun_id, result, err_code);
@@ -218,10 +220,10 @@ void point_callback_end_charging(uint8_t stake_index, cJSON *json_pack)
}
/**
* @brief 解析充电桩实时数据指令
* @brief point_callback_realtime_data解析充电桩实时数据指令处理
* @note 回复实时数据应答
* @param stake_index 桩索引
* @param json_pack json数据包
* @param stake_index 桩索引 (1~6)
* @param json_pack JSON指令指针
*/
void point_callback_realtime_data(uint8_t stake_index, cJSON *json_pack)
{
@@ -314,7 +316,7 @@ void point_callback_realtime_data(uint8_t stake_index, cJSON *json_pack)
root = cJSON_CreateObject();
if (root == NULL)
{
printf("111Failed to create JSON object for stake %d\r\n", stake_index);
printf("Failed to create JSON object for stake %d\r\n", stake_index);
return;
}
@@ -332,6 +334,12 @@ void point_callback_realtime_data(uint8_t stake_index, cJSON *json_pack)
printf(" └── 网关向桩回复[success] 桩ID:%d 枪ID:%d 实时数据回复成功\r\n", stake_index, gun_idx);
}
/**
* @brief point_callback_settlement_bill结算单指令处理
* @note 处理结算单指令,更新桩的结算单
* @param stake_index 桩索引 (1~6)
* @param json_pack JSON指令指针
*/
void point_callback_settlement_bill(uint8_t stake_index, cJSON *json_pack)
{
if (stake_index > MAX_CHARGER_COUNT)
@@ -497,7 +505,7 @@ void point_callback_settlement_bill(uint8_t stake_index, cJSON *json_pack)
cJSON *root = cJSON_CreateObject();
if (root == NULL)
{
printf("333Failed to create JSON object for stake %d\r\n", stake_index);
printf("Failed to create JSON object for stake %d\r\n", stake_index);
return;
}
@@ -519,10 +527,10 @@ void point_callback_settlement_bill(uint8_t stake_index, cJSON *json_pack)
}
/**
* @brief 主动停止充电回调
* @brief point_callback_proactive_end_charging主动上报停止充电指令处理
* @note 桩主动上报停止充电,回复应答
* @param id 桩编码 (1~6)
* @param json_pack json数据包
* @param stake_index 桩索引 (1~6)
* @param json_pack JSON指令指针
*/
void point_callback_proactive_end_charging(uint8_t stake_index, cJSON *json_pack)
{
@@ -546,7 +554,7 @@ void point_callback_proactive_end_charging(uint8_t stake_index, cJSON *json_pack
cJSON *root = cJSON_CreateObject();
if (root == NULL)
{
printf("444Failed to create JSON object for stake %d\r\n", stake_index);
printf("Failed to create JSON object for stake %d\r\n", stake_index);
return;
}
@@ -561,14 +569,16 @@ void point_callback_proactive_end_charging(uint8_t stake_index, cJSON *json_pack
free(str);
cJSON_Delete(root);
charger_to_server_0X19(stake_index, gun_idx);
printf(" └── 网关向桩回复[success] 桩ID: %d 枪ID: %d 主动停止充电回复成功\r\n", stake_index, gun_idx);
}
/**
* @brief 充电过程BMS实时需求上报回调
* @brief point_callback_charge_process充电过程BMS实时需求上报指令处理
* @note 桩周期上报BMS需求与充电机输出数据填充到gun->bms_demand
* @param id 桩编码 (1~6)
* @param json_pack json数据包
* @param stake_index 桩索引 (1~6)
* @param json_pack JSON指令指针
*/
void point_callback_charge_process(uint8_t stake_index, cJSON *json_pack)
{
@@ -699,6 +709,12 @@ void point_callback_charge_process(uint8_t stake_index, cJSON *json_pack)
}
}
/**
* @brief point_callback_bms_info解析充电桩BMS信息指令处理
* @note 回复BMS信息应答
* @param stake_index 桩索引 (1~6)
* @param json_pack JSON指令指针
*/
void point_callback_bms_info(uint8_t stake_index, cJSON *json_pack)
{
if (stake_index > MAX_CHARGER_COUNT)
@@ -822,8 +838,8 @@ void point_callback_bms_info(uint8_t stake_index, cJSON *json_pack)
}
/**
* @brief 主动下发启动指令
* @note 发送启动指令到充电桩,符合协议格式要求
* @brief point_send_start_charging主动解析充电桩启动充电指令处理
* @note 发送启动充电指令到充电桩,符合协议格式要求
* @param stake_index 桩索引 (1~6)
* @param gun_id 枪编码 (1~N)
*/
@@ -861,7 +877,7 @@ void point_send_start_charging(uint8_t stake_index, uint8_t gun_id)
root = cJSON_CreateObject();
if (root == NULL)
{
printf("555Failed to create JSON object for stake %d\r\n", stake_index);
printf("Failed to create JSON object for stake %d\r\n", stake_index);
return;
}
@@ -879,7 +895,7 @@ void point_send_start_charging(uint8_t stake_index, uint8_t gun_id)
billing_array = cJSON_CreateArray();
if (billing_array == NULL)
{
printf("666Failed to create billing array\r\n");
printf("Failed to create billing array\r\n");
cJSON_Delete(root);
return;
}
@@ -978,7 +994,7 @@ void point_send_start_charging(uint8_t stake_index, uint8_t gun_id)
if (err1 != ERR_OK)
{
printf("error error error UDP 开始充电指令发送失败,桩索引:%d\r\n", stake_index);
printf("UDP 开始充电指令发送失败,桩索引:%d\r\n", stake_index);
}
else
{
@@ -987,14 +1003,14 @@ void point_send_start_charging(uint8_t stake_index, uint8_t gun_id)
}
else
{
printf("777Failed to print JSON for stake %d\r\n", stake_index);
printf("Failed to print JSON for stake %d\r\n", stake_index);
}
cJSON_Delete(root);
}
/**
* @brief 主动下发停止充电指令
* @brief point_send_stop_charging主动解析充电桩停止充电指令处理
* @note 发送停止充电指令到充电桩,符合协议格式要求
* @param stake_index 桩索引 (1~6)
* @param gun_id 枪编码 (1~N)
@@ -1024,7 +1040,7 @@ void point_send_stop_charging(uint8_t stake_index, uint8_t gun_id)
root = cJSON_CreateObject();
if (root == NULL)
{
printf("888Failed to create JSON object for stake %d\r\n", stake_index);
printf("Failed to create JSON object for stake %d\r\n", stake_index);
return;
}
@@ -1042,7 +1058,7 @@ void point_send_stop_charging(uint8_t stake_index, uint8_t gun_id)
free(str);
if (err1 != ERR_OK)
{
printf("error error error UDP 停机指令发送失败,桩索引:%d\r\n", stake_index);
printf("UDP 停机指令发送失败,桩索引:%d\r\n", stake_index);
}
else
{
@@ -1055,7 +1071,7 @@ void point_send_stop_charging(uint8_t stake_index, uint8_t gun_id)
}
/**
* @brief 将16字节的交易序列号转换为32位16进制字符串
* @brief trade_serial_to_string将交易序列号转换为32位16进制字符串
* @param trade_serial 16字节数组
* @param output_str 输出缓冲区至少33字节
*/

View File

@@ -1,3 +1,13 @@
/**
******************************************************************************
* @file User\Protocol\Point\point_protocol.h
* @author 路淮
* @version v0.1
* @date 2026-05-21
* @brief 充电桩南向通信协议头文件
******************************************************************************
*/
#ifndef POINT_HANDLER_H
#define POINT_HANDLER_H
@@ -5,6 +15,7 @@
#include "cJSON.h"
#include <stdint.h>
#include "udp_manager.h"
#include "charger_to_server.h"
/* ── 路由表注册接口─────────────── */
void point_callback_power_on(uint8_t id, cJSON *json); // 上电

View File

@@ -1,18 +1,22 @@
/**
* @file charger_to_server.c
* @brief 充电桩通信协议处理模块 上行数据
* @details 处理充电桩与服务器之间的通信协议,包括登录验证、心跳请求、计费模型验证请求、
* 数据上报等功能。支持字节码格式的数据交互,通过串口协议与服务器通信。
* @date 2025-01-09 14:32:15
* @version 1.0.0
* @copyright Copyright (c) 2026
******************************************************************************
* @file User\Protocol\Ykc\charger_to_server.c
* @author 路淮
* @version v0.1
* @date 2026-05-21
* @brief 服务器上行协议处理
******************************************************************************
*/
#include "global.h"
#include "charger_to_server.h"
uint16_t pack_serial = 0;
// 充电桩登录认证
/**
* @brief charger_to_server_0X01充电桩登录认证指令处理
* @note 发送登录认证指令到充电桩,符合协议格式要求
* @param stake_index 桩索引 (1~6)
*/
void charger_to_server_0X01(uint8_t stake_index)
{
PACK_DATA_0X01 data = {0};
@@ -26,10 +30,16 @@ void charger_to_server_0X01(uint8_t stake_index)
data.net_conn_type = g_charger_manager.charger_piles[stake_index - 1].login_info.net_conn_type;
data.tele_factory = g_charger_manager.charger_piles[stake_index - 1].login_info.tele_factory;
memcpy(data.sim, g_charger_manager.charger_piles[stake_index - 1].login_info.sim, 10);
printf("北向:对电桩 %d 发送登录认证,序列号:%s\r\n", stake_index, data.charger_serial);
printf("北向:对电桩 %d 发送登录认证\r\n", stake_index);
pack_and_send_server_data(FRAME_TYPE_0X01, (uint8_t *)&data, sizeof(PACK_DATA_0X01), stake_index);
}
/**
* @brief charger_to_server_0X03充电桩心跳请求指令处理
* @note 发送心跳请求指令到充电桩,符合协议格式要求
* @param stake_index 桩索引 (1~6)
* @param gun_index 枪索引 (1~N)
*/
void charger_to_server_0X03(uint8_t stake_index, uint8_t gun_index)
{
PACK_DATA_0X03 data = {0};
@@ -41,7 +51,12 @@ void charger_to_server_0X03(uint8_t stake_index, uint8_t gun_index)
pack_and_send_server_data(FRAME_TYPE_0X03, (uint8_t *)&data, sizeof(PACK_DATA_0X03), stake_index);
}
// 计费模型验证请求
/**
* @brief charger_to_server_0X05计费模型验证请求指令处理
* @note 发送计费模型验证请求指令到充电桩,符合协议格式要求
* @param num 计费模型号
* @param stake_index 桩索引 (1~6)
*/
void charger_to_server_0X05(uint16_t num, uint8_t stake_index)
{
PACK_DATA_0X05 data = {0};
@@ -52,16 +67,25 @@ void charger_to_server_0X05(uint16_t num, uint8_t stake_index)
pack_and_send_server_data(FRAME_TYPE_0X05, (uint8_t *)&data, sizeof(PACK_DATA_0X05), stake_index);
}
// 充电桩计费模型请求
/**
* @brief charger_to_server_0X09计费模型请求指令处理
* @note 发送计费模型请求指令到充电桩,符合协议格式要求
* @param stake_index 桩索引 (1~6)
*/
void charger_to_server_0X09(uint8_t stake_index)
{
PACK_DATA_0X09 data = {0};
load_charger_serial(stake_index, data.charger_serial); // 加载充电桩序列号
printf("北向:对电桩 %d 计费模型请求,序列号:%s\r\n", stake_index, data.charger_serial);
printf("北向:对电桩 %d 计费模型请求\r\n", stake_index);
pack_and_send_server_data(FRAME_TYPE_0X09, (uint8_t *)&data, sizeof(PACK_DATA_0X09), stake_index);
}
// 上传实时监测数据
/**
* @brief charger_to_server_0X13上传实时监测数据指令处理
* @note 发送实时监测数据指令到充电桩,符合协议格式要求
* @param stake_index 桩索引 (1~6)
* @param gun_index 枪索引 (1~N)
*/
void charger_to_server_0X13(uint8_t stake_index, uint8_t gun_index)
{
PACK_DATA_0X13 data = {0};
@@ -87,16 +111,30 @@ void charger_to_server_0X13(uint8_t stake_index, uint8_t gun_index)
pack_and_send_server_data(FRAME_TYPE_0X13, (uint8_t *)&data, sizeof(PACK_DATA_0X13), stake_index);
}
// 充电结束上报
/**
* @brief charger_to_server_0X19充电结束上报指令处理
* @note 发送充电结束上报指令到充电桩,符合协议格式要求
* @param stake_index 桩索引 (1~6)
* @param gun_index 枪索引 (1~N)
*/
void charger_to_server_0X19(uint8_t stake_index, uint8_t gun_index)
{
PACK_DATA_0X19 data = {0};
load_charger_serial(stake_index, data.charger_serial);
load_trade_serial(stake_index, gun_index, data.trade_serial);
data.gun_index = ((gun_index / 10) << 4) | (gun_index % 10);
printf("北向:对电桩 %d 枪 %d 的充电结束上报 \r\n", stake_index, gun_index);
pack_and_send_server_data(FRAME_TYPE_0X19, (uint8_t *)&data, sizeof(PACK_DATA_0X19), stake_index);
}
// 平台启动回复
/**
* @brief charger_to_server_0X33平台启动回复指令处理
* @note 发送平台启动回复指令到充电桩,符合协议格式要求
* @param stake_index 桩索引 (1~6)
* @param gun_index 枪索引 (1~N)
* @param result 结果码 0失败 1成功
* @param err_code 错误码
*/
void charger_to_server_0X33(uint8_t stake_index, uint8_t gun_index, uint8_t result, uint8_t err_code)
{
PACK_DATA_0X33 data = {0};
@@ -110,7 +148,14 @@ void charger_to_server_0X33(uint8_t stake_index, uint8_t gun_index, uint8_t resu
printf(" └── 网关向云快充发送 [%s] 电桩 %d 枪 %d的平台启动回复结果%d错误码%d\r\n",result == 0 ? "error" : "success", stake_index, gun_index, result, err_code);
pack_and_send_server_data(FRAME_TYPE_0X33, (uint8_t *)&data, sizeof(PACK_DATA_0X33), stake_index);
}
// 平台停机回复
/**
* @brief charger_to_server_0X35平台停机回复指令处理
* @note 发送平台停机回复指令到充电桩,符合协议格式要求
* @param stake_index 桩索引 (1~6)
* @param gun_index 枪索引 (1~N)
* @param result 结果码 0失败 1成功
* @param err_code 错误码
*/
void charger_to_server_0X35(uint8_t stake_index, uint8_t gun_index, uint8_t result, uint8_t err_code)
{
PACK_DATA_0X35 data = {0};
@@ -123,7 +168,12 @@ void charger_to_server_0X35(uint8_t stake_index, uint8_t gun_index, uint8_t resu
pack_and_send_server_data(FRAME_TYPE_0X35, (uint8_t *)&data, sizeof(PACK_DATA_0X35), stake_index);
}
// 上传交易记录
/**
* @brief charger_to_server_0X3B上传交易记录指令处理
* @note 发送交易记录指令到充电桩,符合协议格式要求
* @param stake_index 桩索引 (1~6)
* @param gun_index 枪索引 (1~N)
*/
void charger_to_server_0X3B(uint8_t stake_index, uint8_t gun_index)
{
PACK_DATA_0X3B data = {0};
@@ -175,7 +225,12 @@ void charger_to_server_0X3B(uint8_t stake_index, uint8_t gun_index)
pack_and_send_server_data(FRAME_TYPE_0X3B, (uint8_t *)&data, sizeof(PACK_DATA_0X3B), stake_index);
}
// 计费模型主动更新回复
/**
* @brief charger_to_server_0x57计费模型主动更新回复处理
* @note 回复计费模型主动更新回复,符合协议格式要求
* @param stake_index 桩索引 (1~6)
*/
void charger_to_server_0x57(uint8_t stake_index)
{
PACK_DATA_0X57 data = {0};

View File

@@ -1,3 +1,13 @@
/**
******************************************************************************
* @file User\Protocol\Ykc\charger_to_server.h
* @author 路淮
* @version v0.1
* @date 2026-05-21
* @brief 服务器上行协议头文件
******************************************************************************
*/
#ifndef __CHARGER_TO_SERVER_H__
#define __CHARGER_TO_SERVER_H__
@@ -8,49 +18,21 @@ extern uint16_t pack_serial;
uint32_t get_current_rtc_sec();
//充电桩登录认证请求
extern void charger_to_server_0X01(uint8_t stake_index);
//充电桩心跳包
extern void charger_to_server_0X03(uint8_t stake_index,uint8_t gun_index);
//计费模型验证请求
extern void charger_to_server_0X05(uint16_t num,uint8_t stake_index);
//充电桩计费模型请求
extern void charger_to_server_0X09(uint8_t stake_index);
//上传实时监测数据
extern void charger_to_server_0X13(uint8_t stake_index,uint8_t gun_index);
// 充电结束
extern void charger_to_server_0X19(uint8_t stake_index,uint8_t gun_index);
// 报文被改为A5A8
extern void charger_to_server_0X33(uint8_t stake_index,uint8_t gun_index, uint8_t result, uint8_t err_code);
extern void charger_to_server_0X35(uint8_t stake_index, uint8_t gun_index, uint8_t result, uint8_t err_code);
extern void charger_to_server_0X3B(uint8_t stake_index, uint8_t gun_index);
//余额更新应答
void charger_to_server_0X41(uint8_t * card_id, uint8_t result) ;
//对时设置应答
extern void charger_to_server_0X41(uint8_t * card_id, uint8_t result) ;
extern void charger_to_server_0X55(uint32_t time);
//计费模型应答
extern void charger_to_server_0X57(uint8_t stake_index);
extern uint8_t get_real_status_for_server(uint8_t idx);
//远程启机命令回复
extern void charger_to_server_0XA7(uint8_t gun_index,uint8_t start_result,uint8_t fail_reson);
//交易记录
void charger_to_server_0x3D(uint8_t gun_index,uint32_t card_id,uint8_t trade_flag,uint8_t stop_reason);
//远程重启应答
void charger_to_server_0X91(uint8_t result);
#endif

View File

@@ -1,12 +1,18 @@
#if 1
/**
******************************************************************************
* @file User\Protocol\Ykc\server_common.c
* @author 路淮
* @version v0.1
* @date 2026-05-21
* @brief 云快充协议公共函数
******************************************************************************
*/
#include "global.h"
#include "server_common.h"
#include "time.h"
#include <string.h>
uint8_t trade_serial[2][TRADE_SERIAL_LENGTH] = {0};
static FEE_MODEL current_setting_fee_model = {0};
typedef struct
{
@@ -16,6 +22,12 @@ typedef struct
static CARD_NUM card_num[2] = {0};
/**
* @brief set_card_phy_logic_num设置卡片物理或逻辑卡号
* @param idx 索引
* @param type 0:物理卡号 1:逻辑卡号
* @param num 卡号
*/
void set_card_phy_logic_num(uint8_t idx, uint8_t type, uint32_t num)
{
idx = idx - 1;
@@ -33,6 +45,11 @@ void set_card_phy_logic_num(uint8_t idx, uint8_t type, uint32_t num)
}
}
/**
* @brief get_card_phy_num获取卡片物理卡号
* @param idx 索引
* @return uint32_t 物理卡号
*/
uint32_t get_card_phy_num(uint8_t idx)
{
idx = idx - 1;
@@ -43,8 +60,14 @@ uint32_t get_card_phy_num(uint8_t idx)
return card_num[idx].phy_num;
}
/**
* @brief get_card_logic_num获取卡片逻辑卡号
* @param idx 索引
* @return uint32_t 逻辑卡号
*/
uint32_t get_card_logic_num(uint8_t idx)
{
idx = idx - 1;
if (idx >= 2)
{
return 0;
@@ -52,6 +75,11 @@ uint32_t get_card_logic_num(uint8_t idx)
return card_num[idx].logic_num;
}
/**
* @brief load_charger_serial加载充电器序列号
* @param stake_mark 充枪索引
* @param serial 序列号指针
*/
void load_charger_serial(uint8_t stake_mark, uint8_t *serial)
{
if (stake_mark > MAX_CHARGER_COUNT)
@@ -61,6 +89,12 @@ void load_charger_serial(uint8_t stake_mark, uint8_t *serial)
memcpy(serial, g_charger_manager.charger_piles[stake_mark - 1].charger_serial, CHARGER_SERIAL_LENGTH);
}
/**
* @brief set_trade_serial设置交易序列号
* @param stake_mark 充枪索引
* @param idx 枪索引
* @param serial 序列号指针
*/
void set_trade_serial(uint8_t stake_mark, uint8_t idx, uint8_t *serial)
{
if (stake_mark > MAX_CHARGER_COUNT)
@@ -74,6 +108,12 @@ void set_trade_serial(uint8_t stake_mark, uint8_t idx, uint8_t *serial)
memcpy(g_charger_manager.charger_piles[stake_mark - 1].guns[idx - 1].real_time_data.trade_serial, serial, TRADE_SERIAL_LENGTH);
}
/**
* @brief load_trade_serial加载交易序列号
* @param stake_mark 充枪索引
* @param idx 枪索引
* @param serial 序列号指针
*/
void load_trade_serial(uint8_t stake_mark, uint8_t idx, uint8_t *serial)
{
if (stake_mark > MAX_CHARGER_COUNT)
@@ -87,6 +127,12 @@ void load_trade_serial(uint8_t stake_mark, uint8_t idx, uint8_t *serial)
memcpy(serial, g_charger_manager.charger_piles[stake_mark - 1].guns[idx - 1].real_time_data.trade_serial, TRADE_SERIAL_LENGTH);
}
/**
* @brief is_my_charger_serial判断是否是当前充电枪的序列号
* @param stake_mark 充电器索引
* @param serial 序列号指针
* @return uint8_t 0:不是 1:是
*/
uint8_t is_my_charger_serial(uint8_t stake_mark, uint8_t *serial)
{
uint8_t ret = 0;
@@ -98,7 +144,7 @@ uint8_t is_my_charger_serial(uint8_t stake_mark, uint8_t *serial)
return ret;
}
// CRC 计算
// CRC 计算
const uint8_t gabyCRCHi[] =
{
0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, 0x01, 0xc0,
@@ -157,6 +203,12 @@ const uint16_t gabyCRCLo[] =
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,
0x43, 0x83, 0x41, 0x81, 0x80, 0x40};
/**
* @brief calc_crc16计算CRC16校验和
* @param pData 数据指针
* @param len 数据长度
* @return uint16_t CRC16校验和
*/
uint16_t calc_crc16(uint8_t *pData, uint8_t len)
{
uint8_t byCRCHi = 0xff;
@@ -175,6 +227,13 @@ uint16_t calc_crc16(uint8_t *pData, uint8_t len)
return crc;
}
/**
* @brief unpack_server_data解包服务器数据
* @param buf 数据指针
* @param len 数据长度
* @param pack 数据包指针
* @return uint8_t 0:失败 1:成功
*/
uint8_t unpack_server_data(uint8_t *buf, uint8_t len, SERVER_PACK *pack)
{
uint8_t ret = 0;
@@ -207,6 +266,13 @@ uint8_t unpack_server_data(uint8_t *buf, uint8_t len, SERVER_PACK *pack)
return ret;
}
/**
* @brief pack_and_send_server_data打包并发送服务器数据
* @param type 帧类型
* @param pdata 数据指针
* @param len 数据长度
* @param stake_mark 充枪索引
*/
void pack_and_send_server_data(uint8_t type, uint8_t *pdata, uint8_t len, uint8_t stake_mark)
{
uint8_t index = 0;
@@ -248,17 +314,16 @@ void pack_and_send_server_data(uint8_t type, uint8_t *pdata, uint8_t len, uint8_
buf[index++] = 0xAA;
buf[index++] = 0x55;
if (type == FRAME_TYPE_0X3B)
{
printf("北向0x3B 原始数据(%d字节): ", index);
for (uint16_t i = 0; i < index; i++)
printf("%02X ", buf[i]);
printf("\r\n");
}
Air724_Message_Send(buf, index);
vPortFree(buf);
}
/**
* @brief get_num_from_string从字符串中提取整数
* @param str 字符串指针
* @param num 整数数组指针
* @return int 提取的整数数量
*/
int get_num_from_string(const char *str, int *num)
{
int len = strlen(str);
@@ -284,6 +349,11 @@ int get_num_from_string(const char *str, int *num)
return index;
}
/**
* @brief get_cp56time_from_sec将时间戳转换为CP56时间格式
* @param buff 时间缓冲区指针
* @param sec 时间戳
*/
void get_cp56time_from_sec(uint8_t *buff, uint32_t sec)
{
struct tm timeinfo;
@@ -305,23 +375,12 @@ void get_cp56time_from_sec(uint8_t *buff, uint32_t sec)
buff[6] = (cp56time.time >> 48) & 0xFF;
}
void update_current_fee_model(FEE_MODEL *model)
{
if (!model)
{
return;
}
memcpy(&current_setting_fee_model, model, sizeof(FEE_MODEL));
}
FEE_MODEL *get_setting_fee_model(void)
{
return &current_setting_fee_model;
}
/**
* @brief htons将16位无符号整数转换为网络字节序
* @param val 16位无符号整数
* @return uint16_t 网络字节序整数
*/
uint16_t htons(uint16_t val)
{
return (val << 8) | (val >> 8);
}
#endif

View File

@@ -1,3 +1,12 @@
/**
******************************************************************************
* @file User\Protocol\Ykc\server_common.h
* @author 路淮
* @version v0.1
* @date 2026-05-21
* @brief 云快充协议数据结构文件
******************************************************************************
*/
#ifndef __SERVER_COMMON_H__
#define __SERVER_COMMON_H__
#include <stdint.h>
@@ -14,73 +23,73 @@
#define CHARGER_TYPE_DC 0
#define CHARGER_TYPE_AC 1
#define HEADER_LENGTH 6 // 消息体前的头部数据长度
#define HEADER_LENGTH 6 // 消息体前的头部数据长度
#define FRAME_TYPE_0X01 0x01 // 充电桩登录认证
#define FRAME_TYPE_0X01 0x01 // 充电桩登录认证
#define FRAME_TYPE_0X02 0x02
#define FRAME_TYPE_0X03 0x03 // 充电桩心跳包
#define FRAME_TYPE_0X03 0x03 // 充电桩心跳包
#define FRAME_TYPE_0X04 0x04
#define FRAME_TYPE_0X05 0x05 // 计费模型验证请求
#define FRAME_TYPE_0X05 0x05 // 计费模型验证请求
#define FRAME_TYPE_0X06 0x06
#define FRAME_TYPE_0X09 0x09 // 充电桩计费模型请求
#define FRAME_TYPE_0X09 0x09 // 充电桩计费模型请求
#define FRAME_TYPE_0X0A 0x0A
#define FRAME_TYPE_0X12 0x12 // 读取实时监测数据
#define FRAME_TYPE_0X12 0x12 // 读取实时监测数据
// charger ---> server
#define FRAME_TYPE_0X13 0x13 // 离线监测数据
#define FRAME_TYPE_0X15 0x15 // 充电握手
#define FRAME_TYPE_0X17 0x17 // 参数配置
#define FRAME_TYPE_0X19 0x19 // 充电结束
#define FRAME_TYPE_0X1B 0x1B // 错误报文
#define FRAME_TYPE_0X1D 0x1D // 充电阶段BMS中止
#define FRAME_TYPE_0X21 0x21 // 充电阶段充电机中止
#define FRAME_TYPE_0X23 0x23 // 充电过程BMS需求、充电机输出
#define FRAME_TYPE_0X25 0x25 // 充电过程BMS信息
#define FRAME_TYPE_0X13 0x13 // 离线监测数据
#define FRAME_TYPE_0X15 0x15 // 充电握手
#define FRAME_TYPE_0X17 0x17 // 参数配置
#define FRAME_TYPE_0X19 0x19 // 充电结束
#define FRAME_TYPE_0X1B 0x1B // 错误报文
#define FRAME_TYPE_0X1D 0x1D // 充电阶段BMS中止
#define FRAME_TYPE_0X21 0x21 // 充电阶段充电机中止
#define FRAME_TYPE_0X23 0x23 // 充电过程BMS需求、充电机输出
#define FRAME_TYPE_0X25 0x25 // 充电过程BMS信息
//---------------------------------------
#define FRAME_TYPE_0X31 0x31 // 充电桩主动申请启动充电
#define FRAME_TYPE_0X32 0x32 // 运营平台确认启动充电
#define FRAME_TYPE_0X33 0x33 // 远程启动命令回复
#define FRAME_TYPE_0X34 0x34 // 运营平台远程控制启动
#define FRAME_TYPE_0X31 0x31 // 充电桩主动申请启动充电
#define FRAME_TYPE_0X32 0x32 // 运营平台确认启动充电
#define FRAME_TYPE_0X33 0x33 // 远程启动命令回复
#define FRAME_TYPE_0X34 0x34 // 运营平台远程控制启动
#define FRAME_TYPE_0X35 0x35 // 远程停机命令回复
#define FRAME_TYPE_0X36 0x36 // 运营平台远程停机
#define FRAME_TYPE_0X35 0x35 // 远程停机命令回复
#define FRAME_TYPE_0X36 0x36 // 运营平台远程停机
//---------------------------------------
#define FRAME_TYPE_0X3B 0x3B // 交易记录
#define FRAME_TYPE_0X40 0x40 // 交易记录确认
#define FRAME_TYPE_0X41 0x41 // 交易更新应答
#define FRAME_TYPE_0X42 0x42 // 远程账户余额更新
#define FRAME_TYPE_0X43 0x43 // 卡数据同步
#define FRAME_TYPE_0X44 0x44 // 离线卡数据同步
#define FRAME_TYPE_0X45 0x45 // 离线卡数据清除
#define FRAME_TYPE_0X46 0x46 // 离线卡数据清除应答
#define FRAME_TYPE_0X47 0x47 // 离线卡数据清除
#define FRAME_TYPE_0X48 0x48 // 离线卡数据清除应答
#define FRAME_TYPE_0X3B 0x3B // 交易记录
#define FRAME_TYPE_0X40 0x40 // 交易记录确认
#define FRAME_TYPE_0X41 0x41 // 交易更新应答
#define FRAME_TYPE_0X42 0x42 // 远程账户余额更新
#define FRAME_TYPE_0X43 0x43 // 卡数据同步
#define FRAME_TYPE_0X44 0x44 // 离线卡数据同步
#define FRAME_TYPE_0X45 0x45 // 离线卡数据清除
#define FRAME_TYPE_0X46 0x46 // 离线卡数据清除应答
#define FRAME_TYPE_0X47 0x47 // 离线卡数据清除
#define FRAME_TYPE_0X48 0x48 // 离线卡数据清除应答
#define FRAME_TYPE_0X51 0x51 // 充电桩工作参数设置应答
#define FRAME_TYPE_0X52 0x52 // 充电桩工作参数设置
#define FRAME_TYPE_0X51 0x51 // 充电桩工作参数设置应答
#define FRAME_TYPE_0X52 0x52 // 充电桩工作参数设置
#define FRAME_TYPE_0X55 0x55 // 对时设置应答
#define FRAME_TYPE_0X56 0x56 // 对时设置
#define FRAME_TYPE_0X55 0x55 // 对时设置应答
#define FRAME_TYPE_0X56 0x56 // 对时设置
#define FRAME_TYPE_0X57 0x57 // 计费模型应答
#define FRAME_TYPE_0X58 0x58 // 计算模型设置
#define FRAME_TYPE_0X57 0x57 // 计费模型应答
#define FRAME_TYPE_0X58 0x58 // 计算模型设置
#define FRAME_TYPE_0X61 0x61 // 地锁数据上送
#define FRAME_TYPE_0X62 0x62 // 遥控地锁升锁与降锁
#define FRAME_TYPE_0X63 0x63 // 充电桩返回数据
#define FRAME_TYPE_0X61 0x61 // 地锁数据上送
#define FRAME_TYPE_0X62 0x62 // 遥控地锁升锁与降锁
#define FRAME_TYPE_0X63 0x63 // 充电桩返回数据
#define FRAME_TYPE_0X91 0x91 // 远程启动应答
#define FRAME_TYPE_0X92 0x92 // 远程启动
#define FRAME_TYPE_0X93 0x93 // 远程更新应答
#define FRAME_TYPE_0X94 0x94 // 远程更新
#define FRAME_TYPE_0X91 0x91 // 远程启动应答
#define FRAME_TYPE_0X92 0x92 // 远程启动
#define FRAME_TYPE_0X93 0x93 // 远程更新应答
#define FRAME_TYPE_0X94 0x94 // 远程更新
#define FRAME_TYPE_0XA1 0xA1 // 充电桩主动申请并充充电
#define FRAME_TYPE_0XA2 0xA2 // 运营平台确认并充启动充电
#define FRAME_TYPE_0XA1 0xA1 // 充电桩主动申请并充充电
#define FRAME_TYPE_0XA2 0xA2 // 运营平台确认并充启动充电
#define FRAME_TYPE_0XA3 0xA3 // 远程并充启机命令回复
#define FRAME_TYPE_0XA4 0xA4 // 运营平台远程控制并充启机
#define FRAME_TYPE_0XA3 0xA3 // 远程并充启机命令回复
#define FRAME_TYPE_0XA4 0xA4 // 运营平台远程控制并充启机
#define FRAME_TYPE_0XA7 0xA7
#define FRAME_TYPE_0X91 0x91
#define FRAME_TYPE_0X92 0x92
@@ -112,7 +121,7 @@ typedef enum
STOP_REASON_MANUAL = 0x45,
STOP_REASON_INSUFFICIENT_BALANCE = 0x6E,
STOP_REASON_EMERGENCY_STOP = 0x72,
STOP_REASON_OTHER // 其他原因可以添加在这里
STOP_REASON_OTHER // 其他原因可以添加在这里
} StopReason;
typedef struct
@@ -128,333 +137,333 @@ typedef struct
typedef struct
{
float voltage; // 电压 (单位: V)
float charge_energy; // 充电能量 (单位: kWh)
float current; // 电流 (单位: A)
unsigned long charge_time; // 充电时间 (单位: 秒)
float charge_money; // 充电费用 (单位: 元)
float voltage; // 电压 (单位: V)
float charge_energy; // 充电能量 (单位: kWh)
float current; // 电流 (单位: A)
unsigned long charge_time; // 充电时间 (单位: 秒)
float charge_money; // 充电费用 (单位: 元)
} CHARGING_GUN_CTRL;
typedef struct
{
uint16_t fee_model_no; // 计费模型编号
uint32_t shark_fee_ratio; // 尖费电费费率
uint32_t shark_service_ratio; // 尖服务费费率
uint32_t peak_fee_ratio; // 峰电费费率
uint32_t peak_service_ratio; // 峰服务费费率
uint32_t flat_fee_ratio; // 平电费费率
uint32_t flat_service_ratio; // 平服务费费率
uint32_t valley_fee_ratio; // 谷电费费率
uint32_t valley_service_ratio; // 谷服务费费率
uint8_t loss_ratio; // 计损比例
uint8_t fee_num[48]; // 0x00尖费率 0x01峰费率 0x02平费率 0x03谷费率
uint16_t fee_model_no; // 计费模型编号
uint32_t shark_fee_ratio; // 尖费电费费率
uint32_t shark_service_ratio; // 尖服务费费率
uint32_t peak_fee_ratio; // 峰电费费率
uint32_t peak_service_ratio; // 峰服务费费率
uint32_t flat_fee_ratio; // 平电费费率
uint32_t flat_service_ratio; // 平服务费费率
uint32_t valley_fee_ratio; // 谷电费费率
uint32_t valley_service_ratio; // 谷服务费费率
uint8_t loss_ratio; // 计损比例
uint8_t fee_num[48]; // 0x00尖费率 0x01峰费率 0x02平费率 0x03谷费率
} __attribute__((packed)) FEE_MODEL;
typedef struct
{
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编码
uint8_t charger_type; // 桩类型,0--DC,1--AC
uint8_t gun_num; // 充电枪个数
uint8_t protocol_ver; // 协议版本
uint8_t software_ver[8]; // 程序版本
uint8_t net_conn_type; // 网络链接类型,0SIM卡,1:LAN,2WAN,03:others
uint8_t sim[10]; // SIM卡
uint8_t tele_factory; // 0x00,移动,02:电信,03:联通,04:其他
} __attribute__((packed)) PACK_DATA_0X01; // 0x01 充电桩登陆认证
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编码
uint8_t charger_type; // 桩类型,0--DC,1--AC
uint8_t gun_num; // 充电枪个数
uint8_t protocol_ver; // 协议版本
uint8_t software_ver[8]; // 程序版本
uint8_t net_conn_type; // 网络链接类型,0SIM卡,1:LAN,2WAN,03:others
uint8_t sim[10]; // SIM卡
uint8_t tele_factory; // 0x00,移动,02:电信,03:联通,04:其他
} __attribute__((packed)) PACK_DATA_0X01; // 0x01 充电桩登陆认证
typedef struct
{
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编码
uint8_t result; // 登陆结果
} __attribute__((packed)) PACK_DATA_0X02; // 0x02 充电桩登陆认证应答;
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编码
uint8_t result; // 登陆结果
} __attribute__((packed)) PACK_DATA_0X02; // 0x02 充电桩登陆认证应答;
typedef struct
{
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编码
uint8_t gun_index; // 枪号
uint8_t gun_status; // 枪状态,0:正常,1:异常
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编码
uint8_t gun_index; // 枪号
uint8_t gun_status; // 枪状态,0:正常,1:异常
} __attribute__((packed)) PACK_DATA_0X03; // 0x03
typedef struct
{
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编码
uint8_t gun_index; // 枪号
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编码
uint8_t gun_index; // 枪号
uint8_t ack; // 0
} __attribute__((packed)) PACK_DATA_0X04; // 0x04
typedef struct
{
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编码
uint16_t fee_model_no; // 计费模型编号
} __attribute__((packed)) PACK_DATA_0X05; // 05 计费模型验证请求
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编码
uint16_t fee_model_no; // 计费模型编号
} __attribute__((packed)) PACK_DATA_0X05; // 05 计费模型验证请求
typedef struct
{
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编码
uint16_t fee_model_no; // 计费模型编号
uint8_t result; // 0x00 桩计费模型与平台一致,0x01 桩计费模型与平台不一致
} __attribute__((packed)) PACK_DATA_0X06; // 06 计费模型验证请求
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编码
uint16_t fee_model_no; // 计费模型编号
uint8_t result; // 0x00 桩计费模型与平台一致,0x01 桩计费模型与平台不一致
} __attribute__((packed)) PACK_DATA_0X06; // 06 计费模型验证请求
typedef struct
{
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编码
} __attribute__((packed)) PACK_DATA_0X09; // 0x09 计费模型请求
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编码
} __attribute__((packed)) PACK_DATA_0X09; // 0x09 计费模型请求
typedef struct
{
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编码
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编码
FEE_MODEL model;
} __attribute__((packed)) PACK_DATA_0X0A; // 0x0A
typedef struct
{
uint8_t trade_serial[TRADE_SERIAL_LENGTH]; // 交易流水号
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编号
uint8_t gun_index; // 枪编号
uint8_t status; // 状态
uint8_t gun_back; // 枪是否归位
uint8_t gun_is_insert; // 是否插枪
uint16_t out_voltage; // 输出电压,小数点后一位,待机置0
uint16_t out_current; // 输出电流,小数点后一位,待机置0
uint8_t gun_line_temp; // 枪线温度
uint8_t gun_line_num[8]; // 枪线编码
uint8_t soc; // 待机置零;交流桩置零
uint8_t battery_temp; // 电池组最高温度.整形,偏移量-50 oC待机置零交流桩置零
uint16_t charge_time; // 累计充电时间
uint16_t remain_time; // 剩余时间
uint32_t charge_energy; // 充电度数
uint32_t loss_energy; // 计损充电度数
uint32_t charge_money; // 已充金额
uint16_t hard_fault; // 硬件故障
uint8_t trade_serial[TRADE_SERIAL_LENGTH]; // 交易流水号
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编号
uint8_t gun_index; // 枪编号
uint8_t status; // 状态
uint8_t gun_back; // 枪是否归位
uint8_t gun_is_insert; // 是否插枪
uint16_t out_voltage; // 输出电压,小数点后一位,待机置0
uint16_t out_current; // 输出电流,小数点后一位,待机置0
uint8_t gun_line_temp; // 枪线温度
uint8_t gun_line_num[8]; // 枪线编码
uint8_t soc; // 待机置零;交流桩置零
uint8_t battery_temp; // 电池组最高温度.整形,偏移量-50 oC待机置零交流桩置零
uint16_t charge_time; // 累计充电时间
uint16_t remain_time; // 剩余时间
uint32_t charge_energy; // 充电度数
uint32_t loss_energy; // 计损充电度数
uint32_t charge_money; // 已充金额
uint16_t hard_fault; // 硬件故障
} __attribute__((packed)) PACK_DATA_0X13; // 0x13
typedef struct
{
uint8_t trade_serial[TRADE_SERIAL_LENGTH]; // 交易流水号
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编号
uint8_t gun_index; // 枪编号
uint8_t trade_serial[TRADE_SERIAL_LENGTH]; // 交易流水号
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编号
uint8_t gun_index; // 枪编号
uint8_t bms_soc; //
uint16_t bms_vol_low; //
uint16_t bms_vol_high;
uint8_t bms_temp_low; //
uint8_t bms_temp_high;
uint16_t charge_time; // 电桩累计充电时间
uint16_t out_energy; // 电桩输出能量
uint32_t charger_motor_no; // 充电桩电机编号
uint16_t charge_time; // 电桩累计充电时间
uint16_t out_energy; // 电桩输出能量
uint32_t charger_motor_no; // 充电桩电机编号
} __attribute__((packed)) PACK_DATA_0X19; // 0x19
typedef struct
{
uint8_t trade_serial[TRADE_SERIAL_LENGTH]; // 交易流水号
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编号
uint8_t gun_index; // 枪号
uint16_t bms_vol_demand; // BMS电压需求 0.1V/位
uint16_t bms_cur_demand; // BMS电流需求 0.1A/位, -400A偏移
uint8_t bms_charge_mode; // BMS充电模式 0x01:恒压 0x02:恒流
uint16_t bms_vol_measure; // BMS充电电压测量值 0.1V/位
uint16_t bms_cur_measure; // BMS充电电流测量值 0.1A/位, -400A偏移
uint16_t bms_max_cell_vol; // BMS最高单体电压及组号 低12位:0.01V/位 高4位:组号
uint8_t bms_soc; // BMS当前SOC 1%/位 0~100%
uint16_t bms_remain_time; // BMS估算剩余充电时间 1min/位 0~600min
uint16_t charger_vol_output; // 电桩电压输出值 0.1V/位
uint16_t charger_cur_output; // 电桩电流输出值 0.1A/位, -400A偏移
uint16_t charge_time; // 累计充电时间 1min/位 0~600min
uint8_t trade_serial[TRADE_SERIAL_LENGTH]; // 交易流水号
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编号
uint8_t gun_index; // 枪号
uint16_t bms_vol_demand; // BMS电压需求 0.1V/位
uint16_t bms_cur_demand; // BMS电流需求 0.1A/位, -400A偏移
uint8_t bms_charge_mode; // BMS充电模式 0x01:恒压 0x02:恒流
uint16_t bms_vol_measure; // BMS充电电压测量值 0.1V/位
uint16_t bms_cur_measure; // BMS充电电流测量值 0.1A/位, -400A偏移
uint16_t bms_max_cell_vol; // BMS最高单体电压及组号 低12位:0.01V/位 高4位:组号
uint8_t bms_soc; // BMS当前SOC 1%/位 0~100%
uint16_t bms_remain_time; // BMS估算剩余充电时间 1min/位 0~600min
uint16_t charger_vol_output; // 电桩电压输出值 0.1V/位
uint16_t charger_cur_output; // 电桩电流输出值 0.1A/位, -400A偏移
uint16_t charge_time; // 累计充电时间 1min/位 0~600min
} __attribute__((packed)) PACK_DATA_0X23; // 0x23
typedef struct
{
uint8_t trade_serial[TRADE_SERIAL_LENGTH]; // 交易流水号
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编号
uint8_t gun_index; // 枪号
uint8_t bms_max_cell_vol_num; // BMS最高单体电压所在编号 1/位,1偏移 1~256
uint8_t bms_max_temp; // BMS最高动力蓄电池温度 1°C/位,-50°C偏移
uint8_t max_temp_point_num; // 最高温度检测点编号 1/位,1偏移 1~128
uint8_t bms_min_temp; // 最低动力蓄电池温度 1°C/位,-50°C偏移
uint8_t min_temp_point_num; // 最低温度检测点编号 1/位,1偏移 1~128
uint8_t bms_alarm_1; // 位0-1:单体电压过高/过低 位2-3:SOC过高/过低 位4-5:充电过流 位6-7:温度过高 (<00>:正常 <01>:过高 <10>:过低)
uint8_t bms_alarm_2; // 位0-1:绝缘状态 位2-3:输出连接器状态 位4-5:充电禁止 位6-7:预留 (<00>:正常 <01>:异常 <10>:不可信)
uint8_t trade_serial[TRADE_SERIAL_LENGTH]; // 交易流水号
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编号
uint8_t gun_index; // 枪号
uint8_t bms_max_cell_vol_num; // BMS最高单体电压所在编号 1/位,1偏移 1~256
uint8_t bms_max_temp; // BMS最高动力蓄电池温度 1°C/位,-50°C偏移
uint8_t max_temp_point_num; // 最高温度检测点编号 1/位,1偏移 1~128
uint8_t bms_min_temp; // 最低动力蓄电池温度 1°C/位,-50°C偏移
uint8_t min_temp_point_num; // 最低温度检测点编号 1/位,1偏移 1~128
uint8_t bms_alarm_1; // 位0-1:单体电压过高/过低 位2-3:SOC过高/过低 位4-5:充电过流 位6-7:温度过高 (<00>:正常 <01>:过高 <10>:过低)
uint8_t bms_alarm_2; // 位0-1:绝缘状态 位2-3:输出连接器状态 位4-5:充电禁止 位6-7:预留 (<00>:正常 <01>:异常 <10>:不可信)
} __attribute__((packed)) PACK_DATA_0X25; // 0x25
typedef struct
{
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编号
uint8_t gun_index; // 枪编号
uint8_t start_mode; // 启动方式,0x1刷卡启动,0x02,账号启动,0x03VIN码启动
uint8_t password_flag; // 是否需要密码
uint8_t card_no[8]; // 账号或物理卡号
uint8_t password[16]; // 对用户输入的密码进行16位MD5加密,小写上传
uint8_t vin[17]; // VIN码,非VIN码方式为0
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编号
uint8_t gun_index; // 枪编号
uint8_t start_mode; // 启动方式,0x1刷卡启动,0x02,账号启动,0x03VIN码启动
uint8_t password_flag; // 是否需要密码
uint8_t card_no[8]; // 账号或物理卡号
uint8_t password[16]; // 对用户输入的密码进行16位MD5加密,小写上传
uint8_t vin[17]; // VIN码,非VIN码方式为0
} __attribute__((packed)) PACK_DATA_0X31; // 0x31
typedef struct
{
uint8_t trade_serial[TRADE_SERIAL_LENGTH]; // 交易流水号
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编号
uint8_t gun_index; // 枪编号
uint8_t logic_card_no[8]; // 逻辑卡号
uint32_t remain_money; // 账户余额
uint8_t result; // 鉴权成功标志,0失败,1成功
uint8_t err_code; // 失败原因,0x01账户不存在,0x02账户冻结,0x03余额不足,0x04未结账记录,0x05桩停用
// 0x06账户不能在此桩充电,0x07密码错误,0x08电站电容不足,0x09VIN码不存在,
// 0x0A该桩存在未结账记录,0x0B该桩不支持刷卡
uint8_t trade_serial[TRADE_SERIAL_LENGTH]; // 交易流水号
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编号
uint8_t gun_index; // 枪编号
uint8_t logic_card_no[8]; // 逻辑卡号
uint32_t remain_money; // 账户余额
uint8_t result; // 鉴权成功标志,0失败,1成功
uint8_t err_code; // 失败原因,0x01账户不存在,0x02账户冻结,0x03余额不足,0x04未结账记录,0x05桩停用
// 0x06账户不能在此桩充电,0x07密码错误,0x08电站电容不足,0x09VIN码不存在,
// 0x0A该桩存在未结账记录,0x0B该桩不支持刷卡
} __attribute__((packed)) PACK_DATA_0X32; // 0x32
typedef struct
{
uint8_t trade_serial[TRADE_SERIAL_LENGTH]; // 交易流水号
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编号
uint8_t gun_index; // 枪编号
uint8_t result; // 启动结果
uint8_t err_code; // 失败原因
uint8_t trade_serial[TRADE_SERIAL_LENGTH]; // 交易流水号
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编号
uint8_t gun_index; // 枪编号
uint8_t result; // 启动结果
uint8_t err_code; // 失败原因
} __attribute__((packed)) PACK_DATA_0X33; // 0x33
typedef struct
{
uint8_t trade_serial[TRADE_SERIAL_LENGTH]; // 交易流水号
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编号
uint8_t gun_index; // 枪编号
uint8_t logic_cardid[8]; // 逻辑卡号
uint8_t phy_cardid[8]; // 物理卡号
uint32_t remain_money; // 账户余额,0.01元
uint16_t max_power; // 最大功率
uint8_t trade_serial[TRADE_SERIAL_LENGTH]; // 交易流水号
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编号
uint8_t gun_index; // 枪编号
uint8_t logic_cardid[8]; // 逻辑卡号
uint8_t phy_cardid[8]; // 物理卡号
uint32_t remain_money; // 账户余额,0.01元
uint16_t max_power; // 最大功率
} __attribute__((packed)) PACK_DATA_0X34; // 0x34
typedef struct
{
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编号
uint8_t gun_index; // 枪编号
uint8_t result; // 停止结果,0x00失败 0x01成功
uint8_t err_code; // 失败原因,0x0无
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编号
uint8_t gun_index; // 枪编号
uint8_t result; // 停止结果,0x00失败 0x01成功
uint8_t err_code; // 失败原因,0x0无
} __attribute__((packed)) PACK_DATA_0X35; // 0x35
typedef struct
{
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编号
uint8_t gun_index; // 枪编号
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编号
uint8_t gun_index; // 枪编号
} __attribute__((packed)) PACK_DATA_0X36; // 0x36
typedef struct
{
uint8_t trade_serial[TRADE_SERIAL_LENGTH]; // 交易流水号
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编号
uint8_t gun_index; // 枪编号
uint8_t trade_serial[TRADE_SERIAL_LENGTH]; // 交易流水号
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编号
uint8_t gun_index; // 枪编号
uint8_t start_time[7]; // 开始时间
uint8_t end_time[7]; // 结束时间
uint8_t start_time[7]; // 开始时间
uint8_t end_time[7]; // 结束时间
uint32_t shark_price; // 尖单价
uint32_t shark_energy; // 尖电量
uint32_t loss_shark_energy; // 计损尖电量
uint32_t shark_money; // 尖金额
uint32_t shark_price; // 尖单价
uint32_t shark_energy; // 尖电量
uint32_t loss_shark_energy; // 计损尖电量
uint32_t shark_money; // 尖金额
uint32_t peak_price; // 峰单价
uint32_t peak_energy; // 峰电量
uint32_t loss_peak_energy; // 计损峰电量
uint32_t peak_money; // 峰金额
uint32_t peak_price; // 峰单价
uint32_t peak_energy; // 峰电量
uint32_t loss_peak_energy; // 计损峰电量
uint32_t peak_money; // 峰金额
uint32_t flat_price; // 平单价
uint32_t flat_energy; // 平电量
uint32_t loss_flat_energy; // 计损平电量
uint32_t flat_money; // 平金额
uint32_t flat_price; // 平单价
uint32_t flat_energy; // 平电量
uint32_t loss_flat_energy; // 计损平电量
uint32_t flat_money; // 平金额
uint32_t valley_price; // 谷单价
uint32_t valley_energy; // 谷电量
uint32_t loss_valley_energy; // 计损谷电量
uint32_t valley_money; // 谷金额
uint32_t valley_price; // 谷单价
uint32_t valley_energy; // 谷电量
uint32_t loss_valley_energy; // 计损谷电量
uint32_t valley_money; // 谷金额
uint8_t meter_start_value[5];
uint8_t meter_end_value[5];
uint32_t total_energy; // 总电量
uint32_t loss_total_energy; // 计损总电量
uint32_t consumption; // 消费金额
uint8_t vin[17]; // 电动汽车唯一标识
uint8_t trade_flag; // 交易标识
uint8_t trade_time[7]; // 交易时间
uint8_t stop_reason; // 停止原因
uint8_t phy_cardid[8]; // 物理卡号
uint32_t total_energy; // 总电量
uint32_t loss_total_energy; // 计损总电量
uint32_t consumption; // 消费金额
uint8_t vin[17]; // 电动汽车唯一标识
uint8_t trade_flag; // 交易标识
uint8_t trade_time[7]; // 交易时间
uint8_t stop_reason; // 停止原因
uint8_t phy_cardid[8]; // 物理卡号
} __attribute__((packed)) PACK_DATA_0X3B; // 0x3B
typedef struct
{
uint8_t trade_serial[TRADE_SERIAL_LENGTH]; // 交易流水号
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编号
uint8_t gun_index; // 枪编号
uint8_t logical_card_number[8]; // 逻辑卡号
uint8_t physical_card_number[8]; // 物理卡号
uint8_t balance[4]; // 账户余额
uint8_t max_power[2]; // 最大功率
uint8_t trade_serial[TRADE_SERIAL_LENGTH]; // 交易流水号
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编号
uint8_t gun_index; // 枪编号
uint8_t logical_card_number[8]; // 逻辑卡号
uint8_t physical_card_number[8]; // 物理卡号
uint8_t balance[4]; // 账户余额
uint8_t max_power[2]; // 最大功率
} __attribute__((packed)) PACK_DATA_0XA8;
typedef struct
{
uint8_t trade_serial[TRADE_SERIAL_LENGTH]; // 交易流水号
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编号
uint8_t gun_index; // 枪编号
uint8_t trade_serial[TRADE_SERIAL_LENGTH]; // 交易流水号
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编号
uint8_t gun_index; // 枪编号
uint8_t result[1];
uint8_t reson[1];
} __attribute__((packed)) PACK_DATA_0XA7;
typedef struct
{
uint8_t trade_serial[TRADE_SERIAL_LENGTH]; // 交易流水号
uint8_t trade_serial[TRADE_SERIAL_LENGTH]; // 交易流水号
uint8_t result;
} __attribute__((packed)) PACK_DATA_0X40;
typedef struct
{
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编号
uint8_t phy_cardid[8]; // 物理卡号
uint8_t result; // 0:修改成功,1:设备编码错误,2:卡号错误
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编号
uint8_t phy_cardid[8]; // 物理卡号
uint8_t result; // 0:修改成功,1:设备编码错误,2:卡号错误
} __attribute__((packed)) PACK_DATA_0X41;
typedef struct
{
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编号
uint8_t gun_index; // 枪编号
uint8_t phy_cardid[8]; // 物理卡号
uint8_t remain_money[4]; // 修复后的余额
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编号
uint8_t gun_index; // 枪编号
uint8_t phy_cardid[8]; // 物理卡号
uint8_t remain_money[4]; // 修复后的余额
} __attribute__((packed)) PACK_DATA_0X42;
typedef struct
{
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编号
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编号
uint8_t current_time[7];
} __attribute__((packed)) PACK_DATA_0X55;
typedef struct
{
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编号
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编号
uint8_t current_time[7];
} __attribute__((packed)) PACK_DATA_0X56;
typedef struct
{
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编码
uint8_t result; // 设置结果
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编码
uint8_t result; // 设置结果
} __attribute__((packed)) PACK_DATA_0X57; // 0x57
typedef struct
{
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编码
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编码
FEE_MODEL model;
} __attribute__((packed)) PACK_DATA_0X58; // 0x58
typedef struct
{
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编码
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编码
uint8_t control_mode;
} __attribute__((packed)) PACK_DATA_0X92; // 0x92
typedef struct
{
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编码
uint8_t charger_serial[CHARGER_SERIAL_LENGTH]; // 桩编码
uint8_t result;
} __attribute__((packed)) PACK_DATA_0X91; // 0x91
#pragma pack(1)
typedef volatile union
{
uint64_t time; // 低7字节是七个八位位组二进制时间
uint64_t time; // 低7字节是七个八位位组二进制时间
struct
{
uint16_t msec;
@@ -482,13 +491,9 @@ struct QueueItem
};
extern void load_charger_serial(uint8_t stake_mark, uint8_t *serial);
extern void set_charger_serial_for_server(uint8_t value, uint8_t offset);
extern uint8_t is_my_charger_serial(uint8_t stake_mark, uint8_t *serial);
extern void load_trade_serial(uint8_t stake_mark, uint8_t idx, uint8_t *serial);
extern void set_trade_serial(uint8_t stake_mark, uint8_t idx, uint8_t *serial);
extern void increase_heart_beat_cnt(void);
extern void reset_heart_beat_cnt(void);
extern uint32_t get_heart_beat_cnt(void);
extern uint8_t unpack_server_data(uint8_t *buf, uint8_t len, SERVER_PACK *pack);
extern void pack_and_send_server_data(uint8_t type, uint8_t *data, uint8_t len, uint8_t stake_mark);
extern int get_num_from_string(const char *str, int *num);
@@ -496,10 +501,5 @@ extern uint32_t get_card_logic_num(uint8_t idx);
extern uint32_t get_card_phy_num(uint8_t idx);
extern void set_card_phy_logic_num(uint8_t idx, uint8_t type, uint32_t num);
extern void get_cp56time_from_sec(uint8_t *buff, uint32_t sec);
extern void update_current_fee_model(FEE_MODEL *model);
extern FEE_MODEL *get_setting_fee_model(void);
extern void generateTransactionID(uint8_t *buffer, uint16_t bufferSize, uint8_t gun_num);
extern void printLocalTime();
extern void sendFailureReasonToQueue(StopReason reason);
uint16_t htons(uint16_t val);
#endif

View File

@@ -1,17 +1,22 @@
/**
* @file server_to_charger.c
* @brief 充电桩通信协议处理模块 下行数据
* @details 处理充电桩与服务器之间的通信协议,包括登录认证应答、心跳应答、计费模型验证应答、
* 等功能。支持字节码格式的数据交互,通过串口协议与服务器通信。
* @date 2025-01-09 14:32:15
* @version 1.0.0
* @copyright Copyright (c) 2026
******************************************************************************
* @file User\Protocol\Ykc\server_to_charger.c
* @author 路淮
* @version v0.1
* @date 2026-05-21
* @brief 服务器下行协议处理
******************************************************************************
*/
#include "global.h"
#include "server_to_charger.h"
#include "point_protocol.h"
#include "host_computer_protocol.h"
// 登录认证应答
/**
* @brief on_cmd_frame_type_0X02处理登录认证应答
* @param stake_index 充电桩索引
* @param pack 服务器下行协议数据包指针
*/
void on_cmd_frame_type_0X02(uint8_t stake_index, SERVER_PACK *pack)
{
PACK_DATA_0X02 data;
@@ -28,7 +33,11 @@ void on_cmd_frame_type_0X02(uint8_t stake_index, SERVER_PACK *pack)
}
}
// 心跳应答
/**
* @brief on_cmd_frame_type_0X04处理心跳应答
* @param stake_index 充电桩索引
* @param pack 服务器下行协议数据包指针
*/
void on_cmd_frame_type_0X04(uint8_t stake_index, SERVER_PACK *pack)
{
PACK_DATA_0X04 data;
@@ -38,7 +47,11 @@ void on_cmd_frame_type_0X04(uint8_t stake_index, SERVER_PACK *pack)
#endif
}
// 计费模型验证应答
/**
* @brief on_cmd_frame_type_0X06处理计费模型验证应答
* @param stake_index 充电桩索引
* @param pack 服务器下行协议数据包指针
*/
void on_cmd_frame_type_0X06(uint8_t stake_index, SERVER_PACK *pack)
{
PACK_DATA_0X06 data;
@@ -51,7 +64,11 @@ void on_cmd_frame_type_0X06(uint8_t stake_index, SERVER_PACK *pack)
}
}
// 获取计费模型
/**
* @brief on_cmd_frame_type_0X0A处理获取计费模型
* @param stake_index 充电桩索引
* @param pack 服务器下行协议数据包指针
*/
void on_cmd_frame_type_0X0A(uint8_t stake_index, SERVER_PACK *pack)
{
PACK_DATA_0X0A data;
@@ -133,6 +150,11 @@ void on_cmd_frame_type_0X0A(uint8_t stake_index, SERVER_PACK *pack)
}
}
/**
* @brief on_cmd_frame_type_0X58处理计费模型更新设置
* @param stake_index 充电桩索引
* @param pack 服务器下行协议数据包指针
*/
void on_cmd_frame_type_0X58(uint8_t stake_index, SERVER_PACK *pack)
{
PACK_DATA_0X58 data;
@@ -140,7 +162,6 @@ void on_cmd_frame_type_0X58(uint8_t stake_index, SERVER_PACK *pack)
if (is_my_charger_serial(stake_index, data.charger_serial))
{
g_charger_manager.fee_model_global = data.model;
g_charger_manager.charger_piles[stake_index - 1].get_model = true;
@@ -216,7 +237,11 @@ void on_cmd_frame_type_0X58(uint8_t stake_index, SERVER_PACK *pack)
}
}
// 平台控制充电
/**
* @brief on_cmd_frame_type_0X34处理平台控制启动充电
* @param stake_index 充电桩索引
* @param pack 服务器下行协议数据包指针
*/
void on_cmd_frame_type_0X34(uint8_t stake_index, SERVER_PACK *pack)
{
PACK_DATA_0X34 data;
@@ -239,7 +264,11 @@ void on_cmd_frame_type_0X34(uint8_t stake_index, SERVER_PACK *pack)
printf(" └── [info] 等待桩启动回应...\r\n");
}
// 平台控制停止充电
/**
* @brief on_cmd_frame_type_0X36处理平台控制停止充电
* @param stake_index 充电桩索引
* @param pack 服务器下行协议数据包指针
*/
void on_cmd_frame_type_0X36(uint8_t stake_index, SERVER_PACK *pack)
{
PACK_DATA_0X36 data;
@@ -265,15 +294,18 @@ void on_cmd_frame_type_0X36(uint8_t stake_index, SERVER_PACK *pack)
}
// 平台接收到交易记录
/**
* @brief on_cmd_frame_type_0X40处理平台接收到交易记录
* @param stake_index 充电桩索引
* @param pack 服务器下行协议数据包指针
*/
void on_cmd_frame_type_0X40(uint8_t stake_index, SERVER_PACK *pack)
{
PACK_DATA_0X40 data;
memcpy(&data, pack->data, sizeof(PACK_DATA_0X40));
printf("北向:平台接收到交易记录,桩ID:%d, 交易记录:%s\r\n", stake_index, data.trade_serial);
if (data.result == 0)
{
printf("1234567890987654324567898765434567890-98765165165165*************************************成功\r\n");
printf("北向:平台接收到交易记录,桩ID:%d, 交易记录:%s\r\n", stake_index, data.trade_serial);
return;
}
}

View File

@@ -1,3 +1,13 @@
/**
******************************************************************************
* @file User\Protocol\Ykc\server_to_charger.h
* @author 路淮
* @version v0.1
* @date 2026-05-21
* @brief 服务器下行协议头文件
******************************************************************************
*/
#ifndef __SERVER_TO_CHARGER_H__
#define __SERVER_TO_CHARGER_H__

View File

@@ -1,3 +1,13 @@
/**
******************************************************************************
* @file User\Protocol\Ykc\ykc_router.c
* @author 路淮
* @version v0.1
* @date 2026-05-21
* @brief 云快充协议路由分发
******************************************************************************
*/
#include "ykc_router.h"
static const ykc_route_entry_t YKC_ROUTE_TABLE[] = {

View File

@@ -1,3 +1,13 @@
/**
******************************************************************************
* @file User\Protocol\Ykc\ykc_router.h
* @author 路淮
* @version v0.1
* @date 2026-05-21
* @brief 云快充协议路由分发头文件
******************************************************************************
*/
#ifndef __YKC_ROUTER_H
#define __YKC_ROUTER_H