这段代码中do while的作用:
宏定义中的语句块:do { ... } while (0) 允许你在宏定义中创建一个语句块,从而可以包含多条语句。这在宏定义中特别有用,因为宏只是简单的文本替换,不像函数那样有作用域和返回类型。因此,如果你想在宏中执行多个操作,你需要将这些操作放在一个语句块中。
保证逻辑在一行内完成:使用 do { ... } while (0) 可以确保宏定义中的所有逻辑都在一行内完成。这有助于避免在宏展开时可能出现的语法错误,特别是当宏在复杂的表达式中被调用时。
免编译器警告或错误:如果宏定义中有多条语句,并且没有使用 do { ... } while (0),编译器可能会产生关于未使用的循环变量的警告或错误。使用 do { ... } while (0) 可以避免这些警告或错误,因为循环条件是常量值“零”,所以循环实际上不会执行。
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5);对引脚电平进行翻转
对两个引脚初始化,推完输出,默认为高电平。
C中的三元运算符(X ? A : B):如果x为真(非0),那么宏BEEP(x)将调用HAL_GPIO_WritePin函数来设置(或打开)蜂鸣器;如果x为假(0),那么宏BEEP(x)将调用HAL_GPIO_WritePin函数来重置(或关闭)蜂鸣器。两个函数之间是冒号。
引脚的输入定义默认为高或低电平的作用:
防止输入端悬空:当输入端处于悬空状态时,即没有外部信号连接,其电平状态容易受到外界干扰而改变。上拉和下拉电阻可以将输入端的电平状态固定在一个确定的状态上,防止其受到外部信号的干扰。
确定电平状态:上拉电阻将不确定的信号通过一个电阻提升为高电平,而下拉电阻将不确定的信号通过一个电阻降低为低电平。这样,无论输入端是否接收到外部信号,都可以保证其电平状态是确定的,从而避免数字信号的传输和控制受到干扰。
按键扫描程序加入delay_ms()去抖动,KEY的值由 HAL_GPIO_ReadPin()所得。
按键扫描+switch判断。
一个外部中断的设置(重点看看gpio_init_struct.Mode = GPIO_MODE_IT_FALLING; ):
注意看下图的最后一行,这里的EXTI4_IRQn与PE4是对应的。
中断回调函数:
注意看这三个函数之间的关系,弄明白HAL外部中断回调函数的使用方法。
外部中断可以绕开主循环,避免影响。
usart的使用:
HAL_UART_Receive_IT开启UART接受中断。
串口的底层初始化:
#define USART_EN_RX 1 这种条件限定值得学习。
在串口中断里处理接收到的数据;
单片机中的看门狗(Watchdog Timer,WDT)是一个重要的安全保护机制。它由一个独立的时钟和一个计数器组成,用于检测系统是否运行正常。当计数器达到一个预先设定的值时,看门狗会向系统发出警报,以此来检测系统是否运行正常。如果系统运行正常,单片机会在计数器达到警报值之前给看门狗发出“清除”信号,以此来重置计数器,继续监测系统的运行状态。然而,如果系统运行异常,例如出现程序跑飞、受到干扰或陷入死循环等情况,单片机不会给看门狗发出“清除”信号。这种情况下,看门狗计数器会持续增加,当达到警报值后,看门狗会向系统发出警报,使单片机强制复位,从而使程序重新开始执行。这样,看门狗能够确保系统在异常情况下能够安全停止运行,避免造成重大损失。看门狗定时器的溢出时间越短,其灵敏度越高,系统跑飞后复位的时间也就越短,从而提高了系统的安全性。然而,这也意味着需要更频繁地给看门狗“喂食”,即在程序中定期给看门狗设置值,以防止其溢出。
看门狗初始化和喂狗:
需要再主函数中每一秒执行iwdg_feed(); 狗才不会疯强制系统复位。
窗口看门狗与普通看门狗的区别:
普通看门狗通常只设定一个时间阈值,系统需要在这个时间阈值内“喂狗”以重置看门狗。如果系统因故障或死锁无法在规定时间内“喂狗”,看门狗会触发复位操作,强制重启系统。这种看门狗方式相对简单,但缺乏灵活性,因为它只有一个固定的时间阈值。
窗口看门狗则设定了两个时间阈值:窗口上限和窗口下限。在这个窗口时间内,系统需要至少“喂狗”一次以重置看门狗。如果系统在这个窗口时间内没有“喂狗”,或者“喂狗”的时间超出窗口上限或下限,看门狗会触发复位操作。这种方式提供了更大的灵活性,因为它允许系统在一定时间范围内“喂狗”,而不是固定在一个时间点。
wwdg_init(0X7F, 0X5F, WWDG_PRESCALER_8);/* 计数器值为7f,窗口寄存器为5f,分频数为8 */
窗口看门狗可以设置中断处理函数,在窗口看门狗需要喂狗的时候调用。