我的编程规范
前言
当你看到这里,说明你即将养成一个好的编程习惯,而熟悉了面向对象的思想则对你代码的水平可以说是提升了非常非常非常高的档次,当你掌握后你就会发现你爱上了它,写出的代码可读性高,模块化,非常的 Nice ! 【以下编程习惯为我个人习惯,请根据自身进行取其精华,去其糟粕】
我的IAR代码块模板
- 文件注解
IAR格式
#TEMPLATE "&MY>&FileHeader_NOTE",&Author="Luckys.",&date="$DATE$",&description
/***************************************************************************
* File : $FILE_FNAME$
* Author : %1
* Date : %2
* description : %3
-----------------------------------
LED1 ----> PB5
-----------------------------------
****************************************************************************/
- 函数注解
IAR格式
#TEMPLATE &MY>&Function_NOTE,"Function &name","Input ¶meter","Return ¶meter","Description"
/*
* @function : %1()
* @param : %2
* @retval : %3
* @brief : %4
*/
static void %1(void)
{
%c
}
- 静态函数声明区
IAR格式
#TEMPLATE "&MY>&Static_STATENENT"
/*====================================static function declaration area BEGIN====================================*/
/*====================================static function declaration area END====================================*/
- 变量定义/声明区
IAR格式
#TEMPLATE "&MY>&pv_STATENENT"
/*====================================variable definition declaration area BEGIN===================================*/
/*====================================variable definition declaration area END===================================*/
- 头文件预编译
IAR格式
#TEMPLATE "&MY>&head_COMPILE",&Head_Name
#ifndef __%1_H
#define __%1_H
#include <>
#endif
- 结构体
IAR格式
#TEMPLATE "&CODE>&struct",&Struct_name
typedef struct
{
}%1;
我的vscode模板
h.json.code-snippets
{
"Print to console_1": {
"prefix": "//include",
"body": [
"#ifndef __X_H",
"#define __X_H",
"",
"",
"#endif",
""
],
"description": "头文件预编译"
},
"Print to console_2": {
"prefix": "//FileHeader_NOTE",
"body": [
"/***************************************************************************",
" * File: xxx.c",
" * Author: Luckys.",
" * Date: 2023/09/08",
" * description: ",
" -----------------------------------",
"None",
" -----------------------------------",
"****************************************************************************/",
"",
],
"description": "文件注解"
},
"Print to console_3": {
"prefix": "//Function_NOTE",
"body": [
"/*",
"* @function: xxx",
"* @param: None",
"* @retval: None",
"* @brief: 描述",
"*/",
"static void xxx(void)",
"{",
" ",
"}",
],
"description": "函数注解"
},
"Print to console_4": {
"prefix": "//Private_func",
"body": [
"/* Private function prototypes===============================================*/"
],
"description": "私有函数原型"
},
"Print to console_5": {
"prefix": "//Private_pv",
"body": [
"/* Private variables=========================================================*/"
],
"description": "私有变量"
},
"Print to console_6": {
"prefix": "//struct",
"body": [
"typedef struct",
"{",
" ",
"}struct_Name;",
],
"description": "结构体定义"
},
"Print to console_7": {
"prefix": "//enum",
"body": [
"typedef enum",
"{",
" ",
"}enum_Name;",
],
"description": "枚举定义"
},
"Print to console_8": {
"prefix": "//Private_def",
"body": [
"/* Private define============================================================*/",
],
"description": "私有宏定义"
},
"Print to console_9": {
"prefix": "//Public_pv",
"body": [
"/* Public variables==========================================================*/",
],
"description": "公共变量定义"
},
"Print to console_10": {
"prefix": "//Public_def",
"body": [
"/* Public define==========================================================*/",
],
"description": "公共宏定义"
},
}
模块化模板
| 创建下面文件夹 | 用途 |
|---|---|
| app | 放外设 |
| user | 放main.c及一些通用文件 |
main.c----> 主函数public.c----> 共同函数,包含通用的变量函数Sys_Init.c----> 系统初始化函数System.c----> 系统函数,包含正常运行与待机功能main.h----> 包含全部头文件callback.c----> 中断服务函数task.c----> 任务调度函数
注意
任务调度需要一个定时器进行1ms的定时,把 任务标记函数 放里面, 任务处理函数 放主循环内即可
我的习惯
| 单片机型号 | 工程模板地址 |
|---|---|
| CW32030C8T6 | cw32_Project-cw32030c8t6_template |
工程建立
| 工程文件夹 | 存放 |
|---|---|
| USER | main.c,main.h(主函数)public.c,public.h (公用函数)system.c,system.h (系统函数)system_init.c,system_init.h (系统初始函数)callback.c,callback.h (中断函数)task.h,task.c (任务调度) |
| LIB | inc文件夹 src文件夹 |
| APP | 外设代码 |
| OTHER | 启动文件或者其他杂的 |
变量
- 变量取名遵循首字母大写,多个单词则用
_连接即可,前缀跟取函数名一样,如果是指针的话特殊点,需要加前缀p_ - 形参和传入的参数名称最好不要一模一样,要区分开
头文件
-
库头文件,C库头文件则用
< >,自己定义的头文件使用" ",新建一个AllHead.h用于存放工程的所有头文件,在其他文件则只需要写这一个头文件即可! -
还有就是头文件的顺序习惯是从上到下是
单片机库---C库---自定义的头文件
顺序
静态函数声明要在结构体初始化的上面,全局变量则要在静态函数声明上面即头文件下,顺序:头文件---宏定义---全局变量---静态函数声明---结构体初始化---静态函数定义与实现
注释
宏定义,变量,函数定义则注释写它头顶(如果是函数需要有注解模板),函数声明则写在旁边,其他地方也是尽量写函数旁边,而且写旁边要求是一个TAB间隔然后再写注释,//后面要求一个空格
// 这是宏定义
#define Number 1
static void vFunc(void); // 这是一个函数
- 每一个
.c文件顶部都要写文件注解,要求至少有文件名,作者,时间,描述 - 每一个函数定义顶部都要写函数注解,要求至少有
函数名称,参数,返回值,描述 - 要求静态变量声明要写在声明区内,变量定义则写在变量区内,结构体初始化没有区域限制但是需要按照【顺序】放
宏定义
- 宏定义上面一行是注释,然后宏替换体要跟其他宏替换体对齐,宏定义要求是:
#define Number A
#define Number ABC
...
- 而且宏名称不要全部大写,首字母大写,英文/网络术语等缩写则全部大写,如:
CLK等等 - 如果宏替换体是数值类型或者指针类型则前面显性强制类型转换
#define PI (float)3.14159
结构体
- 结构体类型名称正常一般为 .c 文件的名称,如果一个文件定义多个类型不同的结构体则根据功能来另外起名,结构体类型名称要求首字母大写,多个英文则用
_分开,要求后缀是_st(特殊情况则看功能取名) - 结构体变量名称如果正常下则是结构体类型名称
_st前面部分,多个英文则_分开(特殊情况则看功能取名) - 要求结构体里面定义的变量或者函数指针右边都要写注释!
typedef struct
{
void (*Delay_ms)(uint16_t); // ms延时函数
}Public_st;
extern Public_st PUBLIC;
- 如果函数/变量不需要在外部被调用则不需要写在结构体里,只需要在 .c文件顶部声明然后在内部调用,其他的则全部丢结构体里方便给外部调用
枚举
命名的话后缀是 _et 结尾即可,其他的跟结构体规则一样
函数
- 要求全部函数使用
static前缀,函数名称要看返回值,然后在顶部进行函数声明,声明时形参只需要写参数类型即可!,函数名要求首字母大写,缩写则全部大写,单词与单词之间_隔开
static void vDelay_ms(uint16_t); // 声明
static void vDelay_ms(uint16_t ms)
{
...
}
- 函数前部分可以使用模块或者库名称来区分(但是要全部小写),也要遵循加前缀,后半部分按 【1】说明取即可(参照FreeRTOS的编程规范)
static void vPublic_delay_ms(void);
常用示例:
uint8_t ----> ucFunc() uint16_t ----> usFunc() uint32_t ----> ulFunc() void ----> vFunc() float ----> fFunc() double ----> dFunc() 指针类型则前面加p uint8_t* ----> pucFunc()
- 函数内定义的变量要求放函数内部顶部,for循环里的递增变量i 则直接在里面定义即可(使用C99写法不需要在顶部定义再使用)
