- 头文件函数声明增加extern
extern void DelyMS(unsigned int ms);
因为不同编译器可能会出问题,keil5不用加extern,但最好规范
- 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语言中是非法的,编译器会报错。
最终,两种写法都是可接受的,你应该根据你的代码风格指南或个人偏好来选择。如果你在一个团队中工作,最好遵循团队的一致风格。
- 枚举配置
typedef enum {DISABLE = 0, ENABLE = !DISABLE} EventStatus, ControlStatus;
typedef enum {RESET = 0, SET = !RESET} FlagStatus;
typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrStatus;
- 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寄存器的特定位来实现的,而不影响寄存器中的其他位。
未完待续