This repository has been archived on 2025-02-28. You can view files and clone it, but cannot push or open issues or pull requests.
controller-hd/User/lib/src/lib.c

364 lines
7.9 KiB
C

/*
* @Author:
* @day: 2023-04-11 08:21:19
* @LastEditors: xxx
* @LastEditTime: 2023-08-15 10:14:58
* @Description:
* email:
* Copyright (c) 2023 by xxx, All Rights Reserved.
*/
#include "../inc/lib.h"
#include <stdio.h>
#include <string.h>
const uint8_t _days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const uint16_t _month_days[12] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
/**
* @brief 版本号1.0拆解成1和0
* @param {uint8_t} *version_str
* @param {uint8_t} *hi
* @param {uint8_t} *lo
* @return {*}
*/
void version_split(uint8_t *version_str, uint8_t *hi, uint8_t *lo)
{
uint8_t flag = 1;
for (uint8_t i = 0; version_str[i] != '\0'; i++)
{
if (version_str[i] == '.')
{
flag = 0;
continue;
}
if (flag)
{
*hi = *hi * 10 + (version_str[i] - '0');
}
else
{
*lo = *lo * 10 + (version_str[i] - '0');
}
}
}
// 反序数组
void reverse(uint8_t *buf, uint16_t len)
{
uint8_t tmp;
uint16_t i;
for (i = 0; i < len / 2; i++)
{
tmp = buf[i];
buf[i] = buf[len - i - 1];
buf[len - i - 1] = tmp;
}
}
/***
* @brief 判断是否在数组中
* @param {uint8_t} *arr 数组
* @param {uint8_t} len 数组长度
* @param {uint8_t} val 要判断的值
* @return {*} TRUE: 在数组中
*/
BOOL is_in_array(uint16_t *arr, uint16_t len, uint16_t val)
{
uint16_t i;
for (i = 0; i < len; i++)
{
if (arr[i] == val)
{
return TRUE;
}
}
return FALSE;
}
/**
* 计算并返回指定数据区域crc的值
*
* @param uc_ptr: 待计算的数据区首地址
* @param uc_len: 待计算的数据区长度
*
* @return crc计算的结果
*/
uint16_t crc16_compute(const uint8_t *const uc_ptr, uint16_t uc_len)
{
uint16_t crcVal = 0xffff;
const uint8_t *ptr = uc_ptr;
for (uint16_t i = 0; i < uc_len; i++)
{
crcVal = crcVal ^ (0x00ff & (unsigned short)*ptr);
ptr++;
for (uint8_t j = 0; j < 8; j++)
{
if ((crcVal & 0x0001) == 1)
{
crcVal = (crcVal >> 1) ^ 0x8401;
}
else
{
crcVal = crcVal >> 1;
}
}
}
return crcVal;
}
/**
* 计算并返回指定数据区域异或的值
*
* @param uc_ptr: 待计算的数据区首地址
* @param uc_len: 待计算的数据区长度
*
* @return 异或计算的结果
*/
uint8_t xor_compute(const uint8_t *const uc_ptr, uint16_t uc_len)
{
uint16_t i;
const uint8_t *ptr = uc_ptr;
uint8_t xor = 0;
for (i = 0; i < uc_len; i++)
{
xor ^= *ptr;
ptr++;
}
return xor;
}
// 通过bit位获取置1个数量
uint8_t get_bit_num(uint8_t bit)
{
uint8_t num = 0;
while (bit)
{
if (bit & 0x01)
{
num++;
}
bit >>= 1;
}
return num;
}
// 通过bit位获取置1的位置
BOOL is_bit_set(int x, int k)
{
int mask = 1 << k;
return (x & mask) != 0;
}
// 判断数组是否全是同一个值
BOOL is_same_value(uint8_t *buf, uint16_t len, uint8_t value)
{
uint16_t i;
for (i = 0; i < len; i++)
{
if (buf[i] != value)
{
return FALSE;
}
}
return TRUE;
}
// 检查是否是闰年
uint8_t isLeap(uint16_t year)
{
return (year % 400 == 0) || (year % 100 != 0 && year % 4 == 0);
}
// 计算一年中的第几天
uint16_t dayOfyear(uint16_t year, uint8_t month, uint8_t day)
{
uint8_t month_days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
uint16_t total;
total = day;
if (month > 2 && isLeap(year))
total += 1;
for (uint8_t i = 0; i < month - 1; i++)
{
total += month_days[i];
}
return total;
}
// 计算一年中的第几周
uint16_t weekOfyear(uint16_t year, uint8_t month, uint8_t day)
{
uint16_t day_of_year = dayOfyear(year, month, day);
return (day_of_year - 1) / 7 + 1;
}
// 获取今天星期几
uint8_t get_weekday(uint16_t year, uint8_t month, uint8_t day)
{
uint8_t w = 0;
if (month == 1 || month == 2)
{
month += 12;
year--;
}
w = (day + 2 * month + 3 * (month + 1) / 5 + year + year / 4 - year / 100 + year / 400) % 7;
return w + 1;
}
// 传入十六进制0x23 返回十进制23
uint8_t hex_format_dec(uint8_t hex)
{
char buf[4];
osel_memset((uint8_t *)buf, 0, 4);
sprintf(buf, "%x", hex);
int dec = 0;
int weight = 1;
int len = strlen(buf);
for (int i = len - 1; i >= 0; i--)
{
if (buf[i] >= '0' && buf[i] <= '9')
{
dec += (buf[i] - '0') * weight;
}
else if (buf[i] >= 'A' && buf[i] <= 'F')
{
dec += (buf[i] - 'A' + 10) * weight;
}
else if (buf[i] >= 'a' && buf[i] <= 'f')
{
dec += (buf[i] - 'a' + 10) * weight;
}
weight *= 10;
}
return dec;
}
// 传入十进制23 返回十六进制0x23
uint8_t dec_format_hex(uint8_t dec)
{
char buf[4];
osel_memset((uint8_t *)buf, 0, 4);
sprintf(buf, "%d", dec);
uint8_t hex = 0;
uint8_t len = strlen(buf);
for (uint8_t i = 0; i < len; i++)
{
char c = buf[i];
if (c >= '0' && c <= '9')
{
hex = hex * 16 + (c - '0');
}
else
{
continue;
}
}
return hex;
}
/**
* @brief 北京时间转时间戳
* @param {rtc_date_t} date
* @param {rtc_time_t} time
* @return {*}
* @note
*/
uint32_t time2Stamp(rtc_date_t date, rtc_time_t time)
{
uint32_t result;
uint16_t year = date.year + 2000;
result = (year - 1970) * 365 * 24 * 3600 + (_month_days[date.month - 1] + date.day - 1) * 24 * 3600 + (time.hour - 8) * 3600 + time.minute * 60 + time.second;
result += (date.month > 2 && (year % 4 == 0) && (year % 100 != 0 || year % 400 == 0)) * 24 * 3600; // 闰月
year -= 1969;
result += (year / 4 - year / 100 + year / 400) * 24 * 3600; // 闰年
return result;
}
/**
* @brief 时间戳转北京时间
* @param {uint32_t} stamp
* @param {rtc_date_t} *date
* @param {rtc_time_t} *time
* @return {*}
* @note
*/
void stamp2Time(uint32_t stamp, rtc_date_t *date, rtc_time_t *time)
{
uint32_t days;
uint16_t leap_num;
time->second = stamp % 60;
stamp /= 60; // 获取分
time->minute = stamp % 60;
stamp += 8 * 60;
stamp /= 60; // 获取小时
time->hour = stamp % 24;
days = stamp / 24;
leap_num = (days + 365) / 1461;
if (((days + 366) % 1461) == 0)
{
date->year = (days / 366) + 1970 - 2000;
date->month = 12;
date->day = 31;
}
else
{
days -= leap_num;
date->year = (days / 365) + 1970 - 2000;
days %= 365;
days += 1;
if (((date->year % 4) == 0) && (days == 60))
{
date->month = 2;
date->day = 29;
}
else
{
if (((date->year % 4) == 0) && (days > 60))
--days;
for (date->month = 0; _days[date->month] < days; date->month++)
{
days -= _days[date->month];
}
++date->month;
date->day = days;
}
}
}
/**************************排序**************************/
static void swap(uint16_t *a, uint16_t *b)
{
uint16_t t = *a;
*a = *b;
*b = t;
}
static int partition(uint16_t arr[], int low, int high)
{
uint16_t pivot = arr[high];
int i = (low - 1);
for (int j = low; j <= high - 1; j++)
{
if (arr[j] < pivot)
{
i++;
swap(&arr[i], &arr[j]);
}
}
swap(&arr[i + 1], &arr[high]);
return (i + 1);
}
void quicksort(uint16_t arr[], int low, int high)
{
if (low < high)
{
int pi = partition(arr, low, high);
quicksort(arr, low, pi - 1);
quicksort(arr, pi + 1, high);
}
}