简单了解EOF,static,#define

本文深入探讨了C语言中的关键概念,包括如何使用EOF判断输入结束、static关键字的多种用途以及预处理器指令#define的应用技巧。通过具体示例展示了这些概念的实际应用。
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>

////了解EOF!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//
//int main()
//{
//	int a = 0,b=0,c=0;
//	int ret = scanf("%d", &a);//输出后发现 ret=1,意思是它读到的有效数字个数为一个
//	int ret2 = scanf("%d%d", &b, &c);//类比↑
//	//如果在vs(其他编译器可能按一次就够了)里面按三次ctrl+z+回车(这里打了ret和ret2所以6次) 发现ret=-1
//	//而-1是谁?是EOF∴scanf读取失败的时候会返回EOF
//	//如果读取正常的话,返回的是读取到的数据的个数
//	printf("ret=%d\n", ret);
//	printf("ret2=%d\n", ret2);
//	printf("a=%d\n",a);
//	return 0;
//}
////而EOF到底有什么用呢?多组数的场景可能会用到



//了解关键字 static!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

//用法:①修饰局部变量
//      ②修饰全局变量
//      ③修饰函数


//①局部变量

////void test()
////{
////	int a = 0;
////	a++;
////	printf("%d ", a);
////}//这个程序如果执行起来在屏幕上会打印 十个1
//////局部变量a每次进test这个函数是创建,出这个函数时销毁
//////每次a都创建为0,然后++,为1
//////而你想要的是1 2 3 4 5 6 7 8 9 10
//
//void test()
//{
//	static int a = 0;
//	a++;
//	printf("%d ", a);
//}//这样打出来的就是1 2 3 4 5 6 7 8 9 10    上面void函数↑改进版
//
////   *所以在局部变量中 static的作用是延长局部变量的生命周期,它保留了上一次局部a的值
////局部变量是放在内存的栈区的,它进入作用域创建,出了作用域就释放
////局部变量被static修饰后就被放在内存的静态区了
////而放在静态区的数据创建后,直到程序结束才释放
////因为储存位置的差异,使得执行的效果不一样
////注:局部变量被static修饰是不影响作用域的
//
//int main()
//{
//	int i = 0;
//	while (i < 10)
//	{
//		test();
//		i++;
//	}
//	return 0;
//}


//②全局变量

//extern int g_val;
//extern int g_val1;
//int main()
//{
//	printf("%d\n", g_val);
//	printf("%d\n", g_val1);
//	return 0;
//}//在另一个源文件(2022.11.2'')定义的g_val=2022用extern在这里输出是没有问题的
////但用了static的g_val1就不行
////因为全局变量本身是具有外部链接属性的
////在A文件中定义的变量,在B问了中可以通过【链接】使用
////但是如果全局变量被static修饰,这个外部链接属性就改变了
////变成了内部链接属性
//当某个全局变量你想自己独吞的时候可以考虑static
////   *所以在全局变量中,static的作用是将全局变量的外部连接属性变成内部链接属性
////最终使得全局变量的作用域变小


//③修饰函数

////声明外部函数
//extern int Add(int x, int y);
//extern int Average(int x, int y);
////修饰函数
//int main()
//{
//	int a = 10;
//	int b = 20;
//	int c = Add(a, b);
//	int d = Average(a, b);
//	printf("%d\n", c);
//	printf("%d\n", d);
//	return 0;
//}//发现函数和全局变量是非常相似的
////同理,函数本身具有外部链接属性的
////被static修饰后,外部连接属性变成了内部链接属性
////使得这个函数只能在自己所在的源文件内部使用,其他源文件无法使用
////static限制了被修饰函数的作用域
//// 另外函数是没有生命周期的,这点和全局变量不一样
////想独吞此函数时可以考虑


//‘#define’ 的作用!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

//// 用来定义常量和宏
//
////定义常量
//
//
////#define M 100
////int main()
////{
////	int a = M;
////	printf("%d\n", M);
////	printf("%d\n", a);
////	return 0;
////}
//
//
//
////定义宏
//
//
////Max(int x, int y)
////{
////	return (x > y ? x : y);
////	//↑的意思是
////	//if(x>y)return x;
////	//else return y;
////}
////我们可以写出一个宏与上面的函数非常相似
//
//#define MAX(x,y) (x>y?x:y)//与函数的区别就是参数不需要给定类型,还有函数体的差异
////       名字 参数  宏体
////一般来说函数是用来处理比较复杂的内容
////宏一般用来处理比较简单的内容
//#define ADD(x,y) ((x)+(y))
//
//
//int main()
//{
//int a = 10;
//int b = 20;
////int m = Max(a, b);
//int n = MAX(a, b);//宏的作用就是这行代码会被替换为 int n=(a>b?a:b);宏体替换
//int k = ADD(a, b);
////printf("%d\n", m);
//printf("%d\n", n);
//printf("%d\n", k);
//return 0;
//}

/* ======================================== * * Copyright YOUR COMPANY, THE YEAR * All Rights Reserved * UNPUBLISHED, LICENSED SOFTWARE. * * CONFIDENTIAL AND PROPRIETARY INFORMATION * WHICH IS THE PROPERTY OF your company. * * ======================================== */ #ifndef __FP_SYNO_PROTOCOL_H__ #define __FP_SYNO_PROTOCOL_H__ #ifdef __cplusplus extern "C" { #endif #include <stdint.h> /* //1、删除未注册指纹,应答还是成功; //2、自学习功能默认一般为打开,配置的话可以参考最后的补充说明里面,针对不同软件版本有些区别; //3、注册和验证采集图像指令不同指令号; //4、是的,模组上电后,中断脚不要做为中断使用 */ #define FP_SYNO_WAIT_UP_TIME 6000 #define FP_SYNO_ENROLL_COUNTER ( 5 ) // 指纹录入次数 #define FP_SYNO_EMPTY_ACK_TIMEOUT (2000) #define FP_SYNO_COMMON_TIMEOUT (1000 ) // 通用的通信超时时间 unit: ms #define FP_SYNO_MATCH_TIMEOUT 2300 #define FP_SYNO_DEFAULT_BAUD ( 57600 )// 串口通信波特率 #define FP_SYNO_PWRON_WAIT_PERIOD ( 300 ) // 模组上电并采图应答等待时长 #define FP_SYNO_SLEEP_TIMEOUT (400 ) // 休眠指令超时时间 unit: ms #define FP_SYNO_CAPTURE_TIMEOUT (480 ) // 休眠指令超时时间 unit: ms #define FP_SYNO_RGBCTRL_TIMEOUT (780 ) // 休眠指令超时时间 unit: ms #define FP_SYNO_FIRST_HEAD ( 0xEF ) // 包头 0xEF01 #define FP_SYNO_SECOND_HEAD ( 0x01 ) // 包头 0xEF01 #define FP_SYNO_CMD_PKG ( 0x01 ) // 命令包 #define FP_SYNO_DATA_PKG ( 0x02 ) // 数据包 #define FP_SYNO_EOF_PKG ( 0x08 ) // 结束包 #define CALC_SUM_START_POS ( 6 ) #define CMD_CODE_START_POS ( 9 ) #define VARIABLE_FILED_START_POS ( 10 ) #define PS_OK 0x00 #define PS_COMM_ERR 0x01 #define PS_NO_FINGER 0x02 #define PS_GET_IMG_ERR 0x03 #define PS_FP_TOO_DRY 0x04 #define PS_FP_TOO_WET 0x05 #define PS_FP_DISORDER 0x06 #define PS_LITTLE_FEATURE 0x07 #define PS_NOT_MATCH 0x08 #define PS_NOT_SEARCHED 0x09 #define PS_MERGE_ERR 0x0a #define PS_ADDRESS_OVER 0x0b #define PS_READ_ERR 0x0c #define PS_UP_TEMP_ERR 0x0d #define PS_RECV_ERR 0x0e #define PS_UP_IMG_ERR 0x0f #define PS_DEL_TEMP_ERR 0x10 #define PS_CLEAR_TEMP_ERR 0x11 #define PS_SLEEP_ERR 0x12 #define PS_INVALID_PASSWORD 0x13 #define PS_RESET_ERR 0x14 #define PS_INVALID_IMAGE 0x15 #define PS_HANGOVER_UNREMOVE 0X17 #define PS_FLASH_ERR 0x18 #define PS_TRNG_ERR 0x19 #define PS_INVALID_REG 0x1a #define PS_REG_SET_ERR 0x1b #define PS_NOTEPAD_PAGE_ERR 0x1c #define PS_ENROLL_ERR 0x1e #define PS_LIB_FULL_ERR 0x1f #define PS_DEVICE_ADDR_ERR 0x20 #define PS_MUST_VERIFY_PWD 0x21 #define PS_TMPL_NOT_EMPTY 0x22//指纹模板非空 #define PS_TMPL_EMPTY 0x23//指纹模板为空 #define PS_LIB_EMPTY_ERR 0x24//指纹库为空 #define PS_TMPL_NUM_ERR 0x25//录入次数设置错误 #define PS_TIME_OUT 0x26//超时 #define PS_FP_DUPLICATION 0x27//指纹已存在 #define PS_TMP_RELATION 0x28//指纹模板有关联 #define PS_CHECK_SENSOR_ERR 0x29//传感器初始化失败 #define PS_MOD_INF_NOT_EMPTY 0x2a//模组信息非空 #define PS_MOD_INF_EMPTY 0x2b//模组信息空 #define PS_ENROLL_CANCEL 0x2C//取消注册 #define PS_IMAGE_SMALL 0x33//图像面积太小 #define PS_IMAGE_UNAVAILABLE 0x34//图像不可用 #define PS_ENROLL_TIMES_NOT_ENOUGH 0x40 //注册次数不够 #define PS_COMMUNICATE_TIMEOUT 0X41 //#define APP_ENROLL_FLAG 0X42 typedef enum { // 通用类指令 SYNO_CMD_MATCH_GETIMAGE = 0x01, // 验证用获取图像 SYNO_CMD_ENROLL_GETIMAGE = 0x29, // 注册用获取图像 SYNO_CMD_GEN_EXTRACT = 0x02, // 生成特征 SYNO_CMD_SEARCH_TEMPLETE = 0x04, // 搜索指纹 SYNO_CMD_GEN_TEMPLETE = 0x05, // 合并/生成模板 SYNO_CMD_STORE_TEMPLETE = 0x06, // 存储模板 SYNO_CMD_DEL_TEMPLETE = 0x0C, // 删除模板 SYNO_CMD_EMPTY_TEMPLETE = 0x0D, // 清空指纹库 SYNO_CMD_WRITE_SYSPARA = 0x0E, // 写系统寄存器 SYNO_CMD_READ_SYSPARA = 0x0F, // 读取模组基本参数 SYNO_CMD_READ_VALID_TEMPLETE_NUMS = 0x1D, // 读有效模板个数 SYNO_CMD_READ_TEMPLETE_INDEX_TABLE = 0x1F, // 读索引表 // 模块指令集 SYNO_CMD_AUTO_CANCEL = 0x30, SYNO_CMD_AUTO_ENROLL = 0x31, SYNO_CMD_AUTO_MATCH = 0x32, SYNO_CMD_INTO_SLEEP = 0x33, // 维护类指令 SYNO_CMD_HANDSHAKE = 0x35, SYNO_CMD_RGB_CTRL = 0x3C, SYNO_CMD_CHECK_FINGER = 0x9d, } FP_SYNO_CMD; typedef enum { FP_SYNO_RGB_BREATH=0X01, FP_SYNO_RGB_FLICK, FP_SYNO_RGB_OPEN, FP_SYNO_RGB_OFF, FP_SYNO_RGB_GRADUADL_OPEN, FP_SYNO_RGB_GRADUADL_OFF, FP_SYNO_RGB_HORSE, } ENUM_FP_SYNO_RGB_FUNC_CODE;//功能码 typedef enum { FP_SYNO_RGB_COLOR_OFF=0X00, FP_SYNO_RGB_COLOR_B, FP_SYNO_RGB_COLOR_G, FP_SYNO_RGB_COLOR_GB, FP_SYNO_RGB_COLOR_R, FP_SYNO_RGB_COLOR_RB, FP_SYNO_RGB_COLOR_RG, FP_SYNO_RGB_COLOR_RGB, FP_SYNO_RGB_COLOR_RGLOOP=0X16, FP_SYNO_RGB_COLOR_RBLOOP=0X15, FP_SYNO_RGB_COLOR_GBLOOP=0X13, FP_SYNO_RGB_COLOR_RGBLOOP=0X17, FP_SYNO_RGB_COLOR_RGALTINATE=0X26, FP_SYNO_RGB_COLOR_RBALTINATE=0X25, FP_SYNO_RGB_COLOR_GBALTINATE=0X23, } ENUM_FP_SYNO_RGB_COLOR;//起始颜色 typedef enum { FP_SYNO_RGB_DUTY_RLT_SUCC=0X91,//成功提示用9:1亮灯 FP_SYNO_RGB_DUTY_NORMAL=0X11,//正常提示用1:1亮灯 } ENUM_FP_SYNO_RGB_DUTY;//占空比 typedef enum { SYNO_ACK_SUCCESS = 0x00, // 指令执行ok SYNO_ACK_ERR_PKG_RCV = 0x01, // 数据包接收错误 SYNO_ACK_ERR_NO_FINGER = 0x02, // 传感器上无指纹 } FP_SYNO_ACK; typedef enum { FP_SYNO_RCV_FIRST_HEAD = 0x01, FP_SYNO_RCV_SECOND_HEAD, FP_SYNO_RCV_PKG_SIZE, FP_SYNO_RCV_DATAS, FP_SYNO_FRAME_CHECK, } ENUM_FP_SYNO_FRAME_RCV_FSM_STATE; #pragma pack(1) typedef struct { uint16_t header; uint32_t dev_addr; uint8_t pkg_identification; uint16_t data_size; uint8_t data[]; } fp_syno_pkg_list_t; #pragma pack() extern void fp_syno_cmd_rgb_ctrl(ENUM_FP_SYNO_RGB_FUNC_CODE func_code,ENUM_FP_SYNO_RGB_COLOR s_color,uint8_t e_color_duty,uint8_t loop_times,uint8_t cycle); void tysl_pdl_fp_uart_send(uint8_t *data, uint16_t size); //extern void fp_syno_reset_default_cmd(void); extern void fp_syno_long_press(void); extern void fp_syno_reset_protocol_parse(void); extern void fp_syno_protocol_parse(uint8_t *p_data, uint16_t len); extern void fp_syno_pkg_handle(uint8_t *data, uint16_t size); #ifdef __cplusplus } #endif #endif // __FP_SYNO_PROTOCOL_H__ /* [] END OF FILE */ 头文件补充
07-10
#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、不要用常数,用魔法数字,如果是全是常数的公式,可以在宏里面定义 分模块,分别给出每个文件的具体代码
09-03
#include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <stdbool.h> // 系统配置 #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、每个函数最多一个出口 分模块,分别给出每个文件的具体代码
09-03
#include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <stdbool.h> // 系统配置 #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]([parameter]….); 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、每个函数最多一个出口
09-03
以这个代码为模板,#include "Arduino.h" #include "WiFiMulti.h" #include "Audio.h" #include "SD_MMC.h" #include "FS.h" #include "es8311.h" #include "esp_check.h" #include "Wire.h" #define SD_MMC_CLK 11 #define SD_MMC_CMD 10 #define SD_MMC_D0 9 #define I2S_MCLK 44 #define I2S_DOUT 16 #define I2S_BCLK 13 #define I2S_LRC 15 #define I2C_SDA 8 #define I2C_SCL 7 #define EXAMPLE_SAMPLE_RATE (16000) #define EXAMPLE_MCLK_MULTIPLE (256) // If not using 24-bit data width, 256 should be enough #define EXAMPLE_MCLK_FREQ_HZ (EXAMPLE_SAMPLE_RATE * EXAMPLE_MCLK_MULTIPLE) #define EXAMPLE_VOICE_VOLUME (75) Audio audio; WiFiMulti wifiMulti; String ssid = ""; String password = ""; static esp_err_t es8311_codec_init(void) { es8311_handle_t es_handle = es8311_create(I2C_NUM_0, ES8311_ADDRRES_0); ESP_RETURN_ON_FALSE(es_handle, ESP_FAIL, TAG, "es8311 create failed"); const es8311_clock_config_t es_clk = { .mclk_inverted = false, .sclk_inverted = false, .mclk_from_mclk_pin = true, .mclk_frequency = EXAMPLE_MCLK_FREQ_HZ, .sample_frequency = EXAMPLE_SAMPLE_RATE }; ESP_ERROR_CHECK(es8311_init(es_handle, &es_clk, ES8311_RESOLUTION_16, ES8311_RESOLUTION_16)); // ESP_RETURN_ON_ERROR(es8311_sample_frequency_config(es_handle, EXAMPLE_SAMPLE_RATE * EXAMPLE_MCLK_MULTIPLE, EXAMPLE_SAMPLE_RATE), TAG, "set es8311 sample frequency failed"); ESP_RETURN_ON_ERROR(es8311_voice_volume_set(es_handle, EXAMPLE_VOICE_VOLUME, NULL), TAG, "set es8311 volume failed"); ESP_RETURN_ON_ERROR(es8311_microphone_config(es_handle, false), TAG, "set es8311 microphone failed"); return ESP_OK; } void setup() { Serial.begin(115200); Wire.begin(I2C_SDA, I2C_SCL); es8311_codec_init(); SD_MMC.setPins(SD_MMC_CLK, SD_MMC_CMD, SD_MMC_D0); if (!SD_MMC.begin("/sdmmc", true, false, 20000)) { esp_rom_printf("Card Mount Failed\n"); while (1) { }; } if (ssid != "" || password != ""){ WiFi.mode(WIFI_STA); wifiMulti.addAP(ssid.c_str(), password.c_str()); wifiMulti.run(); if (WiFi.status() != WL_CONNECTED) { WiFi.disconnect(true); wifiMulti.run(); } } audio.setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT, I2S_MCLK); audio.setVolume(21); // 0...21 audio.connecttoFS(SD_MMC, "music/1.mp3"); // audio.connecttohost("http://www.wdr.de/wdrlive/media/einslive.m3u"); // audio.connecttohost("http://somafm.com/wma128/missioncontrol.asx"); // asx // audio.connecttohost("http://mp3.ffh.de/radioffh/hqlivestream.aac"); // 128k aac // audio.connecttohost("http://mp3.ffh.de/radioffh/hqlivestream.mp3"); // 128k mp3 } void loop() { vTaskDelay(1); audio.loop(); if (Serial.available()) { // put streamURL in serial monitor audio.stopSong(); String r = Serial.readString(); r.trim(); if (r.length() > 5) audio.connecttohost(r.c_str()); log_i("free heap=%i", ESP.getFreeHeap()); } } // optional void audio_info(const char *info) { Serial.print("info "); Serial.println(info); } void audio_id3data(const char *info) { //id3 metadata Serial.print("id3data "); Serial.println(info); } void audio_eof_mp3(const char *info) { //end of file Serial.print("eof_mp3 "); Serial.println(info); } void audio_showstation(const char *info) { Serial.print("station "); Serial.println(info); } void audio_showstreamtitle(const char *info) { Serial.print("streamtitle "); Serial.println(info); } void audio_bitrate(const char *info) { Serial.print("bitrate "); Serial.println(info); } void audio_commercial(const char *info) { //duration in sec Serial.print("commercial "); Serial.println(info); } void audio_icyurl(const char *info) { //homepage Serial.print("icyurl "); Serial.println(info); } void audio_lasthost(const char *info) { //stream URL played Serial.print("lasthost "); Serial.println(info); }我要用vscode编译,platformio为辅助,在audio.cpp文件中写一个可以通过已经设置好的按键start,stop,previous和next点击控制sd卡中音乐的播放,请给我一个完整代码
08-06
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值