Files
CCU621M/app/publicdata/public_func.c
T

390 lines
13 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "publicdata/publicdata.h"
#include "app_init/app_init.h"
#include <string.h>
/**
* ************************************************************************
* @brief - 全局应用函数接口文件--用于汇总所有公共函数
*
* @author jiankalka
* @date 2025-09-12
* ************************************************************************
*/
const char *success = "success";
const char *failure = "failure";
#if 1 //数据校验函数
//CRC校验驱动表
const U8_T aucCRCHi[] = {
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40
};
const U8_T aucCRCLo[] = {
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7,
0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E,
0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9,
0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC,
0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32,
0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D,
0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38,
0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF,
0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1,
0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4,
0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB,
0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA,
0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0,
0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97,
0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E,
0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89,
0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83,
0x41, 0x81, 0x80, 0x40
};
//计算累加和校验
U16_T u16_crc_checksum(U8_T *p, U16_T u16_len)
{
U16_T i;
U16_T u16_sum = 0;
for (i=0; i<u16_len; i++)
u16_sum += *(p+i);
return u16_sum;
}
//modbus crc16校验函数
U16_T u16_modbus_crc16( U8_T * pucFrame, U16_T usLen )
{
U8_T ucCRCHi = 0xFF;
U8_T ucCRCLo = 0xFF;
int iIndex;
while( usLen-- )
{
iIndex = ucCRCLo ^ *( pucFrame++ );
ucCRCLo = ( U8_T )( ucCRCHi ^ aucCRCHi[iIndex] );
ucCRCHi = aucCRCLo[iIndex];
}
return ( U16_T )( ucCRCHi << 8 | ucCRCLo );
}
U8_T u8_calculate_bcc(U8_T *pu8_data, U16_T u16_len) //BCC异或校验
{
U32_T i;
U8_T u8_ret = 0;
for (i=0; i<u16_len; i++)
u8_ret ^= *pu8_data++;
return u8_ret;
}
#endif
#if 1 //时间戳、时间数据计算函数
/**
* @brief 获取系统运行总毫秒数(从启动开始)
* @return uint64_t 当前毫秒数(自动处理32位tick溢出)
*/
uint64_t u64_get_current_millis(void) {
static uint32_t overflow_count = 0;
static TickType_t last_tick = 0;
// 进入临界区保护静态变量
taskENTER_CRITICAL();
TickType_t current_tick = xTaskGetTickCount();
// 检测tick计数器溢出(0xFFFFFFFF → 0
if (current_tick < last_tick) {
overflow_count++;
}
last_tick = current_tick;
taskEXIT_CRITICAL();
// 计算总毫秒数 = (溢出次数 * 周期毫秒) + 当前tick转换的毫秒
const uint64_t period_ms = ((uint64_t)0xFFFFFFFF * 1000) / configTICK_RATE_HZ;
uint64_t current_ms = (uint64_t)current_tick * 1000 / configTICK_RATE_HZ;
return (overflow_count * period_ms) + current_ms;
}
/**
* @brief 计算当前时间与上次时间的毫秒数差值(自动处理64位溢出)
* @param last_millis 上次记录的时间戳(毫秒)
* @return uint64_t 距离上次时间的毫秒数差值(总是正数)
*/
uint64_t u64_safe_millis_since(uint64_t last_millis) {
uint64_t current_millis = u64_get_current_millis();
// 处理毫秒计数器自增特性(时间不会回退)
if (current_millis >= last_millis) {
return current_millis - last_millis;
} else {
// 发生错误时返回0(如传入未来时间或时间重置)
return 0;
}
}
/**
* @brief 获取系统运行总秒数(从启动开始)
* @return uint32_t 当前秒数(自动处理32位tick溢出)
*/
uint32_t get_current_seconds(void) {
return (uint32_t)(u64_get_current_millis() / 1000);
}
/**
* @brief 计算当前时间与上次时间的秒数差值(无符号,自动处理溢出)
* @param last_sec 上次记录的时间戳(秒)
* @return uint32_t 距离上次时间的秒数差值(总是正数)
*/
uint32_t u32_safe_seconds_since(uint32_t last_sec) {
// 获取当前秒数(基于系统tick,含溢出处理)
uint32_t current_sec = get_current_seconds(); // 使用前文定义的get_current_seconds()
// 计算差值(自动处理32位溢出)
return (current_sec >= last_sec) ? (current_sec - last_sec) :
(0xFFFFFFFF - last_sec + current_sec + 1);
}
#endif
#if 1 //数据进制转换函数-BCD转换
// 十进制转BCD
uint8_t dec_to_bcd(uint8_t dec) {
return ((dec / 10) << 4) | (dec % 10);
}
// BCD转十进制
uint8_t bcd_to_dec(uint8_t bcd) {
return ((bcd >> 4) * 10) + (bcd & 0x0F);
}
/**
* @brief 将BCD码转换为ASCII字符串
* @param bcd_data BCD码数据数组
* @param bcd_len BCD数据长度(字节数)
* @param ascii_str 输出ASCII字符串缓冲区
* @param ascii_buf_len 输出缓冲区大小 要大于bcd_len*2+1
* @return 成功返回0,失败返回-1
*/
int bcd_to_ascii(const U8_T *bcd_data, U8_T bcd_len,
char *ascii_str, U8_T ascii_buf_len)
{
if (bcd_data == NULL || ascii_str == NULL) {
return -1;
}
// 确保缓冲区足够大(每个BCD字节可以转换为2个ASCII字符)
if (ascii_buf_len < bcd_len * 2 + 1) {
return -1;
}
int i, j = 0;
for (i = 0; i < bcd_len; i++) {
// 提取高4位和低4位BCD码
U8_T high_nibble = (bcd_data[i] >> 4) & 0x0F;
U8_T low_nibble = bcd_data[i] & 0x0F;
// 转换为ASCII字符
if (high_nibble < 10) {
ascii_str[j++] = high_nibble + '0'; // 数字0-9
} else if (high_nibble == 0x0A) {
ascii_str[j++] = 'A'; // 可选的十六进制表示
} else if (high_nibble == 0x0B) {
ascii_str[j++] = 'B';
} else if (high_nibble == 0x0C) {
ascii_str[j++] = 'C';
} else if (high_nibble == 0x0D) {
ascii_str[j++] = 'D';
} else if (high_nibble == 0x0E) {
ascii_str[j++] = 'E';
} else if (high_nibble == 0x0F) {
ascii_str[j++] = 'F';
}
if (low_nibble < 10) {
ascii_str[j++] = low_nibble + '0';
} else if (low_nibble == 0x0A) {
ascii_str[j++] = 'A';
} else if (low_nibble == 0x0B) {
ascii_str[j++] = 'B';
} else if (low_nibble == 0x0C) {
ascii_str[j++] = 'C';
} else if (low_nibble == 0x0D) {
ascii_str[j++] = 'D';
} else if (low_nibble == 0x0E) {
ascii_str[j++] = 'E';
} else if (low_nibble == 0x0F) {
ascii_str[j++] = 'F';
}
}
ascii_str[j] = '\0'; // 字符串结束符
return 0;
}
#endif
#if 1 //系统重启
void v_sys_reboot()
{
printf("sys reboot\r\n");
mSleep(2000);
//重启
__set_FAULTMASK(1); //关闭所有中断
NVIC_SystemReset(); //复位函数
}
#endif
#if 1 //Base64编码解码函数
/**
* @brief BASE64编码函数
* @param input 二进制数据输入
* @param input_len 输入数据长度
* @param output 输出缓冲区(Base64字符串)
* @param output_size 输出缓冲区大小
* @return 编码后的字符串长度,-1表示错误
*/
int base64_encode(const uint8_t *input, uint32_t input_len,
char *output, uint32_t output_size)
{
static const char base64_table[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
if (input == NULL || output == NULL || output_size == 0) {
return -1;
}
uint32_t i = 0, j = 0;
uint32_t output_len = ((input_len + 2) / 3) * 4; /* Base64编码后的长度 */
if (output_len + 1 > output_size) {
return -1;
}
while (i < input_len) {
uint32_t octet_a = i < input_len ? input[i++] : 0;
uint32_t octet_b = i < input_len ? input[i++] : 0;
uint32_t octet_c = i < input_len ? input[i++] : 0;
uint32_t triple = (octet_a << 16) | (octet_b << 8) | octet_c;
output[j++] = base64_table[(triple >> 18) & 0x3F];
output[j++] = base64_table[(triple >> 12) & 0x3F];
output[j++] = base64_table[(triple >> 6) & 0x3F];
output[j++] = base64_table[triple & 0x3F];
}
/* 添加填充字符 */
if (input_len % 3 == 1) {
output[j - 2] = '=';
output[j - 1] = '=';
} else if (input_len % 3 == 2) {
output[j - 1] = '=';
}
output[j] = '\0';
return j;
}
/**
* @brief BASE64解码函数
* @param input Base64编码字符串输入
* @param output 输出缓冲区(二进制数据)
* @param output_size 输出缓冲区大小
* @return 解码后的数据长度,-1表示错误
*/
int base64_decode(const char *input, uint8_t *output, uint32_t output_size)
{
static const int8_t base64_reverse_table[] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1
};
if (input == NULL || output == NULL || output_size == 0) {
return -1;
}
uint32_t input_len = strlen(input);
uint32_t i = 0, j = 0;
uint32_t output_len = (input_len * 3) / 4; /* 最大可能的输出长度 */
if (output_len > output_size) {
return -1;
}
/* 跳过末尾的填充字符 */
while (input_len > 0 && input[input_len - 1] == '=') {
input_len--;
}
/* 解码过程 */
while (i < input_len) {
int8_t sextet_a = (i < input_len) ? base64_reverse_table[(uint8_t)input[i++]] : -1;
int8_t sextet_b = (i < input_len) ? base64_reverse_table[(uint8_t)input[i++]] : -1;
int8_t sextet_c = (i < input_len) ? base64_reverse_table[(uint8_t)input[i++]] : -1;
int8_t sextet_d = (i < input_len) ? base64_reverse_table[(uint8_t)input[i++]] : -1;
if (sextet_a == -1 || sextet_b == -1) {
return -1; /* 无效的Base64字符 */
}
uint32_t triple = (sextet_a << 18) | (sextet_b << 12);
if (sextet_c != -1) {
triple |= sextet_c << 6;
}
if (sextet_d != -1) {
triple |= sextet_d;
}
output[j++] = (triple >> 16) & 0xFF;
if (sextet_c != -1) {
output[j++] = (triple >> 8) & 0xFF;
}
if (sextet_d != -1) {
output[j++] = triple & 0xFF;
}
}
return j;
}
#endif /* Base64编码解码函数 */