8、nRF52xx蓝牙学习(boards.h文件学习)
boards.h文件的代码如下:
#ifndef BOARDS_H
#define BOARDS_H#include "nrf_gpio.h"
#include "nordic_common.h"#if defined(BOARD_NRF6310)#include "nrf6310.h"
#elif defined(BOARD_PCA10000)#include "pca10000.h"
#elif defined(BOARD_PCA10001)#include "pca10001.h"
#elif defined(BOARD_PCA10002)#include "pca10000.h"
#elif defined(BOARD_PCA10003)#include "pca10003.h"
#elif defined(BOARD_PCA20006)#include "pca20006.h"
#elif defined(BOARD_PCA10028)#include "pca10028.h"
#elif defined(BOARD_PCA10031)#include "pca10031.h"
#elif defined(BOARD_PCA10036)#include "pca10036.h"
#elif defined(BOARD_PCA10040)#include "pca10040.h"
#elif defined(BOARD_PCA10056)#include "pca10056.h"
#elif defined(BOARD_PCA10100)#include "pca10100.h"
#elif defined(BOARD_PCA10112)#include "pca10112.h"
#elif defined(BOARD_PCA20020)#include "pca20020.h"
#elif defined(BOARD_PCA10059)#include "pca10059.h"
#elif defined(BOARD_WT51822)#include "wt51822.h"
#elif defined(BOARD_N5DK1)#include "n5_starterkit.h"
#elif defined (BOARD_D52DK1)#include "d52_starterkit.h"
#elif defined (BOARD_ARDUINO_PRIMO)#include "arduino_primo.h"
#elif defined (CUSTOM_BOARD_INC)#include STRINGIFY(CUSTOM_BOARD_INC.h)
#elif defined(BOARD_CUSTOM)#include "custom_board.h"
#else
#error "Board is not defined"#endif#if defined (SHIELD_BSP_INC)#include STRINGIFY(SHIELD_BSP_INC.h)
#endif#ifdef __cplusplus
extern "C" {
#endif/**@defgroup BSP_BOARD_INIT_FLAGS Board initialization flags.* @{ */
#define BSP_INIT_NONE 0 /**< No initialization of LEDs or buttons (@ref bsp_board_init).*/
#define BSP_INIT_LEDS (1 << 0) /**< Enable LEDs during initialization (@ref bsp_board_init).*/
#define BSP_INIT_BUTTONS (1 << 1) /**< Enable buttons during initialization (@ref bsp_board_init).*/
/**@} *//*** Function for returning the state of an LED.** @param led_idx LED index (starting from 0), as defined in the board-specific header.** @return True if the LED is turned on.*/
bool bsp_board_led_state_get(uint32_t led_idx);/*** Function for turning on an LED.** @param led_idx LED index (starting from 0), as defined in the board-specific header.*/
void bsp_board_led_on(uint32_t led_idx);/*** Function for turning off an LED.** @param led_idx LED index (starting from 0), as defined in the board-specific header.*/
void bsp_board_led_off(uint32_t led_idx);/*** Function for inverting the state of an LED.** @param led_idx LED index (starting from 0), as defined in the board-specific header.*/
void bsp_board_led_invert(uint32_t led_idx);
/*** Function for turning off all LEDs.*/
void bsp_board_leds_off(void);/*** Function for turning on all LEDs.*/
void bsp_board_leds_on(void);/*** Function for initializing the BSP handling for the board.** @note This also initializes the USB DFU trigger library if @ref BOARDS_WITH_USB_DFU_TRIGGER is 1.** @param[in] init_flags Flags specifying what to initialize (LEDs/buttons).* See @ref BSP_BOARD_INIT_FLAGS.*/
void bsp_board_init(uint32_t init_flags);/*** Function for converting pin number to LED index.** @param pin_number Pin number.** @return LED index of the given pin or 0xFFFFFFFF if invalid pin provided.*/
uint32_t bsp_board_pin_to_led_idx(uint32_t pin_number);/*** Function for converting LED index to pin number.** @param led_idx LED index.** @return Pin number.*/
uint32_t bsp_board_led_idx_to_pin(uint32_t led_idx);/*** Function for returning the state of a button.** @param button_idx Button index (starting from 0), as defined in the board-specific header.** @return True if the button is pressed.*/
bool bsp_board_button_state_get(uint32_t button_idx);/*** Function for converting pin number to button index.** @param pin_number Pin number.** @return Button index of the given pin or 0xFFFFFFFF if invalid pin provided.*/
uint32_t bsp_board_pin_to_button_idx(uint32_t pin_number);/*** Function for converting button index to pin number.** @param button_idx Button index.** @return Pin number.*/
uint32_t bsp_board_button_idx_to_pin(uint32_t button_idx);#define BSP_BOARD_LED_0 0
#define BSP_BOARD_LED_1 1
#define BSP_BOARD_LED_2 2
#define BSP_BOARD_LED_3 3
#define BSP_BOARD_LED_4 4
#define BSP_BOARD_LED_5 5
#define BSP_BOARD_LED_6 6
#define BSP_BOARD_LED_7 7#define PIN_MASK(_pin) /*lint -save -e504 */ \(1u << (uint32_t)((_pin) & (~P0_PIN_NUM))) \/*lint -restore */#define PIN_PORT(_pin) (((_pin) >= P0_PIN_NUM) ? NRF_P1 : NRF_GPIO)#ifdef BSP_LED_0
#define BSP_LED_0_MASK PIN_MASK(BSP_LED_0)
#define BSP_LED_0_PORT PIN_PORT(BSP_LED_0)
#else
#define BSP_LED_0_MASK 0
#define BSP_LED_0_PORT 0
#endif
#ifdef BSP_LED_1
#define BSP_LED_1_MASK PIN_MASK(BSP_LED_1)
#define BSP_LED_1_PORT PIN_PORT(BSP_LED_1)
#else
#define BSP_LED_1_MASK 0
#define BSP_LED_1_PORT 0
#endif
#ifdef BSP_LED_2
#define BSP_LED_2_MASK PIN_MASK(BSP_LED_2)
#define BSP_LED_2_PORT PIN_PORT(BSP_LED_2)
#else
#define BSP_LED_2_MASK 0
#define BSP_LED_2_PORT 0
#endif
#ifdef BSP_LED_3
#define BSP_LED_3_MASK PIN_MASK(BSP_LED_3)
#define BSP_LED_3_PORT PIN_PORT(BSP_LED_3)
#else
#define BSP_LED_3_MASK 0
#define BSP_LED_3_PORT 0
#endif
#ifdef BSP_LED_4
#define BSP_LED_4_MASK PIN_MASK(BSP_LED_4)
#define BSP_LED_4_PORT PIN_PORT(BSP_LED_4)
#else
#define BSP_LED_4_MASK 0
#define BSP_LED_4_PORT 0
#endif
#ifdef BSP_LED_5
#define BSP_LED_5_MASK PIN_MASK(BSP_LED_5)
#define BSP_LED_5_PORT PIN_PORT(BSP_LED_5)
#else
#define BSP_LED_5_MASK 0
#define BSP_LED_5_PORT 0
#endif
#ifdef BSP_LED_6
#define BSP_LED_6_MASK PIN_MASK(BSP_LED_6)
#define BSP_LED_6_PORT PIN_PORT(BSP_LED_6)
#else
#define BSP_LED_6_MASK 0
#define BSP_LED_6_PORT 0
#endif
#ifdef BSP_LED_7
#define BSP_LED_7_MASK PIN_MASK(BSP_LED_7)
#define BSP_LED_7_PORT PIN_PORT(BSP_LED_7)
#else
#define BSP_LED_7_MASK 0
#define BSP_LED_7_PORT 0
#endif#define LEDS_MASK (BSP_LED_0_MASK | BSP_LED_1_MASK | \BSP_LED_2_MASK | BSP_LED_3_MASK | \BSP_LED_4_MASK | BSP_LED_5_MASK | \BSP_LED_6_MASK | BSP_LED_7_MASK)#define BSP_BOARD_BUTTON_0 0
#define BSP_BOARD_BUTTON_1 1
#define BSP_BOARD_BUTTON_2 2
#define BSP_BOARD_BUTTON_3 3
#define BSP_BOARD_BUTTON_4 4
#define BSP_BOARD_BUTTON_5 5
#define BSP_BOARD_BUTTON_6 6
#define BSP_BOARD_BUTTON_7 7#ifdef BSP_BUTTON_0
#define BSP_BUTTON_0_MASK (1<<BSP_BUTTON_0)
#else
#define BSP_BUTTON_0_MASK 0
#endif
#ifdef BSP_BUTTON_1
#define BSP_BUTTON_1_MASK (1<<BSP_BUTTON_1)
#else
#define BSP_BUTTON_1_MASK 0
#endif
#ifdef BSP_BUTTON_2
#define BSP_BUTTON_2_MASK (1<<BSP_BUTTON_2)
#else
#define BSP_BUTTON_2_MASK 0
#endif
#ifdef BSP_BUTTON_3
#define BSP_BUTTON_3_MASK (1<<BSP_BUTTON_3)
#else
#define BSP_BUTTON_3_MASK 0
#endif
#ifdef BSP_BUTTON_4
#define BSP_BUTTON_4_MASK (1<<BSP_BUTTON_4)
#else
#define BSP_BUTTON_4_MASK 0
#endif
#ifdef BSP_BUTTON_5
#define BSP_BUTTON_5_MASK (1<<BSP_BUTTON_5)
#else
#define BSP_BUTTON_5_MASK 0
#endif
#ifdef BSP_BUTTON_6
#define BSP_BUTTON_6_MASK (1<<BSP_BUTTON_6)
#else
#define BSP_BUTTON_6_MASK 0
#endif
#ifdef BSP_BUTTON_7
#define BSP_BUTTON_7_MASK (1<<BSP_BUTTON_7)
#else
#define BSP_BUTTON_7_MASK 0
#endif#define BUTTONS_MASK (BSP_BUTTON_0_MASK | BSP_BUTTON_1_MASK | \BSP_BUTTON_2_MASK | BSP_BUTTON_3_MASK | \BSP_BUTTON_4_MASK | BSP_BUTTON_5_MASK | \BSP_BUTTON_6_MASK | BSP_BUTTON_7_MASK)/* This macro is supporting only P0 and should not be used if LEDs are on other ports. */
#define LEDS_OFF(leds_mask) do { ASSERT(sizeof(leds_mask) == 4); \NRF_GPIO->OUTSET = (leds_mask) & (LEDS_MASK & LEDS_INV_MASK); \NRF_GPIO->OUTCLR = (leds_mask) & (LEDS_MASK & ~LEDS_INV_MASK); } while (0)/* This macro is supporting only P0 and should not be used if LEDs are on other ports. */
#define LEDS_ON(leds_mask) do { ASSERT(sizeof(leds_mask) == 4); \NRF_GPIO->OUTCLR = (leds_mask) & (LEDS_MASK & LEDS_INV_MASK); \NRF_GPIO->OUTSET = (leds_mask) & (LEDS_MASK & ~LEDS_INV_MASK); } while (0)/* This macro is supporting only P0 and should not be used if LEDs are on other ports. */
#define LED_IS_ON(leds_mask) ((leds_mask) & (NRF_GPIO->OUT ^ LEDS_INV_MASK) )/* This macro is supporting only P0 and should not be used if LEDs are on other ports. */
#define LEDS_INVERT(leds_mask) do { uint32_t gpio_state = NRF_GPIO->OUT; \ASSERT(sizeof(leds_mask) == 4); \NRF_GPIO->OUTSET = ((leds_mask) & ~gpio_state); \NRF_GPIO->OUTCLR = ((leds_mask) & gpio_state); } while (0)/* This macro is supporting only P0 and should not be used if LEDs are on other ports. */
#define LEDS_CONFIGURE(leds_mask) do { uint32_t pin; \ASSERT(sizeof(leds_mask) == 4); \for (pin = 0; pin < 32; pin++) \if ( (leds_mask) & (1 << pin) ) \nrf_gpio_cfg_output(pin); } while (0)#ifdef __cplusplus
}
#endif#endif
代码理解如下:
这是一个名为 BOARDS_H 的头文件代码,主要用于定义与开发板相关的配置、引脚操作函数声明以及一些常用的宏定义。
下面对其进行详细解释:
1. 头文件保护
#ifndef BOARDS_H
#define BOARDS_H
这是头文件保护宏,防止该头文件被重复包含,确保头文件中的内容在一个编译单元中只被处理一次。
2. 包含其他头文件
#include "nrf_gpio.h"
#include "nordic_common.h"
包含了 nrf_gpio.h 和 nordic_common.h 头文件,前者可能提供了与 Nordic 芯片 GPIO 操作相关的定义和函数声明,后者可能包含了 Nordic 相关的通用定义和工具函数。
3. 根据不同开发板包含对应头文件
#if defined(BOARD_NRF6310)
#include "nrf6310.h"
#elif defined(BOARD_PCA10000)
#include "pca10000.h"
#elif defined(BOARD_PCA10001)
#include "pca10001.h"
#elif defined(BOARD_PCA10002)
#include "pca10000.h"
#elif defined(BOARD_PCA10003)
#include "pca10003.h"
#elif defined(BOARD_PCA20006)
#include "pca20006.h"
#elif defined(BOARD_PCA10028)
#include "pca10028.h"
#elif defined(BOARD_PCA10031)
#include "pca10031.h"
#elif defined(BOARD_PCA10036)
#include "pca10036.h"
#elif defined(BOARD_PCA10040)
#include "pca10040.h"
#elif defined(BOARD_PCA10056)
#include "pca10056.h"
#elif defined(BOARD_PCA10100)
#include "pca10100.h"
#elif defined(BOARD_PCA10112)
#include "pca10112.h"
#elif defined(BOARD_PCA20020)
#include "pca20020.h"
#elif defined(BOARD_PCA10059)
#include "pca10059.h"
#elif defined(BOARD_WT51822)
#include "wt51822.h"
#elif defined(BOARD_N5DK1)
#include "n5_starterkit.h"
#elif defined (BOARD_D52DK1)
#include "d52_starterkit.h"
#elif defined (BOARD_ARDUINO_PRIMO)
#include "arduino_primo.h"
#elif defined (CUSTOM_BOARD_INC)
#include STRINGIFY(CUSTOM_BOARD_INC.h)
#elif defined(BOARD_CUSTOM)
#include "custom_board.h"
#else
#error "Board is not defined"
#endif
根据不同的 BOARD_* 宏定义,包含相应开发板的特定头文件。如果没有定义任何一个已知的开发板宏,则会产生编译错误,提示 Board is not defined。
4. 包含扩展板相关头文件
#if defined (SHIELD_BSP_INC)
#include STRINGIFY(SHIELD_BSP_INC.h)
#endif
如果定义了 SHIELD_BSP_INC 宏,则包含相应的扩展板头文件。
5. C++ 兼容声明
#ifdef __cplusplus
extern "C" {
#endif
如果是 C++ 编译环境,使用 extern "C" 声明,确保 C 语言风格的函数声明在 C++ 中具有正确的链接属性,以便 C++ 代码可以调用这些函数。
6. 开发板初始化标志宏定义
#define BSP_INIT_NONE 0 /**< No initialization of LEDs or buttons (@ref bsp_board_init).*/
#define BSP_INIT_LEDS (1 << 0) /**< Enable LEDs during initialization (@ref bsp_board_init).*/
#define BSP_INIT_BUTTONS (1 << 1) /**< Enable buttons during initialization (@ref bsp_board_init).*/
定义了三个宏,用于表示开发板初始化时的不同标志:
• BSP_INIT_NONE:表示不初始化 LED 和按键。
• BSP_INIT_LEDS:表示初始化时启用 LED。
• BSP_INIT_BUTTONS:表示初始化时启用按键。
7. LED 操作函数声明
bool bsp_board_led_state_get(uint32_t led_idx);
void bsp_board_led_on(uint32_t led_idx);
void bsp_board_led_off(uint32_t led_idx);
void bsp_board_led_invert(uint32_t led_idx);
void bsp_board_leds_off(void);
void bsp_board_leds_on(void);
声明了一系列与 LED 操作相关的函数:
• bsp_board_led_state_get:获取指定 LED 的状态(是否点亮)。
• bsp_board_led_on:点亮指定的 LED。
• bsp_board_led_off:熄灭指定的 LED。
• bsp_board_led_invert:反转指定 LED 的状态。
• bsp_board_leds_off:熄灭所有 LED。
• bsp_board_leds_on:点亮所有 LED。
8. 开发板初始化函数声明
void bsp_board_init(uint32_t init_flags);
声明了开发板初始化函数 bsp_board_init,接受一个 init_flags 参数,根据传入的标志决定初始化哪些部分(如 LED 和按键)。
9. 引脚与 LED 索引转换函数声明
uint32_t bsp_board_pin_to_led_idx(uint32_t pin_number);
uint32_t bsp_board_led_idx_to_pin(uint32_t led_idx);
声明了两个函数用于在引脚编号和 LED 索引之间进行转换:
• bsp_board_pin_to_led_idx:将引脚编号转换为 LED 索引。
• bsp_board_led_idx_to_pin:将 LED 索引转换为引脚编号。
10. 按键操作函数声明
bool bsp_board_button_state_get(uint32_t button_idx);
uint32_t bsp_board_pin_to_button_idx(uint32_t pin_number);
uint32_t bsp_board_button_idx_to_pin(uint32_t button_idx);
声明了一系列与按键操作相关的函数:
• bsp_board_button_state_get:获取指定按键的状态(是否按下)。 • bsp_board_pin_to_button_idx:将引脚编号转换为按键索引。
• bsp_board_button_idx_to_pin:将按键索引转换为引脚编号。
11. LED 和按键编号宏定义
#define BSP_BOARD_LED_0 0
#define BSP_BOARD_LED_1 1
#define BSP_BOARD_LED_2 2
#define BSP_BOARD_LED_3 3
#define BSP_BOARD_LED_4 4
#define BSP_BOARD_LED_5 5
#define BSP_BOARD_LED_6 6
#define BSP_BOARD_LED_7 7
#define BSP_BOARD_BUTTON_0 0
#define BSP_BOARD_BUTTON_1 1
#define BSP_BOARD_BUTTON_2 2
#define BSP_BOARD_BUTTON_3 3
#define BSP_BOARD_BUTTON_4 4
#define BSP_BOARD_BUTTON_5 5
#define BSP_BOARD_BUTTON_6 6
#define BSP_BOARD_BUTTON_7 7
定义了 LED 和按键的编号宏,从 0 到 7,用于标识不同的 LED 和按键。
12. 引脚掩码和端口宏定义
#define PIN_MASK(_pin) /*lint -save -e504 */ \
(1u << (uint32_t)((_pin) & (~P0_PIN_NUM))) \
/*lint -restore */
#define PIN_PORT(_pin) (((_pin) >= P0_PIN_NUM) ? NRF_P1 : NRF_GPIO)
• PIN_MASK:根据引脚编号生成引脚掩码,用于后续对引脚的操作。
• PIN_PORT:根据引脚编号判断引脚所属的端口(NRF_P1 或 NRF_GPIO)。
13. 每个 LED 的掩码和端口定义
#ifdef BSP_LED_0
#define BSP_LED_0_MASK PIN_MASK(BSP_LED_0)
#define BSP_LED_0_PORT PIN_PORT(BSP_LED_0)
#else
#define BSP_LED_0_MASK 0
#define BSP_LED_0_PORT 0
#endif
// 其他 LED 类似
根据是否定义了相应的 BSP_LED_X 宏,为每个 LED 生成掩码和端口定义。如果未定义,则掩码和端口都设为 0。
14. 所有 LED 和按键的总掩码宏定义
#define LEDS_MASK (BSP_LED_0_MASK | BSP_LED_1_MASK | \
BSP_LED_2_MASK | BSP_LED_3_MASK | \
BSP_LED_4_MASK | BSP_LED_5_MASK | \
BSP_LED_6_MASK | BSP_LED_7_MASK)
#define BUTTONS_MASK (BSP_BUTTON_0_MASK | BSP_BUTTON_1_MASK | \
BSP_BUTTON_2_MASK | BSP_BUTTON_3_MASK | \
BSP_BUTTON_4_MASK | BSP_BUTTON_5_MASK | \
BSP_BUTTON_6_MASK | BSP_BUTTON_7_MASK)
分别将所有 LED 和按键的掩码进行按位或操作,得到所有 LED 和按键的总掩码。
15. LED 控制宏定义
#define LEDS_OFF(leds_mask) do { ASSERT(sizeof(leds_mask) == 4); \
NRF_GPIO->OUTSET = (leds_mask) & (LEDS_MASK & LEDS_INV_MASK); \
NRF_GPIO->OUTCLR = (leds_mask) & (LEDS_MASK & ~LEDS_INV_MASK); } while (0)
#define LEDS_ON(leds_mask) do { ASSERT(sizeof(leds_mask) == 4); \
NRF_GPIO->OUTCLR = (leds_mask) & (LEDS_MASK & LEDS_INV_MASK); \
NRF_GPIO->OUTSET = (leds_mask) & (LEDS_MASK & ~LEDS_INV_MASK); } while (0)
#define LED_IS_ON(leds_mask) ((leds_mask) & (NRF_GPIO->OUT ^ LEDS_INV_MASK) )
#define LEDS_INVERT(leds_mask) do { uint32_t gpio_state = NRF_GPIO->OUT; \
ASSERT(sizeof(leds_mask) == 4); \
NRF_GPIO->OUTSET = ((leds_mask) & ~gpio_state); \
NRF_GPIO->OUTCLR = ((leds_mask) & gpio_state); } while (0)
#define LEDS_CONFIGURE(leds_mask) do { uint32_t pin; \
ASSERT(sizeof(leds_mask) == 4); \
for (pin = 0; pin < 32; pin++) \
if ( (leds_mask) & (1 << pin) ) \
nrf_gpio_cfg_output(pin); } while (0)
定义了一系列用于控制 LED 的宏:
• LEDS_OFF:熄灭指定的 LED。
• LEDS_ON:点亮指定的 LED。
• LED_IS_ON:判断指定的 LED 是否点亮。
• LEDS_INVERT:反转指定 LED 的状态。
• LEDS_CONFIGURE:将指定的引脚配置为输出模式,用于控制 LED。
16. C++ 兼容结束声明
#ifdef __cplusplus
}
#endif
如果是 C++ 编译环境,结束 extern "C" 声明。
17. 头文件保护宏结束
#endif
结束头文件保护宏,确保头文件内容只被包含一次。 总的来说,这个头文件为开发板的 GPIO 操作,特别是 LED 和按键的控制,提供了统一的接口和配置方式,方便在不同的开发板上进行应用开发。
以下是对 BOARDS_H 头文件中定义的函数和宏的功能详细说明:
函数 1. LED 操作函数
• bool bsp_board_led_state_get(uint32_t led_idx); ◦
功能:获取指定索引的 LED 当前状态。若 LED 处于点亮状态则返回 true,反之返回 false。 ◦ 参数:led_idx 是 LED 的索引,从 0 开始计数。
• void bsp_board_led_on(uint32_t led_idx); ◦
功能:点亮指定索引的 LED。 ◦ 参数:led_idx 是 LED 的索引,从 0 开始计数。
• void bsp_board_led_off(uint32_t led_idx); ◦
功能:熄灭指定索引的 LED。 ◦ 参数:led_idx 是 LED 的索引,从 0 开始计数。
• void bsp_board_led_invert(uint32_t led_idx); ◦
功能:反转指定索引 LED 的状态,即若 LED 点亮则熄灭,若熄灭则点亮。 ◦
参数:led_idx 是 LED 的索引,从 0 开始计数。
• void bsp_board_leds_off(void); ◦
功能:熄灭开发板上的所有 LED。
• void bsp_board_leds_on(void); ◦
功能:点亮开发板上的所有 LED。
2. 开发板初始化函数
• void bsp_board_init(uint32_t init_flags); ◦
功能:对开发板进行初始化操作,依据传入的 init_flags 参数来决定初始化哪些部分(如 LED 和按键)。
参数:init_flags 是初始化标志,可通过 BSP_INIT_NONE、BSP_INIT_LEDS、BSP_INIT_BUTTONS 等宏进行组合。
3. 引脚与 LED 索引转换函数
• uint32_t bsp_board_pin_to_led_idx(uint32_t pin_number); ◦
功能:把引脚编号转换为对应的 LED 索引。若传入的引脚编号无效,则返回 0xFFFFFFFF。 ◦
参数:pin_number 是引脚编号。
• uint32_t bsp_board_led_idx_to_pin(uint32_t led_idx); ◦
功能:将 LED 索引转换为对应的引脚编号。 ◦
参数:led_idx 是 LED 的索引,从 0 开始计数。
4. 按键操作函数
• bool bsp_board_button_state_get(uint32_t button_idx); ◦
功能:获取指定索引的按键当前状态。若按键被按下则返回 true,反之返回 false。 ◦
参数:button_idx 是按键的索引,从 0 开始计数。
• uint32_t bsp_board_pin_to_button_idx(uint32_t pin_number); ◦
功能:把引脚编号转换为对应的按键索引。若传入的引脚编号无效,则返回 0xFFFFFFFF。 ◦
参数:pin_number 是引脚编号。
• uint32_t bsp_board_button_idx_to_pin(uint32_t button_idx); ◦
功能:将按键索引转换为对应的引脚编号。 ◦
参数:button_idx 是按键的索引,从 0 开始计数。
宏 1. 开发板初始化标志宏
• #define BSP_INIT_NONE 0 ◦
功能:表示在初始化时不初始化 LED 和按键。
• #define BSP_INIT_LEDS (1 << 0) ◦
功能:表示在初始化时启用 LED。
• #define BSP_INIT_BUTTONS (1 << 1) ◦
功能:表示在初始化时启用按键。
2. 引脚掩码和端口宏
• #define PIN_MASK(_pin) (1u << (uint32_t)((_pin) & (~P0_PIN_NUM))) ◦
功能:根据传入的引脚编号 _pin 生成对应的引脚掩码,用于后续对引脚的操作。
• #define PIN_PORT(_pin) (((_pin) >= P0_PIN_NUM) ? NRF_P1 : NRF_GPIO) ◦
功能:依据传入的引脚编号 _pin 判断该引脚所属的端口,若引脚编号大于等于 P0_PIN_NUM 则属于 NRF_P1 端口,否则属于 NRF_GPIO 端口。
3. LED 和按键掩码宏
• #define LEDS_MASK (BSP_LED_0_MASK | BSP_LED_1_MASK | ... | BSP_LED_7_MASK) ◦ 功能:将所有 LED 的掩码进行按位或操作,得到所有 LED 的总掩码,用于对所有 LED 进行统一操作。
• #define BUTTONS_MASK (BSP_BUTTON_0_MASK | BSP_BUTTON_1_MASK | ... | BSP_BUTTON_7_MASK) ◦
功能:将所有按键的掩码进行按位或操作,得到所有按键的总掩码,用于对所有按键进行统一操作。
4. LED 控制宏
• #define LEDS_OFF(leds_mask) ◦
功能:熄灭由 leds_mask 指定的 LED。此宏仅支持 P0 端口,若 LED 位于其他端口则不适用。
• #define LEDS_ON(leds_mask) ◦
功能:点亮由 leds_mask 指定的 LED。此宏仅支持 P0 端口,若 LED 位于其他端口则不适用。
• #define LED_IS_ON(leds_mask) ◦
功能:判断由 leds_mask 指定的 LED 是否点亮。此宏仅支持 P0 端口,若 LED 位于其他端口则不适用。
• #define LEDS_INVERT(leds_mask) ◦
功能:反转由 leds_mask 指定的 LED 的状态。此宏仅支持 P0 端口,若 LED 位于其他端口则不适用。
• #define LEDS_CONFIGURE(leds_mask) ◦
功能:将由 leds_mask 指定的引脚配置为输出模式,用于控制 LED。此宏仅支持 P0 端口,若 LED 位于其他端口则不适用。
除了上述函数,BOARDS_H中还定义了哪些有用的功能?
除了前面提到的函数,BOARDS_H 头文件中还定义了很多其他有用的功能,主要通过宏定义和条件编译来实现,下面为你详细介绍:
1. 开发板特定头文件的包含
#if defined(BOARD_NRF6310)
#include "nrf6310.h"
#elif defined(BOARD_PCA10000)
#include "pca10000.h"
# ... 其他类似条件编译
#else
#error "Board is not defined"
#endif
• 功能:根据不同的 BOARD_* 宏定义,包含相应开发板的特定头文件。若未定义任何已知的开发板宏,会产生编译错误,提示用户需要定义开发板类型。这使得代码能够适配不同的硬件开发板,增强了代码的可移植性。
2. 扩展板头文件的包含 c #if defined (SHIELD_BSP_INC)
#include STRINGIFY(SHIELD_BSP_INC.h)
#endif
• 功能:如果定义了 SHIELD_BSP_INC 宏,就会包含对应的扩展板头文件。这为开发板添加扩展功能提供了便利,用户可以根据需要启用不同的扩展板。
3. 开发板初始化标志宏定义 c #define BSP_INIT_NONE 0
#define BSP_INIT_LEDS (1 << 0)
#define BSP_INIT_BUTTONS (1 << 1)
• 功能:这些宏用于表示开发板初始化时的不同标志。BSP_INIT_NONE 表示不初始化 LED 和按键;BSP_INIT_LEDS 表示初始化时启用 LED;BSP_INIT_BUTTONS 表示初始化时启用按键。可以通过位运算组合这些标志,灵活控制开发板的初始化过程。
4. LED 和按键编号宏定义 c #define BSP_BOARD_LED_0 0
#define BSP_BOARD_LED_1 1
# ... 其他 LED 编号宏
#define BSP_BOARD_BUTTON_0 0
#define BSP_BOARD_BUTTON_1 1
# ... 其他按键编号宏
• 功能:为开发板上的 LED 和按键定义了统一的编号,从 0 开始计数。这些编号可用于后续的 LED 和按键操作函数,提高了代码的可读性和可维护性。
5. 引脚掩码和端口宏定义 c #define PIN_MASK(_pin) (1u << (uint32_t)((_pin) & (~P0_PIN_NUM)))
#define PIN_PORT(_pin) (((_pin) >= P0_PIN_NUM) ? NRF_P1 : NRF_GPIO)
• PIN_MASK(_pin):根据传入的引脚编号 _pin 生成对应的引脚掩码。引脚掩码可用于位操作,方便对特定引脚进行控制。 • PIN_PORT(_pin):根据引脚编号判断引脚所属的端口。如果引脚编号大于等于 P0_PIN_NUM,则认为该引脚属于 NRF_P1 端口,否则属于 NRF_GPIO 端口。
6. 每个 LED 和按键的掩码和端口定义 c #ifdef BSP_LED_0
#define BSP_LED_0_MASK PIN_MASK(BSP_LED_0)
#define BSP_LED_0_PORT PIN_PORT(BSP_LED_0)
#else
#define BSP_LED_0_MASK 0
#define BSP_LED_0_PORT 0
#endif
# ... 其他 LED 类似
#ifdef BSP_BUTTON_0
#define BSP_BUTTON_0_MASK (1<<BSP_BUTTON_0)
#else
#define BSP_BUTTON_0_MASK 0
#endif
# ... 其他按键类似
• 功能:对于每个 LED 和按键,如果对应的宏(如 BSP_LED_0、BSP_BUTTON_0)被定义,则使用 PIN_MASK 和 PIN_PORT 宏生成对应的掩码和端口;否则,将掩码和端口都定义为 0。这为每个 LED 和按键提供了独立的掩码和端口信息,方便对单个元件进行操作。
7. 所有 LED 和按键的总掩码宏定义 c #define LEDS_MASK (BSP_LED_0_MASK | BSP_LED_1_MASK | ... | BSP_LED_7_MASK)
#define BUTTONS_MASK (BSP_BUTTON_0_MASK | BSP_BUTTON_1_MASK | ... | BSP_BUTTON_7_MASK)
• 功能:将所有 LED 和按键的掩码进行按位或操作,得到所有 LED 和按键的总掩码。这些总掩码可用于对所有 LED 或按键进行统一操作,例如同时点亮所有 LED 或检测所有按键的状态。
8. LED 控制宏定义 c #define LEDS_OFF(leds_mask) ...
#define LEDS_ON(leds_mask) ...
#define LED_IS_ON(leds_mask) ...
#define LEDS_INVERT(leds_mask) ...
#define LEDS_CONFIGURE(leds_mask) ...
• LEDS_OFF(leds_mask):熄灭由 leds_mask 指定的 LED。 • LEDS_ON(leds_mask):点亮由 leds_mask 指定的 LED。 • LED_IS_ON(leds_mask):判断由 leds_mask 指定的 LED 是否点亮。 • LEDS_INVERT(leds_mask):反转由 leds_mask 指定的 LED 的状态。 • LEDS_CONFIGURE(leds_mask):将由 leds_mask 指定的引脚配置为输出模式,用于控制 LED。 这些宏提供了便捷的方式来控制 LED 的状态,并且使用掩码进行操作,使得可以同时控制多个 LED。需要注意的是,这些宏仅支持 P0 端口,如果 LED 位于其他端口,则不适用。
相关文章:
8、nRF52xx蓝牙学习(boards.h文件学习)
boards.h文件的代码如下: #ifndef BOARDS_H #define BOARDS_H#include "nrf_gpio.h" #include "nordic_common.h"#if defined(BOARD_NRF6310)#include "nrf6310.h" #elif defined(BOARD_PCA10000)#include "pca10000.h" #…...
声明文件.d.ts
在 TypeScript 中,.d.ts 文件是类型声明文件(Declaration Files),用于描述 JavaScript 库或模块的类型信息,但不包含具体实现。它们帮助 TypeScript 编译器进行类型检查,同时保持与纯 JavaScript 的兼容性。…...
java整合socket通信全流程
前言 大家好,由于工作上业务的需要,在java项目中引入了socket通信,特此记录一下,用以备份,本文章中的socket通信实现了,服务端与客户端的双向通讯,以及二者之间的心跳通信,服务端重启之后,客户端的自动重连功能。 原理 Socket通信是计算机网络中常用的一种通信机制…...
2025年常见渗透测试面试题-sql(题目+回答)
网络安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 SQLi 一、发现test.jsp?cid150 注入点的5种WebShell获取思路 1. 文件写入攻击 2. 日志文件劫持 3.…...
【RabbitMQ】队列模型
1.概述 RabbitMQ作为消息队列,有6种队列模型,分别在不同的场景进行使用,分别是Hello World,Work queues,Publish/Subscribe,Routing,Topics,RPC。 下面就分别对几个模型进行讲述。…...
StarRocks 助力首汽约车精细化运营
作者:任智红,首汽约车大数据负责人 更多交流,联系我们:https://wx.focussend.com/weComLink/mobileQrCodeLink/334%201%202/ffbe5 导读: 本文整理自首汽约车大数据负责人任智红在 StarRocks 年度峰会上的演讲…...
Springboot--Kafka客户端参数关键参数的调整方法
调整 Kafka 客户端参数需结合生产者、消费者和 Broker 的配置,以实现性能优化、可靠性保障或资源限制。以下是关键参数的调整方法和注意事项: 一、生产者参数调整 max.request.size 作用:限制单个请求的最大字节数(包括消…...
C++ 基类的虚析构函数与派生的析构函数关系
1、基类非虚析构函数,派生类析构函数,基类指针指向派生类 class Base { public:~Base() { // 非虚析构函数std::cout << "Base class destructor" << std::endl;} };class Derived : public Base { public:~Derived() { // 派生…...
解决Spring Boot上传默认限制文件大小和完善超限异常(若依框架)
文章目录 报错信息问题分析技术原理解决方法1️⃣调整 Spring Boot 配置文件2️⃣检查内嵌 Tomcat 配置(可选)3️⃣ 代码自定义配置(覆盖配置文件) 全局异常处理代码 报错信息 org.springframework.web.multipart.MaxUploadSizeE…...
AI平台如何实现推理?数算岛是一个开源的AI平台(主要用于管理和调度分布式AI训练和推理任务。)
数算岛是一个开源的AI平台,主要用于管理和调度分布式AI训练和推理任务。它基于Kubernetes构建,支持多种深度学习框架(如TensorFlow、PyTorch等)。以下是数算岛实现模型推理的核心原理、架构及具体实现步骤: 一、数算岛…...
痉挛性斜颈康复助力:饮食调养指南
痉挛性斜颈患者除了积极治疗,合理饮食也能辅助缓解症状,提升生活质量。其健康饮食可从以下方面着手: 高蛋白质食物助力肌肉修复 痉挛性斜颈会导致颈部肌肉异常收缩,消耗较多能量,蛋白质有助于肌肉的修复与维持。日常可…...
mysql镜像创建docker容器,及其可能遇到的问题
前提,已经弄好基本的docker服务了。 一、基本流程 1、目录准备 我自己的资料喜欢放在 /data 目录下,所以老规矩: 先进入 /data 目录: cd /data 创建 mysql 目录并进入: mkdir mysql cd mysql 2、镜像查找 docke…...
Dify平台
目录 安装介绍Dify:开源大语言模型应用开发平台核心功能应用场景架构设计优势 安装 基于RDS PostgreSQL与Dify平台构建AI应用 使用RDS PostgreSQL打造RAG应用 介绍 Dify是一个开源的大语言模型(LLM)应用开发平台,融合了后端即…...
荣耀90 GT信息
外观设计 屏幕:采用 6.7 英寸 AMOLED 荣耀绿洲护眼屏,超窄边框设计,其上边框 1.6mm,左右黑边 1.25mm,屏占较高,带来更广阔的视觉体验。屏幕还支持 120Hz 自由刷新率,可根据使用场景自动切换刷新…...
JavaEE——线程的状态
目录 前言1. NEW2. TERMINATED3. RUNNABLE4. 三种阻塞状态总结 前言 本篇文章来讲解线程的几种状态。在Java中,线程的状态是一个枚举类型,Thread.State。其中一共分为了六个状态。分别为:NEW,RUNNABLE,BLOCKED,WAITING,TIMED_WAITING, TERMI…...
spring mvc 在拦截器、控制器和视图中获取和使用国际化区域信息的完整示例
在拦截器、控制器和视图中获取和使用国际化区域信息的完整示例 1. 核心组件代码示例 1.1 配置类(Spring Boot) import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.spring…...
1021 Deepest Root
1021 Deepest Root 分数 25 全屏浏览 切换布局 作者 CHEN, Yue 单位 浙江大学 A graph which is connected and acyclic can be considered a tree. The height of the tree depends on the selected root. Now you are supposed to find the root that results in a highest…...
RuntimeError: Error(s) in loading state_dict for ChartParser
一 bug错误 最近使用千问大模型有一个bug,报错信息如下 raise RuntimeError(Error(s) in loading state_dict for {}:\n\t{}.format( RuntimeError: Error(s) in loading state_dict for ChartParser:Unexpected key(s) in state_dict: "pretrained_model.em…...
WHAT - React 惰性初始化
目录 在 React 中如何使用惰性初始化示例:常规初始化 vs. 惰性初始化1. 常规初始化2. 惰性初始化 为什么使用惰性初始化示例:从 localStorage 获取值并使用惰性初始化总结 在 React 中,惰性初始化(Lazy Initialization)…...
2025 年安徽交安安全员考试:利用记忆宫殿强化记忆
安徽考生在面对交安安全员考试繁杂的知识点时,记忆宫殿是强大的记忆工具。选择一个熟悉且空间结构清晰的场所作为记忆宫殿,如自己居住的房屋。将房屋的不同区域,如客厅、卧室、厨房等,分别对应不同知识板块,像客厅对应…...
安全编码课程 实验6 整数安全
实验项目 实现安全计数器:实现 Counter 结构,确保计数范围为 0~100。 实验要求: 1、使用 struct 封装计数值value; 2、计数器初值为 0; 3、increment() 方法增加计数,但不能超过 100; 4、decrem…...
解决上传PDF、视频、音频等格式文件到FTP站点时报错“将文件复制到FTP服务器时发生错误。请检查是否有权限将文件放到该服务器上”问题
一、问题描述 可以将文本文件(.txt格式),图像文件(.jpg、.png等格式)上传到我们的FTP服务器上;但是上传一些PDF文件、视频等文件时就会报错“ 将文件复制到FTP服务器时发生错误。请检查是否有权限将文件放到该服务器上。 详细信息: 200 Type set to l. 227 Entering Pas…...
【Linux操作系统】:信号
Linux操作系统下的信号 一、引言 首先我们可以简单理解一下信号的概念,信号,顾名思义,就是我们操作系统发送给进程的消息。举个简单的例子,我们在写C/C程序的时候,当执行a / 0类似的操作的时候,程序直接就挂…...
经典频域分析法(Bode图、Nyquist判据) —— 理论、案例与交互式 GUI 实现
目录 经典频域分析法(Bode图、Nyquist判据) —— 理论、案例与交互式 GUI 实现一、引言二、经典频域分析方法的基本原理2.1 Bode 图分析2.2 Nyquist 判据三、数学建模与公式推导3.1 一阶系统的频域响应3.2 多极系统的 Bode 图绘制3.3 Nyquist 判据的数学描述四、经典频域分析…...
使用scoop一键下载jdk和实现版本切换
安装 在 PowerShell 中输入下面内容,保证允许本地脚本的执行: set-executionpolicy remotesigned -scope currentuser然后执行下面的命令安装 Scoop: iwr -useb get.scoop.sh | iex国内用户可以使用镜像源安装:powershell iwr -us…...
对状态模式的理解
对状态模式的理解 一、场景二、不采用状态模式1、代码2、缺点 三、采用状态模式1、代码1.1 状态类1.2 上下文(这里指:媒体播放器)1.3 客户端 2、优点 一、场景 同一个东西(例如:媒体播放器),有一…...
LangChain与LangGraph内置回调函数
LangChain与LangGraph回调函数指南 回调函数概述 LangChain和LangGraph共享同一套回调系统,通过BaseCallbackHandler类提供了丰富的生命周期钩子,可用于监控、调试和跟踪AI应用的执行过程。 回调函数流程图 #mermaid-svg-EsqgET3Cjlj0l0Z1 {font-fami…...
字符串哈希算法详解:原理、实现与应用
字符串哈希是一种高效处理字符串匹配和比较的技术,它通过将字符串映射为一个唯一的数值(哈希值),从而在O(1)时间内完成子串的比较。本文将结合代码实现,详细讲解前缀哈希法的工作原理,并通过流程图逐步解析…...
vue2(webpack)集成electron和 electron 打包
前言 之前发过一篇vue集成electron的文章,但是用vue3vite实现的,在vue2webpack工程可能不适用,所以这篇文章就主要介绍vue2webpack集成electron方法 创建项目 vue create vue-electron-demo目录架构 vue-electron-demo/ ├── src/ …...
C++内存管理优化实战:提升应用性能与效率
🧑 博主简介:CSDN博客专家、CSDN平台优质创作者,高级开发工程师,数学专业,拥有高级工程师证书;擅长C/C、C#等开发语言,熟悉Java常用开发技术,能熟练应用常用数据库SQL server,Oracle…...
