【58】编程技巧:单片机编程命名规范
【58】编程技巧:单片机编程命名规范
引言
在大型嵌入式项目开发中,变量和常量的命名混乱会导致代码难以维护。本文系统阐述变量、常量、指针、结构体等命名规范,通过统一规则提升代码可读性与协作效率。目标是帮助开发者建立清晰的命名习惯,降低项目复杂度。
本文详细讲解全局/局部变量、静态变量、常量、循环变量、数组、指针、结构体及宏常量的命名规则,通过代码示例与场景说明,展示如何通过规范命名提升代码质量。内容涵盖命名规则、代码结构及调试方法,适用于单片机与嵌入式系统开发。
关键词 :命名规范、变量命名、常量命名、指针命名、结构体命名、宏常量
硬件设计
电路原理
以STC8单片机为例,硬件设计需包含以下模块:
- UART通信模块:用于输出调试信息(如成绩分级结果)。
- GPIO端口:用于LED或按键输入(如P1口)。
寄存器配置
// UART0初始化配置
void UART0_Init() { SCON = 0x50; // 8位数据,1位停止位,可变波特率 TMOD |= 0x20; // 定时器1工作模式2(自动重装) TH1 = 0xFD; // 波特率115200计算值 TL1 = 0xFD; TR1 = 1; // 启动定时器1 ES = 1; // 使能UART中断 EA = 1; // 全局中断使能
}
文件结构
Project/
├── Drivers/ // 驱动层代码
│ ├── BSP/ // 硬件抽象层(如BSP_UART.c)
│ └── Module/ // 功能模块(如DRV_GRADE.c)
├── User/ // 应用层代码(main.c)
├── Core/ // 芯片核心配置(如sys.h)
├── Projects/ // IDE工程文件(如Keil的.uvproj)
├── Docs/ // 文档与示例说明
└── Inc/ // 公共头文件(如common.h)
代码实现
变量命名规范
全局变量与局部变量
// 全局变量
unsigned char Gu8Score; // 全局8位变量,存储学生成绩
static unsigned int ESu16Count; // 全局静态16位变量,计数器 // 局部变量
void ProcessData() { unsigned char u8Temp; // 局部8位变量,临时存储数据 static unsigned long Su32Time; // 局部静态32位变量,记录累计时间
}
静态变量命名
// 全局静态变量
static unsigned char ESu8Flag = 0; // 标志位,仅在文件内可见 // 局部静态变量
void TimerCallback() { static unsigned int Su16TickCount = 0; // 计数器,跨调用保持状态
}
常量命名
// 全局常量
const unsigned char Cu8MaxScore = 100; // 学生最高分 // 局部常量
void CalculateThreshold() { const unsigned int Cu16Threshold = 50; // 阈值,仅在函数内使用
}
循环变量命名
void LoopExample() { // 单字母循环变量,i,j,k用于简单循环 for (unsigned char i = 0; i < 5; i++) { // 处理逻辑 } // 多层循环时,使用j,k区分 for (unsigned char i = 0; i < 5; i++) { for (unsigned char j = 0; j < 3; j++) { // 处理二维数据 } } // 复杂循环可结合语义命名 for (unsigned int k = 0; k < ARRAY_SIZE; k++) { // 处理数组元素 }
}
数组命名规范
普通数组与字符串
// 全局数组
unsigned char Gu8DataBuffer[10]; // 临时数据缓冲区
unsigned char Gu8Message[20]; // 存储消息字符串 // 局部数组
void ProcessString() { unsigned char u8String[20]; // 本地字符串处理
}
查找表与配置表
// 查找表(代码段存储)
code unsigned char Cu8LookupTable[] = { 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x00 // 共阴数码管字模表
}; // 配置表
const struct tConfig GuConfigTable[] = { {0x01, 100}, // 配置项1 {0x02, 200}, // 配置项2
};
指针命名规范
全局指针
// 全局变量指针
unsigned char *pGu8Data; // 指向全局数据的指针 // 全局常量指针
const unsigned char *pCu8ConstData = Cu8LookupTable; // 指向常量表
局部指针
void ProcessArray() { // 局部变量指针 unsigned int *pu16Ptr = &u16Value; // 静态指针 static unsigned long *pSu32StaticPtr = &Su32Time;
}
函数指针
typedef void (*pFunc)(void); // 函数指针类型定义 // 全局函数指针
pFunc pGFunc = NULL; void RegisterCallback(pFunc pf) { pGFunc = pf; // 注册回调函数
}
结构体命名规范
结构体定义与变量
// 结构体定义
struct tStructData { unsigned char u8Status; // 状态标志 unsigned long u32Value; // 数据值
}; // 全局结构体变量
struct tStructData GtData; // 局部结构体变量
void ProcessStruct() { struct tStructData tLocalData; // 本地数据 static struct tStructData StStaticData; // 静态数据
}
结构体指针
// 结构体指针
struct tStructData *ptData = &GtData; // 指向全局结构体 void ProcessPointer() { struct tStructData *ptLocal = &tLocalData; // 指向局部结构体
}
宏常量命名规范
基础宏定义
// 硬件相关宏
#define LED_PORT P1 // LED端口
#define LED_PIN 0x01 // LED引脚 // 系统配置宏
#define MAX_SCORE 100 // 最高分
#define DELAY_TIME 30000 // 延时时间(单位:微秒)
专业术语与缩写
// 专业术语处理
#define ESD_FLAG 1 // ESD(静电释放)标志 // 缩写规范
#define UART_BAUDRATE 115200 // UART波特率
#define PWM_DUTY_CYCLE 50 // PWM占空比
扩展应用
场景1:传感器数据处理
// 全局传感器数据
struct tSensorData { unsigned char u8Temp; // 温度 unsigned int u16Humidity; // 湿度
}; struct tSensorData GtSensor; void ReadSensor() { // 读取数据并存储到GtSensor
}
场景2:状态机设计
// 状态枚举
typedef enum { STATE_IDLE, STATE_RUNNING, STATE_ERROR
} DeviceState; // 全局状态变量
DeviceState GtDeviceState = STATE_IDLE; void UpdateState() { if (errorDetected) { GtDeviceState = STATE_ERROR; }
}
测试验证
测试用例设计
| 测试用例编号 | 测试场景 | 预期结果 |
|---|---|---|
| TC001 | 全局变量命名检查 | 变量名以Gu8/Gu16/Gu32开头 |
| TC002 | 循环变量命名检查 | 循环变量为单字母(i,j,k等) |
| TC003 | 结构体指针命名检查 | 指针名以pt开头 |
| TC004 | 宏常量命名检查 | 宏名全大写,使用下划线分隔 |
| TC005 | 静态变量可见性测试 | 静态变量仅在文件/函数内可见 |
调试方法
- 静态代码分析:
- 使用IDE插件(如PC-Lint)检查命名规则:
// 配置规则:检查变量名是否以u8/u16/u32开头
- 使用IDE插件(如PC-Lint)检查命名规则:
- 代码审查:
- 团队定期审查代码,确保命名一致性:
// 示例审查点: // 1. 全局变量是否遗漏Gu8前缀? // 2. 宏常量是否全大写?
- 团队定期审查代码,确保命名一致性:
- 编译器警告:
- 启用编译器警告,检测未遵循命名规范的变量:
// 示例警告: // warning: variable 'a' does not follow naming convention (variable-name)
- 启用编译器警告,检测未遵循命名规范的变量:
总结
本文通过详细示例,系统阐述了嵌入式开发中变量、常量、指针、结构体及宏常量的命名规范:
- 变量命名:
- 全局变量以
Gu8/Gu16/Gu32开头,局部变量以u8/u16/u32开头。 - 静态变量添加
ES/S前缀,区分全局与局部。
- 全局变量以
- 循环变量:
- 使用单字母(
i,j,k)以突出其特殊性,复杂循环可结合语义命名(如k表示索引)。
- 使用单字母(
- 数组命名:
- 后缀
Buffer/String/Table/Message区分用途,如Gu8DataBuffer表示数据缓冲区。
- 后缀
- 指针命名:
- 前缀
p,结合变量类型与作用域(如pGu8Data为全局变量指针)。
- 前缀
- 结构体命名:
- 前缀
t,指针用pt,静态变量用St(如GtData为全局结构体变量)。
- 前缀
- 宏常量:
- 全大写,下划线分隔,专业术语保留原意(如
ESD_FLAG)。
- 全大写,下划线分隔,专业术语保留原意(如
关键实践建议:
- 团队协作:通过文档统一命名规则,避免个人习惯差异。
- 工具辅助:使用IDE插件或脚本自动化检查命名规范。
- 代码可读性:优先选择清晰的命名,避免缩写歧义(如
PWM_DUTY_CYCLE优于PWM_DUTY)。
通过本文内容,开发者可建立统一的命名规范,显著提升代码质量与维护效率。
附录:
- 常见错误示例:
- 错误1:全局变量未加Gu8前缀:
// 错误: unsigned char u8Score; // 应改为Gu8Score - 错误2:宏常量未全大写:
// 错误: #define delayTime 30000 // 应改为DELAY_TIME
- 错误1:全局变量未加Gu8前缀:
- 禁止事项:
- 禁止使用无意义的变量名(如
a,b,c,循环变量除外)。
过本文内容,开发者可建立统一的命名规范,显著提升代码质量与维护效率。
- 禁止使用无意义的变量名(如
附录:
- 常见错误示例:
- 错误1:全局变量未加Gu8前缀:
// 错误: unsigned char u8Score; // 应改为Gu8Score - 错误2:宏常量未全大写:
// 错误: #define delayTime 30000 // 应改为DELAY_TIME
- 错误1:全局变量未加Gu8前缀:
- 禁止事项:
- 禁止使用无意义的变量名(如
a,b,c,循环变量除外)。 - 禁止宏常量与变量名冲突,避免歧义。
- 禁止使用无意义的变量名(如
相关文章:
【58】编程技巧:单片机编程命名规范
【58】编程技巧:单片机编程命名规范 引言 在大型嵌入式项目开发中,变量和常量的命名混乱会导致代码难以维护。本文系统阐述变量、常量、指针、结构体等命名规范,通过统一规则提升代码可读性与协作效率。目标是帮助开发者建立清晰的命名习惯&…...
Windows 部署项目 apache + mod_wsgi,nginx + waitress
文章目录 1、apache mod_wsgi,nginx waitress两种部署方式的区别2、以nginx waitress为例 有些项目必须部署在windows上,有IIS wfastcgi、apache mod_wsgi,nginx waitress部署方式 1、apache mod_wsgi,nginx waitress两种…...
车辆视频检测器linux版对于密码中包含敏感字符的处理方法
由于密码中含有敏感字符,导致前端页面异常,图标变灰,坐标拾取打不开图像等,主要原因是:密码比较前后不一致,左边是Abc_110,右边是:Abc_110%2B,对于此问题,特别…...
Java服务端开发基石:深入理解Spring IoC与依赖注入 (DI)
今天,我们从现代Java开发,尤其是企业级应用中,几乎无处不在的Spring框架的核心概念开始:控制反转(Inversion of Control, IoC) 与 依赖注入(Dependency Injection, DI)。理解它们&am…...
【人工智能】大语言模型多义词解析技术揭秘——以“项目“歧义消解为例
今天田辛老师和小伙伴探讨了一个有趣的多义词问题, 在人工智能技术日新月异的今天,大语言模型(LLM)对自然语言的理解能力已经达到令人惊叹的水平。大模型到底是如何去区分多义词的? 比如:当用户提到"…...
贪心算法(17)(java)可被三整除的最大整数和
给你一个整数数组 nums,请你找出并返回能被三整除的元素 最大和。 示例 1: 输入:nums [3,6,5,1,8] 输出:18 解释:选出数字 3, 6, 1 和 8,它们的和是 18(可被 3 整除的最大和)。 …...
qq邮箱群发程序
1.界面设计 1.1 环境配置 在外部工具位置进行配置 1.2 UI界面设计 1.2.1 进入QT的UI设计界面 在pycharm中按顺序点击,进入UI编辑界面: 点击第三步后进入QT的UI设计界面,通过点击按钮进行界面设计,设计后进行保存到当前Pycharm…...
K8S学习之基础七十九:关闭istio功能
关闭istio功能 kubectl get ns --show-labels kubectl label ns default istio-injection-有istio-injectionenabled的命名空间,pod都会开启istio功能 反之,如果要开启istio,在对应命名空间打上该标签即可...
上门预约洗鞋店小程序都具备哪些功能?
现在大家对洗鞋子的清洗条件越来越高,在家里不想去,那就要拿去洗鞋店去洗。如果有的客户没时间去洗鞋店,这个时候,有个洗鞋店小程序就可以进行上门取件,帮助没时间的客户去取需要清洗的鞋子,这样岂不是既帮…...
在Ubuntu 22.04上配置【C/C++编译环境】
在Ubuntu 22.04上配置C/C编译环境 如果你想在Ubuntu 22.04上编译和运行C或C程序,首先需要安装一个合适的编译器和相关工具。本文将为你提供详细的安装建议和操作步骤,帮助你快速搭建开发环境。 准备工作 在开始之前,确保你的系统可以通过终…...
蓝桥杯——走迷宫(Java-BFS)
这是一个经典的BFS算法 1. BFS算法保证最短路径 核心机制:广度优先搜索按层遍历所有可能的路径,首次到达终点的路径长度即为最短步数。这是BFS的核心优势。队列的作用:通过队列按先进先出的顺序处理节点,确保每一步探索的都是当…...
Spring MVC与Spring Boot文件上传配置差异对比及文件上传关键类详细说明与对比
一、Spring MVC与Spring Boot文件上传配置差异对比 1. 配置方式差异 框架配置方式依赖管理自动配置Spring MVC需手动配置MultipartResolver(如StandardServletMultipartResolver)需自行引入commons-fileupload等依赖无,默认不启用文件上传支…...
LLM 的model.generate() 参数说明
LLM 的model.generate() 参数说明 目录 LLM 的model.generate() 参数说明生成长度控制参数采样策略参数重复惩罚参数束搜索参数其他参数model.generate() 方法是 Hugging Face Transformers 库中用于文本生成的核心方法,它有众多参数可用于控制生成过程 生成长度控制参数 min…...
下载firefox.tar.xz后如何将其加入到Gnome启动器
起因:近期(2025-04-07)发现firefox公布了130.0 版本,可以对pdf文档进行签名了,想试一下,所以卸载了我的Debian12上的firefox-esr,直接下载了新版本的tar.xz 包。 经过一番摸索,实现了将其加入Gn…...
Flutter性能优化终极指南:从JIT到AOT的深度调优
一、Impeller渲染引擎调优策略 1.1 JIT预热智能预编译 // 配置Impeller预编译策略 void configureImpeller() {ImpellerEngine.precacheShaders(shaders: [lib/shaders/skinned_mesh.vert,lib/shaders/particle_system.frag],warmupFrames: 30, // 首屏渲染前预编译帧数cach…...
加密≠安全:文件夹密码遗忘背后的数据丢失风险与应对
在数字化时代,保护个人隐私和数据安全变得尤为重要。许多人选择对重要文件夹进行加密,以防止未经授权的访问。然而,一个常见且令人头疼的问题也随之而来——文件夹加密密码遗忘。当你突然发现自己无法访问那些加密的文件夹时,那种…...
实习技能记录【2】-----LVGL[基本概念]
LVGL主要概念 1. Screen (屏幕): 概念: 屏幕是 LVGL 应用程序中的顶层容器。它是用户界面的根对象,所有的可见 UI 元素最终都会添加到某个屏幕上(通常是活动屏幕)。 功能: 作为其他 UI 元素的父对象。 可以拥有自己的背景颜色、背景图片等样…...
【操作系统(Linux)】——通过案例学习父子进程的线程异步性
本篇旨在通过几个案例来学习父子进程的线程异步性 一、父进程与子进程 我们将要做的: 创建父子进程,观察父子进程执行的顺序,了解进程执行的异步行为 源代码: #include <stdio.h> #include <sys/types.h> #include…...
Go 语言范围 (Range)
Go 语言范围 (Range) Go 语言是一种静态强类型、编译型、并发型编程语言,由 Google 开发。它的简洁性和高效性使其成为众多开发者的首选。在 Go 语言中,range 是一个非常有用的关键字,用于遍历数组、切片、字符串以及通道(channe…...
【开源宝藏】30天学会CSS - DAY12 第十二课 从左向右填充的文字标题动画
用伪元素搞定文字填充动效:一行 JS 不写,效果炸裂 你是否曾经在设计页面标题时,觉得纯文字太寡淡?或者想做一个有动感的文字特效,但又不想引入 JS 甚至 SVG? 在这篇文章中,我们将通过 一段不到…...
nginx或tengine服务器,配置HTTPS下使用WebSocket的线上环境实践!
问题描述: HTTPS 下发起WS连接,连接失败,Chrom 浏览器报错。 socket.js:19 Mixed Content: The page at https://app.XXX.com was loaded over HTTPS, but attempted to connect to the insecure WebSocket endpoint ws://172.16.10.80:903…...
WSA(Windows 安卓子系统)过检测教程
windows安卓子系统WSA的root和magisk的安装教程 安卓子系统WSLWSA的rootmagisk安装 WSA(Windows 安卓子系统)过检测的方法与思路 一、引言 Windows 安卓子系统(WSA)为 Windows 用户提供了在电脑上运行安卓应用的便利。然而&…...
蓝桥杯 B3620 x 进制转 10 进制
题目描述 给一个小整数 x 和一个 x 进制的数 S。将 S 转为 10 进制数。对于超过十进制的数码,用 A,B,… 表示。 输入格式 第一行一个整数 x; 第二行一个字符串 S。 输出格式 输出仅包含一个整数,表示答案。 输入输出样例 …...
【Oracle篇】跨字符集迁移:基于数据泵的ZHS16GBK转AL32UTF8全流程迁移
💫《博主主页》:奈斯DB-CSDN博客 🔥《擅长领域》:擅长阿里云AnalyticDB for MySQL(分布式数据仓库)、Oracle、MySQL、Linux、prometheus监控;并对SQLserver、NoSQL(MongoDB)有了解 💖如果觉得文章对你有所帮…...
Qt子模块的功能介绍
一、Qt 主要子模块的功能介绍 1. 核心模块 模块名称功能描述QtCore核心非GUI功能(信号槽、线程、文件IO、容器类、JSON/XML处理等)QtGui基础图形绘制(窗口系统集成、OpenGL抽象、图像处理、字体管理等)QtConcurrent高级多线程API(并行计算框架,如QtConcurrent::run)QtN…...
FRP练手:hello,world实现
方案一:使用 Flask(推荐) from flask import Flaskapp Flask(__name__)app.route(/) def hello_world():return "你好啊世界"if __name__ __main__:# 监听所有网络接口(0.0.0.0),端口 3344app.…...
《深入探秘:分布式软总线自发现、自组网技术原理》
在当今数字化浪潮中,分布式系统的发展日新月异,而分布式软总线作为实现设备高效互联的关键技术,其自发现与自组网功能宛如打开智能世界大门的钥匙,为多设备协同工作奠定了坚实基础。 分布式软总线的重要地位 分布式软总线是构建…...
西门子S7-1200PLC 工艺指令PID_Temp进行控温
1.硬件需求: 西门子PLC:CPU 1215C DC/DC/DC PLC模块:SM 1231 TC模块 个人电脑:已安装TIA Portal V17软件 加热套:带加热电源线以及K型热电偶插头 固态继电器:恩爵 RT-SSK4A2032-08S-F 其他࿱…...
提升Windows安全的一些措施
由简单到复杂,仅供参考 一、杀毒软件: 1、杀毒能力: https://haokan.hao123.com/v?vid3883775443252827335&pdhaokan_share 2、使用注意: 一台主机只安装一个杀毒软件就可以了 杀毒软件会误报,造成正常文件…...
Jupyter notebook定制字体
一、生成配置文件 运行Anaconda Powershell Prompt终端,输入下面一行代码: jupyter notebook --generate-config 将生成文件“C:\Users\XXX\.jupyter\jupyter_notebook_config.py”,XXX为计算机账户名字。 二、修改配置文件 c.NotebookAp…...
