#include
#include
#include
#include
#include
#include
// 系统配置
#define NUM_LEDS 8
#define SCALE_FACTOR 1000
#define HYSTERESIS_THRESHOLD 1000
#define MAX_INPUT_LENGTH 256
// LED阈值定义
#define UP_THRESHOLD_0 50250 // 50.25
#define UP_THRESHOLD_1 60000 // 60.0
#define UP_THRESHOLD_2 72000 // 72.0
#define UP_THRESHOLD_3 83250 // 83.25
#define UP_THRESHOLD_4 107250 // 107.25
#define UP_THRESHOLD_5 115500 // 115.5
#define UP_THRESHOLD_6 120000 // 120.0
#define UP_THRESHOLD_7 126000 // 126.0
#define UP_THRESHOLD_8 130500 // 130.5
#define DOWN_THRESHOLD_1 48000 // 48.0
#define DOWN_THRESHOLD_2 57750 // 57.75
#define DOWN_THRESHOLD_3 69750 // 69.75
#define DOWN_THRESHOLD_4 81000 // 81.0
#define DOWN_THRESHOLD_5 102750 // 102.75
#define DOWN_THRESHOLD_6 113250 // 113.25
#define DOWN_THRESHOLD_7 117750 // 117.75
#define DOWN_THRESHOLD_8 126000 // 126.0
// 方向枚举
typedef enum {
DIRECTION_UP,
DIRECTION_DOWN
} Direction;
// 滞回控制状态
typedef struct {
int last_value;
Direction last_direction;
} HysteresisState;
// 输入转换函数
int transform_input(uint8_t input_value) {
return (int)input_value * 750 - 48000; // (input × 0.75 - 48) × 1000
}
// LED数量判断函数
uint8_t determine_led_count(int transformed_value, Direction direction) {
uint8_t led_count = 0;
if (direction == DIRECTION_UP) { if (transformed_value < UP_THRESHOLD_0) { led_count = 0; } else if (transformed_value < UP_THRESHOLD_1) { led_count = 1; } else if (transformed_value < UP_THRESHOLD_2) { led_count = 2; } else if (transformed_value < UP_THRESHOLD_3) { led_count = 3; } else if (transformed_value < UP_THRESHOLD_4) { led_count = 4; } else if (transformed_value < UP_THRESHOLD_5) { led_count = 5; } else if (transformed_value < UP_THRESHOLD_6) { led_count = 6; } else if (transformed_value <= UP_THRESHOLD_7) { led_count = 7; } else if (transformed_value <= UP_THRESHOLD_8) { led_count = 8; } } else { // DIRECTION_DOWN if (transformed_value >= DOWN_THRESHOLD_8) { led_count = 8; } else if (transformed_value > DOWN_THRESHOLD_7) { led_count = 7; } else if (transformed_value > DOWN_THRESHOLD_6) { led_count = 6; } else if (transformed_value > DOWN_THRESHOLD_5) { led_count = 5; } else if (transformed_value > DOWN_THRESHOLD_4) { led_count = 4; } else if (transformed_value > DOWN_THRESHOLD_3) { led_count = 3; } else if (transformed_value > DOWN_THRESHOLD_2) { led_count = 2; } else if (transformed_value > DOWN_THRESHOLD_1) { led_count = 1; } } return led_count;
}
// 生成LED状态
uint8_t generate_led_states(uint8_t led_count) {
if (led_count >= NUM_LEDS) {
return 0xFF; // 所有LED亮
}
if (led_count > 0) {
return (1 << led_count) - 1; // 低位led_count个LED亮
}
return 0; // 所有LED灭
}
// 滞回方向判断
Direction determine_direction(int transformed_value, const HysteresisState* state) {
int value_difference = transformed_value - state->last_value;
if (abs(value_difference) < HYSTERESIS_THRESHOLD) { return state->last_direction; } return (value_difference >= 0) ? DIRECTION_UP : DIRECTION_DOWN;
}
// 主处理函数
void process_input(HysteresisState* state, uint8_t input_value) {
int transformed_value = transform_input(input_value);
Direction current_direction = determine_direction(transformed_value, state);
uint8_t led_count = determine_led_count(transformed_value, current_direction);
uint8_t led_states = generate_led_states(led_count);
// 更新状态 state->last_value = transformed_value; state->last_direction = current_direction; // 拆分整数和小数部分 int integer_part = transformed_value / SCALE_FACTOR; int fractional_part = abs(transformed_value) % SCALE_FACTOR; char sign_char = (transformed_value < 0) ? ‘-’ : ’ '; const char* direction_str = (current_direction == DIRECTION_UP) ? “上行” : “下行”; // 输出结果 printf(“LED状态: “); for (int i = 0; i < NUM_LEDS; i++) { putchar(led_states & (1 << i) ? ‘#’ : ‘-’); } printf(” (0x%02X)\n”, led_states); printf(“输入: %3u → 转换: %c%d.%03d (%s) → LED数: %u\n\n”, input_value, sign_char, abs(integer_part), fractional_part, direction_str, led_count);
}
// 解析命令行参数
void parse_command_line_args(int argc, char* argv[], uint8_t** values, size_t* count) {
*count = argc - 1;
*values = malloc(*count * sizeof(uint8_t));
if (values == NULL) { fprintf(stderr, “内存分配失败\n”); exit(EXIT_FAILURE); } for (int i = 1; i < argc; i++) { char endptr; long val = strtol(argv[i], &endptr, 10); if (*endptr != ‘\0’ || val < 0 || val > 255) { fprintf(stderr, “错误: 无效输入 ‘%s’ - 请输入0-255之间的整数\n”, argv[i]); free(*values); exit(EXIT_FAILURE); } (*values)[i - 1] = (uint8_t)val; }
}
// 从用户输入获取一组值
int get_input_values(uint8_t** values, size_t* count) {
printf("请输入测试值 (0-255之间,空格分隔,回车结束): ");
fflush(stdout); // 确保提示信息显示
char input_line[MAX_INPUT_LENGTH]; if (fgets(input_line, sizeof(input_line), stdin) == NULL) { return -1; // 读取失败或EOF } // 检查空行 if (strlen(input_line) == 1 && input_line[0] == ‘\n’) { return 0; // 空行 } // 临时存储解析的值 uint8_t temp_values[100]; count = 0; char token = strtok(input_line, " \t\n"); while (token != NULL && count < sizeof(temp_values)/sizeof(temp_values[0])) { // 验证是否为数字 char ptr = token; while (*ptr) { if (!isdigit((unsigned char)*ptr)) { printf(“错误: 无效字符 ‘%c’ 在输入 ‘%s’ 中\n”, *ptr, token); return 2; // 输入格式错误 } ptr++; } int val = atoi(token); if (val < 0 || val > 255) { printf(“错误: 值 %d 超出范围 (0-255)\n”, val); return 3; // 数值超出范围 } temp_values[(*count)++] = (uint8_t)val; token = strtok(NULL, " \t\n"); } if (*count == 0) { return 0; // 没有有效输入 } // 分配精确大小的内存 *values = malloc(*count * sizeof(uint8_t)); if (*values == NULL) { fprintf(stderr, “内存分配失败\n”); return -1; } memcpy(*values, temp_values, *count * sizeof(uint8_t)); return 1; // 成功
}
// 询问用户是否继续
bool ask_continue() {
printf("是否继续输入?(y/n): ");
fflush(stdout);
char response[10]; if (fgets(response, sizeof(response), stdin) == NULL) { return false; // 读取失败 } // 去除换行符 response[strcspn(response, “\n”)] = ‘\0’; return (strcmp(response, “y”) == 0 || strcmp(response, “Y”) == 0);
}
// 处理用户输入值
void process_user_inputs(HysteresisState* state) {
while (true) {
uint8_t* input_values = NULL;
size_t value_count = 0;
int result = get_input_values(&input_values, &value_count); if (result == -1) { break; // 读取失败或EOF } else if (result == 0) { printf(“输入为空,”); if (!ask_continue()) break; continue; } else if (result > 1) { // 输入错误 printf(“请重新输入\n”); continue; } // 处理所有输入 for (size_t i = 0; i < value_count; i++) { printf(“— 输入序列 %zu: 输入值=%u —\n”, i + 1, input_values[i]); process_input(state, input_values[i]); } // 释放内存 free(input_values); // 询问是否继续 if (!ask_continue()) { break; } }
}
int main(int argc, char* argv[]) {
// 初始化状态
HysteresisState state = {0, DIRECTION_UP};
if (argc > 1) { // 命令行参数模式 uint8_t* input_values = NULL; size_t value_count = 0; parse_command_line_args(argc, argv, &input_values, &value_count); printf(“=== 命令行输入模式 =\n"); for (size_t i = 0; i < value_count; i++) { printf(“— 测试 %zu: 输入=%u —\n”, i + 1, input_values[i]); process_input(&state, input_values[i]); } free(input_values); // 命令行模式后允许继续交互 printf(“\n= 命令行输入完成 =\n”); if (ask_continue()) { printf(“\n= 交互输入模式 =\n”); process_user_inputs(&state); } } else { // 交互式输入模式 printf("= 交互输入模式 ===\n”); process_user_inputs(&state); } printf(“\n程序结束\n”); return 0;
}
我觉得SCALE_FACTOR可以缩小到100,那些宏的定义也可以少一个0,也不用用u32了
进行编码规范:
1、标准变量类型
禁止使用C语言的标准变量类型。
请使用共通头文件“aip_common.h”中定义了标准类型,如下:
#ifndef AIP_COMMON_H
#define AIP_COMMON_H
typedef unsigned char U1;
typedef unsigned short U2;
typedef unsigned int U4;
typedef long unsigned int U8;
typedef signed char S1;
typedef signed short S2;
typedef signed long S4;
typedef signed long long S8;
typedef U1* U1P;
typedef U2* U2P;
typedef U4* U4P;
typedef U8* U8P;
typedef S1* S1P;
typedef S2* S2P;
typedef S4* S4P;
typedef S8* S8P;
typedef void* VDP;
#define U1_MAX 0xFFU
#define U1_MIN 0x00U
#define S1_MAX 0x7F
#define S1_MIN 0x80
#define U2_MAX 0xFFFFU
#define U2_MIN 0x0000U
#define S2_MAX 0x7FFF
#define S2_MIN 0x8000
#define U4_MAX 0xFFFFFFFFUL
#define U4_MIN 0x00000000UL
#define S4_MAX 0x7FFFFFFFL
#define S4_MIN 0x80000000L
#define U8_MAX 0xFFFFFFFFFFFFFFFFULL
#define U8_MIN 0x0000000000000000ULL
#define S8_MAX 0x7FFFFFFFFFFFFFFFLL
#define S8_MIN 0x8000000000000000LL
#define TRUE 1
#define FALSE 0
#define ST struct
#define EN enum
#endif /* AIP_COMMON_H */
2、变量:
Format type [dt][s][a][module][variable];
Length of Identifier 最多32个字符
[dt]变量类型 标准类型 u1, u2, u4, u8, s1, s2, s4, s8
结构体类型 st
枚举类型 en
共用体类型 MISRA-C中禁止使用
函数指针类型 fp
变量指针类型 u1p, u2p, u4p, s1p, s2p, s4p, s8p, stp
空指针类型 vdp
[s]作用域 ※ 函数域内的自动变量 t
函数阈内的参数变量 a
文件阈内的static变量 s
文件域内外的extern变量 g
[a]数组 ※ 维数=0 无修饰字符
维数=1 p
维数=n p[n]
[module]模块名
[variable]变量名 有const修饰 只能使用大写字母
无const修饰 只能使用小写字母
3、函数
Format type [dt][s]_[module]function;
Length of Identifier 最多32个字节
[dt]返回值类型 标准类型 u1, u2, u4, u8, s1, s2, s4, s8
结构体类型 st
枚举类型 en
共用体类型 MISRA-C中禁止使用
变量指针类型 u1p, u2p, u4p, s1p, s2p, s4p, s8p, stp
空指针类型 vdp
[s]作用域 static函数仅在文件内 s
extern函数在文件内外 g
[module]模块名
[function]函数名 大小写字母均可使用
[parameter]形参名 3.3. 命名规则:遵从定义变量的命名格式
※:函数原型声明时,必须定义形参。
※函数内不会修改的参数,必须加上“const”修饰符。
4、注释必须是英文,不要使用“//”注释,不要跨行使用注释。在每一行,分别使用“/”和“/”来注释“/”后面和“/”的前面,插入空格
每个函数前面都要加注释,形如:
/=/
/* Function Name: v_g_SYMBOL_saveFile /
/ --------------------------------------------------------------------------------------------------------------------------------- /
/ Description: Saves user-defined symbol pairs to Symbol.txt file after validation /
/ Arguments: const U2 *u2p_g_FILE_folder_path_p : Folder path /
/ const U2 u2p_a_SYMBOL_user_input : User input symbols /
/ Return: void /
/=/
5、{每个左大括号都要另起一行
6、所有判断语句,if while等只能是判断语句,不能嵌套函数
7、每个函数最多一个出口
8、返回值是一个变量,或者直接写一个值,不要写公式
9、结构体:
Format typedef struct{
[member]
…
}ST_[module]_[variable];
Length of Identifier 最多32个字符
[module]模块名
[variable]变量名
只能使用大写字母
[member] 成员名称需要按照3.3. 变量的规定。
禁止使用位域类型定义。
不过,Micro Controller Vendor提供的Micro-Controller的控制寄存器定义除外。
10、不要用常数,用魔法数字,如果是全是常数的公式,可以在宏里面定义
分模块,分别给出每个文件的具体代码