嵌入式代码编写规范

  1. 头文件函数声明增加extern
extern void DelyMS(unsigned int ms);

因为不同编译器可能会出问题,keil5不用加extern,但最好规范

  1. if(0 != nor_init())为什么不写成if( nor_init() != 0)

在C语言中,if语句的条件表达式可以是任何产生布尔结果的表达式。在大多数情况下,非零值被视为true,而零值被视为false。因此,if(0 != nor_init())和if(nor_init() != 0)在逻辑上是等价的,因为它们都会检查nor_init()函数的返回值是否不等于零。

以下是两种写法的逻辑解释:

if(0 != nor_init()):这种写法首先将0与nor_init()的返回值进行比较。如果nor_init()返回非零值,则条件为true,执行if语句块内的代码。
if(nor_init() != 0):这种写法直接将nor_init()的返回值与0进行比较。如果nor_init()返回非零值,则条件同样为true,执行if语句块内的代码。
从技术角度来看,两者都可以正常工作,并且没有性能差异。选择哪种风格取决于个人或团队的编码风格指南和偏好。以下是一些可能影响选择的原因:

可读性:有些人可能认为if(nor_init() != 0)的顺序更自然,因为它遵循了从左到右的阅读顺序,即先调用函数,然后比较结果。
习惯:有些程序员习惯于将常量放在比较的左侧,尤其是在比较指针和整数时,这种习惯可以帮助避免不小心将误写为=。
错误预防:将0放在比较的左侧可以防止你错误地将
写成单个=,因为0 = nor_init()在C语言中是非法的,编译器会报错。
最终,两种写法都是可接受的,你应该根据你的代码风格指南或个人偏好来选择。如果你在一个团队中工作,最好遵循团队的一致风格。

  1. 枚举配置
typedef enum {DISABLE = 0, ENABLE = !DISABLE} EventStatus, ControlStatus;
typedef enum {RESET = 0, SET = !RESET} FlagStatus;
typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrStatus;
  1. if else else不要省
static uint8_t _iap_get_host_status()
{
    uint32_t read_sta = 0; // 声明一个32位无符号整数变量,用于存储从主机读取的状态信息
    uint8_t ret;           // 声明一个8位无符号整数变量,用于存储SPI操作的返回值

    // 使用spi_read_data32函数通过SPI接口从主机读取状态信息,并将读取到的数据存储在read_sta变量中
    ret = spi_read_data32(g_reg_fd, REG_HIGH_ADDR, UPDATE_HOST_STA_ADDR, &read_sta);

    // 如果读取操作超时,则返回1
    if(ret == SPI_TIME_OUT)
        return 1;

    // 使用GET_BITS宏从read_sta变量中获取指定位置的位值,并将其存储在sg_iap_sta结构体的update_en和update_st成员中
    sg_iap_sta.update_en = GET_BITS(read_sta, HOST_UPDATE_EN_START, HOST_UPDATE_EN_END);
    sg_iap_sta.update_st = GET_BITS(read_sta, HOST_UPDATE_ST_START, HOST_UPDATE_ST_END);

    // 函数执行成功,返回0
    return 0;
}

_iap_get_host_status函数中,else块被省略了,这意味着当spi_read_data32函数成功返回且返回值不是SPI_TIME_OUT时,函数没有执行任何额外的代码。这种情况下,函数直接返回了0。

省略else块并不是一个好的编程实践,因为它可能导致代码的逻辑不完整。当spi_read_data32函数成功返回但不是因为超时时,代码应该继续执行以处理可能出现的其他错误情况。

例如,如果spi_read_data32函数成功返回,但读取的数据不正确或出现了其他问题,那么应该执行一些错误处理逻辑,而不是直接返回0。这样可以提高代码的健壮性和可维护性。

因此,如果spi_read_data32函数成功返回但不是因为超时,建议添加一个else块来处理这种情况,并可能返回一个特定的错误代码或执行一些错误处理逻辑。这样可以确保代码能够正确地处理各种可能的情况,从而提高程序的可靠性。

[https://mp.weixin.qq.com/s/JYZ3p0PIkU89wxBRQVG81g]消灭if else

  • |=, &=, 和 &=~ 的区别
void TIM2_Set(u8 sta)
{
	if(sta) // 如果sta非零(通常意味着sta为1,即真)
	{
    TIM2->CNT=0;         // 计数器清空,将定时器的计数器寄存器(CNT)设置为0
		TIM2->CR1|=1<<0;     // 使能定时器2,通过设置控制寄存器1(CR1)的第0位为1来启动定时器
	}
	else // 如果sta为零(即假)
		TIM2->CR1&=~(1<<0); // 关闭定时器2,通过将控制寄存器1(CR1)的第0位清零来停止定时器
}

关于操作符 |=, &=, 和 &=~ 的区别:

  • |=: 按位或赋值操作符
    它将左操作数的每一位与右操作数的相应位进行按位或操作,并将结果赋值给左操作数。
    例如,TIM2->CR1|=1<<0; 这行代码将控制寄存器1的第0位设置为1,而不影响其他位。
  • &=: 按位与赋值操作符
    它将左操作数的每一位与右操作数的相应位进行按位与操作,并将结果赋值给左操作数。
    例如,TIM2->CR1&=0xFF; 这行代码将保留CR1寄存器的低8位,而将其他位清零。
  • &=~: 按位与非赋值操作符
    它实际上是按位与和按位非的组合操作。首先对右操作数进行按位非操作,然后将结果与左操作数进行按位与操作,最后将结果赋值给左操作数。
    例如,TIM2->CR1&=~(1<<0); 这行代码首先将数字1左移0位(结果是1),然后对这个结果进行按位非操作(结果是 ~1,即 0xFFFFFFFE),最后将这个结果与CR1寄存器进行按位与操作,从而将CR1寄存器的第0位清零。

在 TIM2_Set 函数中,使用 |=1<<0 是为了将CR1寄存器的第0位设置为1,以启动定时器;而使用 &=~(1<<0) 是为了将CR1寄存器的第0位清零,以停止定时器。这两个操作都是通过修改CR1寄存器的特定位来实现的,而不影响寄存器中的其他位。
未完待续

  • 6
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值