【DIY飞控板PX4移植】LED模块的PCB硬件设计和PX4驱动配置

大部分PX4的飞控板都有三个LED,分别是红色、绿色、蓝色。

飞控板的配置文件夹结构

飞控板的配置文件夹结构为下列所示。

YanQi
├─extras
|  └─UCAS_YanQi_bootloader.bin
├─init
|  ├─rc.board_defaults
|  └─rc.board_sensors
├─nuttx-config
|  ├─bootloader
|  |  └─defconfig
|  ├─include
|  |  ├─board.h
|  |  └─board_dma_map.h
|  ├─nsh
|  |  └─defconfig
|  ├─scripts
|  |  ├─bootloader_script.ld
|  |  └─script.ld
|  ├─src
|  └─Kconfig
├─src
|  ├─board_config.h
|  ├─bootloader_main.c
|  ├─CMakeLists.txt
|  ├─hw_config.h
|  ├─i2c.cpp
|  ├─init.c
|  ├─...
|  └─usb.c
├─bootloader.px4board
├─default.px4board
└─firmware.prototype

nuttx-config/include/board.h文件

如果CONFIG_ARCH_LEDS标识符被定义,那么LED的控制权在NuttX操作系统手中,如果标识符没有被定义,则用户(PX4程序)可以对LED进行控制。

如果CONFIG_ARCH_LEDS标识符没有被定义,LED号的定义在下列代码。

/* LED index values for use with board_userled() */

#define BOARD_LED1        0
#define BOARD_LED2        1
#define BOARD_LED3        2
#define BOARD_NLEDS       3

#define BOARD_LED_RED     BOARD_LED1
#define BOARD_LED_GREEN   BOARD_LED2
#define BOARD_LED_BLUE    BOARD_LED3

/* LED bits for use with board_userled_all() */

#define BOARD_LED1_BIT    (1 << BOARD_LED1)
#define BOARD_LED2_BIT    (1 << BOARD_LED2)
#define BOARD_LED3_BIT    (1 << BOARD_LED3)

如果CONFIG_ARCH_LEDS标识符被定义,LED显示模式对应操作系统的状态的表格如下。

/* If CONFIG_ARCH_LEDS is defined, the usage by the board port is defined in
 * include/board.h and src/stm32_leds.c. The LEDs are used to encode OS-related
 * events as follows:
 *
 *
 *   SYMBOL                     Meaning                      LED state
 *                                                        Red   Green Blue
 *   ----------------------  --------------------------  ------ ------ ----*/

#define LED_STARTED        0 /* NuttX has been started   OFF    OFF   OFF  */
#define LED_HEAPALLOCATE   1 /* Heap has been allocated  OFF    OFF   ON   */
#define LED_IRQSENABLED    2 /* Interrupts enabled       OFF    ON    OFF  */
#define LED_STACKCREATED   3 /* Idle stack created       OFF    ON    ON   */
#define LED_INIRQ          4 /* In an interrupt          N/C    N/C   GLOW */
#define LED_SIGNAL         5 /* In a signal handler      N/C    GLOW  N/C  */
#define LED_ASSERTION      6 /* An assertion failed      GLOW   N/C   GLOW */
#define LED_PANIC          7 /* The system has crashed   Blink  OFF   N/C  */
#define LED_IDLE           8 /* MCU is is sleep mode     ON     OFF   OFF  */

/* Thus if the Green LED is statically on, NuttX has successfully booted and
 * is, apparently, running normally.  If the Red LED is flashing at
 * approximately 2Hz, then a fatal error has been detected and the system
 * has halted.
 */

src/board_config.h文件

Trace功能,即ITM,(英文:Instrumentation Trace Macrocell,指令跟踪宏单元),是一种针对MCU进行跟踪调试的新方法,与打断点(Breakpoint)不同,ITM方法不需要暂停程序运行,可以在程序全速运行的过程中实时输出变量的数值以便观察。

该Trace功能有五个引脚,TRACECLK、TRACED0、TRACED1、TRACED2和TRACED3,需要占用引脚PE2、PE3、PE4、PE5、PC12,这与三个LED的GPIO引脚和UART5_TX_TELEM2的GPIO引脚产生冲突,所以Trace功能和这两个功能只能选择其一,代码如下。

/* Trace Clock and D0-D3 are available on the trace connector
 *
 * TRACECLK PE2  - Dedicated       - Trace Connector Pin 1
 * TRACED0  PE3  - nLED_RED        - Trace Connector Pin 3
 * TRACED1  PE4  - nLED_GREEN      - Trace Connector Pin 5
 * TRACED2  PE5  - nLED_BLUE       - Trace Connector Pin 7
 * TRACED3  PC12 - UART5_TX_TELEM2 - Trace Connector Pin 8

 */
#undef TRACE_PINS

/* LEDs are driven with push open drain to support Anode to 5V or 3.3V or used as TRACE0-2 */

#if !defined(TRACE_PINS)
#  define GPIO_nLED_RED        /* PE3 */  (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|GPIO_OUTPUT_SET|GPIO_PORTE|GPIO_PIN3)
#  define GPIO_nLED_GREEN      /* PE4 */  (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|GPIO_OUTPUT_SET|GPIO_PORTE|GPIO_PIN4)
#  define GPIO_nLED_BLUE       /* PE5 */  (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|GPIO_OUTPUT_SET|GPIO_PORTE|GPIO_PIN5)

#  define BOARD_HAS_CONTROL_STATUS_LEDS      1
#  define BOARD_OVERLOAD_LED     LED_RED
#  define BOARD_ARMED_STATE_LED  LED_BLUE

#else
#  if defined(CONFIG_STM32H7_UART5) && (GPIO_UART5_TX == GPIO_UART5_TX_3)
#    error Need to disable CONFIG_STM32H7_UART5 for Trace 3 (Retarget to CAN2 if need be)
#  endif
#endif

如果需要修改LED对应的GPIO,可以在这里进行修改,这里选择Push-Pull推挽输出,也可以选择Open-Drain开漏输出。

在这里插入图片描述

推挽输出可以输出高电平,也可以输出低电平,支持连接LED阳极、阴极,支持共阳、共阴的三色LED。

开漏输出只能输出低电平,只支持连接LED阴极,只支持共阳的三色LED。

在这里插入图片描述

LED共阴极是指LED灯中的二极管的阴极有一个共同的接点,并且该接点连接在GND端,即处于低电平状态。

LED共阳极是指LED灯中的二极管的阳极有一个共同的接点,并且该接点连接在VCC端,即处于高电平状态。

#  define GPIO_nLED_RED        /* PE3 */  (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|GPIO_OUTPUT_SET|GPIO_PORTE|GPIO_PIN3)
#  define GPIO_nLED_GREEN      /* PE4 */  (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|GPIO_OUTPUT_SET|GPIO_PORTE|GPIO_PIN4)
#  define GPIO_nLED_BLUE       /* PE5 */  (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|GPIO_OUTPUT_SET|GPIO_PORTE|GPIO_PIN5)

设置了红色LED为过载状态指示灯,蓝色LED为飞机解锁状态指示灯。

#  define BOARD_HAS_CONTROL_STATUS_LEDS      1
#  define BOARD_OVERLOAD_LED     LED_RED
#  define BOARD_ARMED_STATE_LED  LED_BLUE

src/hw_config.h文件

设置了蓝色LED为工作状态指示灯,绿色LED为BootLoader状态指示灯。

这里配置的是运行BootLoader时LED的定义,输出低电平是打开LED,输出高电平是关闭LED。

#define BOARD_PIN_LED_ACTIVITY         GPIO_nLED_BLUE // BLUE
#define BOARD_PIN_LED_BOOTLOADER       GPIO_nLED_GREEN // GREEN
#define BOARD_LED_ON                   0
#define BOARD_LED_OFF                  1

src/led.c文件

这个文件是LED的驱动文件。

声明了LED初始化、打开、关闭、翻转等函数的函数头。

__BEGIN_DECLS
extern void led_init(void);
extern void led_on(int led);
extern void led_off(int led);
extern void led_toggle(int led);
__END_DECLS

CONFIG_ARCH_LEDS标识符是否被定义两种情况下的LED号的编号。

#ifdef CONFIG_ARCH_LEDS
static bool nuttx_owns_leds = true;
//                                B  R  S  G
//                                0  1  2  3
static const uint8_t xlatpx4[] = {1, 2, 4, 0};
#  define xlat(p) xlatpx4[(p)]
static uint32_t g_ledmap[] = {
	GPIO_nLED_GREEN,   // Indexed by BOARD_LED_GREEN
	GPIO_nLED_BLUE,    // Indexed by BOARD_LED_BLUE
	GPIO_nLED_RED,     // Indexed by BOARD_LED_RED
	GPIO_nSAFETY_SWITCH_LED_OUT,  // Indexed by LED_SAFETY by xlatpx4
};

#else

#  define xlat(p) (p)
static uint32_t g_ledmap[] = {
	GPIO_nLED_BLUE,                     // Indexed by LED_BLUE
	GPIO_nLED_RED,                      // Indexed by LED_RED, LED_AMBER
	0,                                  // Indexed by LED_SAFETY (defaulted to an input)
	GPIO_nLED_GREEN,                    // Indexed by LED_GREEN
};

#endif

LED初始化、打开、关闭、翻转等函数的函数体。

__EXPORT void led_init(void)
{
	for (size_t l = 0; l < (sizeof(g_ledmap) / sizeof(g_ledmap[0])); l++) {
		if (g_ledmap[l] != 0) {
			stm32_configgpio(g_ledmap[l]);
		}
	}
}

static void phy_set_led(int led, bool state)
{
	/* Drive Low to switch on */

	if (g_ledmap[led] != 0) {
		stm32_gpiowrite(g_ledmap[led], !state);
	}
}

static bool phy_get_led(int led)
{
	/* If Low it is on */
	if (g_ledmap[led] != 0) {
		return !stm32_gpioread(g_ledmap[led]);
	}

	return false;
}

__EXPORT void led_on(int led)
{
	phy_set_led(xlat(led), true);
}

__EXPORT void led_off(int led)
{
	phy_set_led(xlat(led), false);
}

__EXPORT void led_toggle(int led)
{
	phy_set_led(xlat(led), !phy_get_led(xlat(led)));
}

这里默认输出低电平是打开LED,led_on()函数中调用phy_set_led(xlat(led), true)函数,则在phy_set_led()函数中state为true,命令stm32_gpiowrite(g_ledmap[led], !state)即把GPIO输出低电平。

同时获取LED状态,默认低电平时LED是打开状态,phy_get_led()函数中调用stm32_gpioread(g_ledmap[led])函数,低电平时返回值是0,则return !stm32_gpioread(g_ledmap[led])返回值是1,即LED为打开状态。

src/init.c文件

board_app_initialize()函数中有关于LED的代码,board_app_initialize()函数中调用了初始化LED状态的代码,包括点亮绿色LED表示系统已经上电等。

/* initial LED state */
	drv_led_start();
	led_off(LED_RED);
	led_on(LED_GREEN); // Indicate Power.
	led_off(LED_BLUE);

	if (board_hardfault_init(2, true) != 0) {
		led_on(LED_RED);
	}
  • 6
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

后厂村路练习生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值