嵌入式应用开发之代码整洁之道二

       前言:本系列教程旨在如何将自己的代码写的整洁,同时本系列参考 正点原子 , C++代码整洁之道,编写可读的代码艺术。

#函数的应用规范

#函数作用的功能

        函数功能:函数应该只做一件事,做好这件事,只做这一件事,一个函数不应该被应用于多个功能,如果满足前者,这个函数就应该,被二次拆分,出更细致的功能,去简化这个函数,直到划分为每个功能单一的函数

函数的第一规则是要短小,第二条规则是还要更短小,函数就该小。—————Clean Code

       函数封装:将重复调用的代码封装为功能单一的函数,进行调用,重复的代码,重复写不封装,浪费代码行,浪费阅读时间,封装之后,一行代码,能解决的事情,不用写那么多行,还能提升自己效率,封装函数在主程序循环中调用和没有进行封装调用,循环执行时间不一样的,前者是比后者快的相对来讲。

       函数嵌套:封装函数中,不要进行大量的循环判断嵌套,当在函数体中进行(if  for  while  switch)应用这些语句的大量嵌套,那么别人读懂这个函数,就要思考很多函数对应的情况,如果没有理解这个函数,进行调用,就会出现问题,最后要进行排查,嵌套最好不要超过4层向上。

        函数参数:自己定义地多参数函数,别人在调用的时候,可能需要 Ctrl+F仔细看每个参数的取值,是什么,函数的参数越少,在调用的时候,就越傻瓜式,就越省事,当然前提是,减少参数并不会影响功能。

最理想的参数数量是零,其次是单参数函数,在此是双参数函数——————Clean Code

#代码行的应用以及规范

        代码长度:每行代码的长度应该限制在 80列,如果超过这个数,这句代码,后半句建议写到下一行 ,如果非要写很长,用很长的变量名,这样可读性会很差,同时在一些编辑器 IDE 里面是由行宽限制的。

perm_count_msg.head.len = NO7_TO_STAT_PERM_COUNT_LEN
+ STAT_SIZE_PER_FRAM * sizeof( _UL );    ————————正点原子

        函数间隔:调用不同的库函数之间,每个函数之间建议使用回车进行分隔,方便阅读。

int main(void)
{
	
	board_init();
	
	uart1_init(115200U);

    printf("start\r\n");
        
    PCA9685_Init(60,0);	//PCA9685--16路舵机初始化  频率60Hz -- 0度
	
    delay_ms(1000);
	
    PID  servo;//声明PID 结构体 变量
	
	PID_Init(&servo,Kp,Ki,Kd);//这几个宏定义在PID.h文件里面。
    while(1) 
    {
       
    }
	
}

        声明变量按行写:一行声明多个变量,跟每行声明一个变量,可能有的小伙伴觉得前者比较省事情,但是这样写,不利于他人阅读。

int a = b =0;//不利于观看

int a = 0;//推荐写法
int b = 0;

        判断语句书写:if  while for do case switch default  这些语句单独占一行,后面执行语句,不论有多少条,统一加  {}  ,进行表示,判断语句单独占一行

不规范的写法: 
if (p_gpiox->IDR & pinx) return 1; /* pinx 的状态为 1 */
else return 0; /* pinx 的状态为 0 */
应改为:
if (p_gpiox->IDR & pinx)
{
return 1; /* pinx 的状态为 1 */
}
else
{
 return 0; /* pinx 的状态为 0 */
}

#变量的声明与使用

        变量的用途:在声明变量的时候,应该不用或者少用,全局变量,或者使用static声明全局变量,作为文件的私有变量,全部变量应该是模块化的私有数据,不能作用为对外的接口,使用static定义全局变量可以防止,外部文件对定义文件的变量非正常访问。同时一个变量应该只用作一个用途。

一个变量只能有一个特定功能,不能把一个变量作为多用途使用,——————正点原子
int time;
time = 200; /* 表示时间 */
time = getvalue(); /* 用作返回值 */
//应改为下面的
int time,ret;
time = 200;
ret = getvalue();

#宏定义的使用

               宏定义作用:大量使用宏定义,方便移植程序,提升程序运行速度,如果使用宏定义写的程序,移植的时候,一般只需要改头文件里面的宏定义就能,进行正常运行工作,同样一段程序,不写宏定义,那么可能每个参数都要从头改到尾,会造成时间上的浪费。

#ifndef _BSP_PCA9685_H_
#define _BSP_PCA9685_H_

#include "stm32f4xx.h"


//端口移植
#define RCC_PCA9685_GPIO  	RCC_AHB1Periph_GPIOA
#define PORT_PCA9685 		GPIOA

#define GPIO_SDA 			GPIO_Pin_5
#define GPIO_SCL 			GPIO_Pin_6

//设置SDA输出模式
#define SDA_OUT()   {        \
                        GPIO_InitTypeDef  GPIO_InitStructure; \
                        GPIO_InitStructure.GPIO_Pin = GPIO_SDA; \
                        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; \
                        GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; \
                        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; \
                        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; \
                        GPIO_Init(GPIOA, &GPIO_InitStructure); \
                     }
//设置SDA输入模式
#define SDA_IN()    {        \
                        GPIO_InitTypeDef  GPIO_InitStructure; \
                        GPIO_InitStructure.GPIO_Pin = GPIO_SDA; \
                        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; \
                        GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; \
                        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; \
                        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; \
                        GPIO_Init(GPIOA, &GPIO_InitStructure); \
                    }
//获取SDA引脚的电平变化
#define SDA_GET()       GPIO_ReadInputDataBit(GPIOA, GPIO_SDA)
//SDA与SCL输出
#define SDA(x)          GPIO_WriteBit(GPIOA, GPIO_SDA, (x?Bit_SET:Bit_RESET) )
#define SCL(x)          GPIO_WriteBit(GPIOA, GPIO_SCL, (x?Bit_SET:Bit_RESET) )

#define PCA_Addr              0x80        //IIC地址
#define PCA_Model             0x00        
#define LED0_ON_L             0x06
#define LED0_ON_H             0x07
#define LED0_OFF_L            0x08
#define LED0_OFF_H            0x09
#define PCA_Pre               0xFE        //配置频率地址

void PCA9685_Init(float hz,uint8_t angle);
void setAngle(uint8_t num,uint8_t angle);
void PCA9685_setFreq(float freq);
void PCA9685_setPWM(uint8_t num,uint32_t on,uint32_t off);

#endif

        除此之外,宏定义是预处理指令,这种指令的执行,实在程序执行之前,在程序编译之前,大量使用这种指令,会提升程序运行速度,这种指令在程序执行前就已经执行过了,能提升程序整体运行速度。

        初次之外,二次封装库中的函数,完全可以用宏定义函数来代替,不用在程序中进行封装,宏定义一行就能搞定的事情,模块文件中,封装在声明,没必要写那么多行。

//错误写法,写了之后还要声明函数。
void SDA(x)
{
GPIO_WriteBit(GPIOA, GPIO_SDA, (x?Bit_SET:Bit_RESET) );
}

void SCL(x)
{
GPIO_WriteBit(GPIOA, GPIO_SDA, (x?Bit_SET:Bit_RESET) );
}
//正确写法宏定义声明函数
//这种写发程序执行速度比较块
#define SDA(x)          GPIO_WriteBit(GPIOA, GPIO_SDA, (x?Bit_SET:Bit_RESET) )
#define SCL(x)          GPIO_WriteBit(GPIOA, GPIO_SCL, (x?Bit_SET:Bit_RESET) )

                                欢迎指正,希望对你,有所帮助!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值