- 打卡等级:以坛为家II
- 打卡总天数:456
- 最近打卡:2025-05-02 08:26:53
已绑定手机
金牌会员
机长
- 积分
- 1691
|
本帖最后由 hsrzq 于 2023-6-16 10:43 编辑
- 整个项目中的所有代码风格都应当保持一致。例如:要用空格缩进就都用空格,要用Tab缩进就都用Tab……
(异议)代码都应当使用utf-8编码格式- 同一层级的代码缩进也应当相同;次一级应当比上一级拥有更多缩进;优先使用4个空格代替Tab缩进;尤其要注意成对花括号的对齐。赏心阅目的代码能方便自己和别人查找代码中的问题。
- 需要时一般的代码块之间可以空一行作为分隔,较大区别或分属不同大块的代码之间可以空两行,但不要出现大段大段毫无意义的空行在那里。
- 嵌入式开发中的特殊语法如sfr、sbit等应当定义宏,不要直接使用,以方便有需要时方便在keil、iar和sdcc间迁移。
#if defined (SDCC) || defined (__SDCC)
#define SBIT(name, addr, bit) __sbit __at(addr+bit) name
#define SFR(name, addr) __sfr __at(addr) name
#elif defined (__CX51__)
#define SBIT(name, addr, bit) sbit name = addr^bit
#define SFR(name, addr) sfr name = addr
#endif - 对于数字类型int、long等应当定义别名使用,别名应当能够充分体现是否有符号和长度,不要直接使用默认的原始类型。正例:u8、u16
- 定义类型别名时应当使用typedef而不是#define。原因是#define只是简单的文本替换,可能会产生意想不到的意外效果。
当使用#define pint (int*)时, pint a, b, c;等同于int* a, b, c;
当使用typedef int* pint 时,pint a, b, c;等同于int* a; int* b; int* c; - 不要直接使用默认的GPIO寄存器名称,应当再定义一个与业务相关的别名使用,以便在需要更换引脚时尽量少修改代码。正例:#define LED P01
- 一些常量魔术值应当先定义再使用,一般不要直接使用值本身。例如:TMR2_VECTOR一定比12更方便阅读
- 强烈建议创建一个用于全局配置的头文件,将一些开关、常量等统一在这个头文件中,如当前所使用晶振的频率等。正例:FreeRTOS中的FreeRTOSConfig.h头文件
- 定时器等的初始值不应当直接使用某个具体数字,而是应当使用全局配置文件中的晶振频率推算。这样方便在修改晶振中心频率后无需修改定时器。
- 数学运算优先使用位移操作,以尽可能提高代码性能。正例:T2L = BRT; T2H = BRT >> 8; 反例:T2L = BRT % 0xff; T2H = BRT / 0xff;
- 优先使用定时器、状态机等方式来进行延时,非万不得以不要使用delay方式死等
- 不要使用单个字母或无意义的单词作为变量名。例外:for循环中的i、j、k;表示坐标的x、y、z。反例:int aaa;
- 定义变量时习惯性加上默认的初始值,防止意外使用了RAM中不确定的随机值。正例:u8 value = 0;
- (待定)建议所有变量都加上xdata;非万不得以不要轻易使用pdata;无特殊要求一般不指定data和idata
- 数组常量表一定要加上code以节省RAM,经典场景如7/8段数码管的编码表、1602/12864的字模表等,通常占用体积巨大并且使用中并不会改变
- (待定)判断相等时常量在前,可以防止手误将双等号写成单等号,继而误将待判断的变量值改变。反例:if (P11 = 0) 则不仅读不到P1.1端口正确状态,还会将端口状态错误设置成0,并且该if条件将永远也不会为真
- 不要依赖运算符的优先级,随时可以加括号指定运算顺序。反例:if (x > 0 && y < 0 || x < 0 && y > 0)。正例:if ((x > 0 && y < 0) || (x < 0 && y > 0))
- 即使只有一条子语句,if/for/while等也不要省略花括号。例外:当使用while(!busy);这种等待标记变化时,是直接用分号将语句结束的,这种情况下可以省略花括号。
- 代码按照大功能块归属不同来分类,不同的大功能应当拆分到各自文件中,甚至可以各自拆分到不同的文件夹中。正例:usb可以有一个文件夹、spi可以有一个文件夹、i2c可以有一个文件夹……
- 对于一个大功能块下的方法定义,建议按照初始化→控制写→控制读→数据写→数据读→关闭的顺序组织(或者其它符合该功能/外设一般操作流程的顺序),只要不是随意胡乱放置即可。
- 不太好理解的代码,或容易记混的sfr赋值等,建议多写上注释。
/* 开启定时器4中断
* 0b1000____
* 0b1_______ : T4R : 定时器T4开始计数
* 0b_0______ : T4_C/T : 定时器/计数器选择
* 0b__0_____ : T4x12 : 对系统时钟12分频
* 0b___0____ : T4CLKO : 关闭定时器的输出
*/
T4T3M = (T4T3M & 0x0f) | 0x80;
|
|