目录

一、代码总体规则

二、文件结构

1.文件头注释。

2.头文件包含顺序

3.头文件保护

 4. 内存 / 资源优化(嵌入式第一优先级)

三、命名规范

1.变量命名

2.函数命名

3.宏定义

4.结构体 / 数组名

五、常用缩写词

五、常用反义词


一、代码总体规则


1.清晰统一
  清晰性是易于维护、易于重构的程序必需具备的特征。代码首先是给人读的,好的代码应当可以像文章一样发声朗诵出来。

2.简洁为美
  简洁就是易于理解并且易于实现。代码越长越难以看懂,也就越容易在修改时引入错误。写的代码越多,意味着出错的地方越多,也就意味着代码的可靠性越低。因此,我们提倡大家通过编写简洁明了的代码来提升代码可靠性。

  废弃的代码(没有被调用的函数和全局变量)要及时清除,重复代码应该尽可能提炼成函数。

3.代码风格
  始终保持统一的代码编程风格,建议蛇形命名为主,硬件相关宏 / 寄存器用大写蛇形 + 模块前缀,全局变量加g_+ 模块前缀,静态变量加s_+ 模块前缀。

        按硬件模块拆分文件,代码注释必须关联硬件语义,所有配置固化为宏(便于移植)。

二、文件结构

1.文件头注释。
/**
 * @file    filename.c
 * @brief   文件功能描述
 * @author  作者
 * @date    创建日期
 * @version 版本号
 * @note    注意事项
 */
2.头文件包含顺序
// 1. 系统头文件
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 2. 第三方库头文件
#include <openssl/ssl.h>

// 3. 项目内部头文件
#include "my_header.h"
#include "utils.h"
3.头文件保护
#ifndef MY_HEADER_H
#define MY_HEADER_H

// 头文件内容

#endif /* MY_HEADER_H */
4. 内存 / 资源优化(嵌入式第一优先级)

变量类型优先用定长整型:不用int/long(长度随编译器变),改用uint8_t/uint16_t/uint32_tstdint.h),如uint8_t led_state;(节省内存)。

避免动态内存分配:禁用malloc/free(嵌入式内存碎片风险高),全部用静态数组 / 全局变量,如uint8_t uart_recv_buf[64]

静态函数 / 变量优先:对外接口用全局,内部逻辑加static,如static void adc_filter(void);(减少符号表,节省 Flash)

寄存器操作封装为宏 / 函数:禁止直接写寄存器(如GPIOA->ODR |= (1<<5)),封装为LED_ON()/LED_OFF(),便于移植和维护。

#define LED_ON()  GPIO_WriteBit(LED_GPIO_PORT, LED_GPIO_PIN, LED_ON_LEVEL)
#define LED_OFF() GPIO_WriteBit(LED_GPIO_PORT, LED_GPIO_PIN, !LED_ON_LEVEL)

中断函数极简主义:中断内只做 “最核心操作”(如读数据、置标志位),复杂逻辑丢到主循环 / 任务中,避免打断实时性。

void exti0_irq_handler(void) {
    if (EXTI_GetITStatus(EXTI_Line0) != RESET) {
        g_key_press_flag = 1; // 仅置标志位,不做复杂处理
        EXTI_ClearITPendingBit(EXTI_Line0); // 必须清中断标志
    }
}

主循环无阻塞:避免while(1)内的长延时,用 “状态机 + 定时器” 替代,如:

while (1) {
    if (g_timer10ms_flag) { // 10ms定时器中断置标志
        g_timer10ms_flag = 0;
        adc_sample(); // 10ms采样一次
    }
    if (g_timer100ms_flag) {
        g_timer100ms_flag = 0;
        led_flash(); // 100ms闪一次灯
    }
}

禁用浮点运算:MCU 浮点运算效率低,尽量用整型替代(如电压计算用mv而非vuint16_t voltage_mv = adc_val * 3300 / 4095;)。

三、命名规范

采用蛇形命名法。

  标识符的命名要清晰、明了,有明确含义,同时使用完整的单词或大家基本可以理解的缩写,避免使人产生误解。除了常见的通用缩写以外,不使用单词缩写,不得使用汉语拼音。

  尽可能给出描述性名称,不要节约空间,让别人很快理解你的代码更重要。

命名维度风格规则示例
函数名小写 + 下划线分隔,前缀体现功能 / 模块dp_download_beep_handle(DP 下发处理)、uart_transmit_output(串口输出)、all_data_update(数据上报)
1.变量命名

  一般形容词+名词形式(小写 + 下划线分隔,前缀体现业务含义)。

char adc_channels[12];
float adc_value;

/* 更多 */
dc_switch (DC 开关)
ac_fre_set(AC 频率设置)
send_len  (发送长度)

  用反义词组命名具有互斥意义的变量。

int now_mode;
int last_mode;

  局部变量:小写蛇形命名

int relay_num;
float adc_value;

  全局变量:小写蛇形命名, 添加一个g_前缀

int g_modbus_holding_regs_addr;
float g_current_value;

  常量: 大写蛇形命名

#define ADC_CHANNEL_NUM 12
const int DAC_CHANNEL_MAX_VALUE = 4095;
2.函数命名

  一般采用动词+名词形式 (小写 + 下划线分隔,前缀体现功能 / 模块)。

float get_current_value(int channel);
void set_current_value(int channel, float value);

/* dp_download_beep_handle(DP 下发处理)*/
static unsigned char dp_download_beep_handle(const unsigned char value[], unsigned short length)

/* uart_transmit_output(串口输出)*/
void uart_transmit_output(unsigned char value);

/* all_data_update(数据上报)*/
void all_data_update(void);

  反义词组命名具有相反动作的函数。

void open_relay(int relay_num);
void close_relay(int relay_num);
3.宏定义

  全大写 + 下划线分隔,前缀区分用途

#define DPID_BATTERY_PERCENTAGE 1   /*(DP 点 ID)*/
#define DP_TYPE_BOOL  0x01            /* (数据类型) */

#ifndef NULL
#define         NULL             ((void *) 0)
#endif

#ifndef SUCCESS
#define         SUCCESS          1
#endif

#ifndef ERROR
#define         ERROR            0
#endif

SUCCESS/ERROR(返回值)
4.结构体 / 数组名

  大驼峰(结构体)+ 小写下划线(数组)

DOWNLOAD_CMD_S(结构体)
download_cmd(数组)
weather_choose(数组)

/* 结构体变量 */
typedef struct {
  unsigned char dp_id;                              //dp序号
  unsigned char dp_type;                            //dp类型
} DOWNLOAD_CMD_S;

/* 结构体变量 */
const DOWNLOAD_CMD_S download_cmd[] =
{
  {DPID_BATTERY_PERCENTAGE, DP_TYPE_VALUE},
  {DPID_REMAIN_TIME, DP_TYPE_VALUE},
};

五、常用缩写词

原词缩写含义
additionadd
subtractionsub
multiplicationmul乘法
divisiondiv除法
answerans响应、回答
arrayarr数组、集合
averageavg平均
bufferbuf或buff缓冲区
capturecap或capt捕获
checkchk检查
countcnt计数器
columncol
controlctrl控制
decodedec解码、译码
definedef定义
deletedel删除
destinationdst或dest目的
displaydisp显示
encodeenc编码
environmentenv环境
errorerr错误
floatflt浮动、浮点
frequencyfreq频率
headerhdr开始、开头
indexidx索引、指示、
imageimg影像、镜像
incrementinc增加、增量
initalizeinit初始化
iterationitr循环、迭代
lengthlen长度
memorymem内存
middlemid中值
makemk制造、形成
messagemsg消息
numbernum数量、编号
operandopnd操作数
optimizationopt最优
operatorvoptr操作
packetpkt息包
positonpos位置
previouspre或prev以前的
pointerptr指针
recordrcd记录
receiverecv收到、接收
resultres结果
returnret返回
sourcesrc源头
stackstk
stringstr字符串
tabletab
temporarytmp或temp临时
totaltot全部的
time stampts时间戳
valueval

五、常用反义词

add / removebegin / end
create / destroyinsert / delete
first / lastget / release
increment / decrementput / get
add / deletelock / unlock
open / closemin / max
old / newstart / stop
next / previoussource / target
show / hidesend / receive
source / destinationcut / paste
up / downenable / disable
on / offsuccess / error

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐