rt-thread:_002STM32F429IGT BSP的PIN设备应用

基于RT-THREAD STM32F429IGT6 BSP的PIN设备应用


硬件平台:野火STM32挑战者 MCU:STM32F429IGT6
开发工具:
  1. MDK Version:5.25
  2. VSCode
  3. env
  4. STM32CubeMX Version:5.2.1
  5. rt-thread源码 Version:4.0.1

工具获取

  • MDK获取链接
  • VSCode获取链接
  • env工具获取链接
  • STM32CubeMX获取链接
  • RT-Thread源码获取链接

说明:
这次先介绍下PIN设备的操作方法,然后一步一步完成PIN设备的BSP过程。

该BSP主要实现使用PIN设备管理接口管理按键和led。

PIN设备的操作方法

应用程序通过RT-Thred提供的pin设备管理接口来操作GPIO,函数接口如下表:

表1.pin设备管理接口API
方法名称 方法描述
rt_pin_mode() 设置引脚模式
rt_pin_write() 设置引脚电平
rt_pin_read() 读取引脚电平
rt_pin_attach_irq() 绑定引脚中断回调函数
rt_pin_detach_irq() 脱离引脚中断回调函数
rt_pin_irq_enable() 使能引脚中断

1. 设置引脚模式

在使用引脚之前需要先设定引脚的工作模式,通过下面函数完成:

void rt_pin_mode(rt_base_t pin, rt_base_t mode);
表2.rt_pin_mode()的输入参数与返回值
参数 描述
pin 引脚编号
mode 引脚工作模式
返回 描述

1.1 引脚编号获取

引脚编号是由rt-thread的pin设备管理驱动程序定义的,并不是芯片的引脚号。有2种方式可以获取引脚编号:使用宏定义GET_PIN(port, pin)或者查看PIN 驱动文件drv_gpio.c

使用宏定义比较方便。比如要获取led的引脚编号,硬件图如图1.led原理图
rt-thread:_002STM32F429IGT BSP的PIN设备应用_第1张图片

图1.led原理图

代码如下:

#define     LEDR_PIN    GET_PIN(H, 10)
#define     LEDG_PIN    GET_PIN(H, 11)
#define     LEDB_PIN    GET_PIN(H, 12)

再比如要获取key的引脚编号,硬件图如图2.key原理图
rt-thread:_002STM32F429IGT BSP的PIN设备应用_第2张图片

图2.key原理图

代码如下:

#define KEY1_PIN    GET_PIN(H, 10)
#define KEY2_PIN    GET_PIN(C, 13)

1.2 设置引脚模式

RT-Thread目前支持的模式有下面5种:

#define PIN_MODE_OUTPUT         0x00    /*推挽输出*/
#define PIN_MODE_INPUT          0x01    /*浮空输入*/
#define PIN_MODE_INPUT_PULLUP   0x02    /*上拉输入*/
#define PIN_MODE_INPUT_PULLDOWN 0x03    /*下拉输出*/
#define PIN_MODE_OUTPUT_OD      0x04    /*开漏输出*/

2. 设置引脚电平

设置引脚电平使用如下函数完成:

void rt_pin_write(rt_base_t pin, rt_base_t value);
表3.rt_pin_write()的输入参数与返回值
参数 描述
pin 引脚编号
value 电平逻辑值:PIN_LOW (低电平),PIN_HIGH(高电平)
返回 描述

3. 读取引脚电平

读取引脚电平使用如下函数完成:

int rt_pin_read(rt_base_t pin);
表4.rt_pin_read()的输入参数与返回值
参数 描述
pin 引脚编号
value 电平逻辑值:PIN_LOW (低电平),PIN_HIGH(高电平)
返回 描述
PIN_LOW 低电平
PIN_HIGH 高电平

4. 绑定引脚中断回调函数

如果需要使用引脚的中断功能,那么需要使用如下函数将某个引脚设置为某种中断触发模式,并且绑定中断触发回调函数,当中段发生时,执行回调函数:

rt_err_t rt_pin_attach_irq(rt_int32_t pin, rt_uint32_t mode,
                             void (*hdr)(void *args), void  *args);
表5.rt_pin_attach_irq()的输入参数与返回值
参数 描述
pin 引脚编号
mode 中断触发模式
hdr 中断回调函数,用户自己定义
args 总段回调函数的参数,无时为空:RT_NULL
返回 描述
RT_EOK 绑定成功
错误码 绑定失败

4.1 中断触发模式

中断触发有以下5种模式:

#define PIN_IRQ_MODE_RISING             0x00    /*上升沿触发*/
#define PIN_IRQ_MODE_FALLING            0x01    /*下降沿触发*/
#define PIN_IRQ_MODE_RISING_FALLING     0x02    /*上升沿和下降沿都触发*/
#define PIN_IRQ_MODE_HIGH_LEVEL         0x03    /*高电平触发*/
#define PIN_IRQ_MODE_LOW_LEVEL          0x04    /*低电平触发*/

5. 使能引脚中断

绑定好中断出发回调函数以后,就可以通过下面的函数使能引脚中断:

rt_err_t rt_pin_irq_enable(rt_base_t pin, rt_uint32_t enabled);
表6.rt_pin_irq_enable()的输入参数与返回值
参数 描述
pin 引脚编号
enabled 使能状态:PIN_IRQ_ENABLE(开启),PIN_IRQ_DISABLE(关闭)
返回 描述
RT_EOK 使能成功
错误码 使能失败

6. 脱离引脚中断回调函数

绑定好中断出发回调函数以后,如果需要不再执行中断触发回调函数,可以使用如下函数脱离绑定的回调函数:

rt_err_t rt_pin_detach_irq(rt_int32_t pin);
表7.rt_pin_detach_irq()的输入参数与返回值
参数 描述
pin 引脚编号
返回 描述
RT_EOK 脱离成功
错误码 脱离失败

注意:脱离中断回调函数后,中断并没有关掉,只是不再执行被脱离的回调函数,可以再次绑定该回调函数,当然也可以不绑定该对调函数,去绑定其他回调函数也是可以的

PIN设备BSP

有了前面的rt-thread:_001STM32F429IGT BSP前期准备,那么该bsp无非就是再次模版基础上加入bsp的应用程序而已,比较方便。

一、led灯bsp

实现红、绿、蓝三个led灯的轮流亮灭。硬件图请看图1

  • 第一步:

首先新建两个文件bsp_led.cbsp_led.h;然后把bsp_led.c放入bsp_src文件夹里,bsp_led.h放入bsp_inc文件夹里。同时在
main.h里面添加bsp_led的头文件,如下:

#include "bsp_inc/bsp_led.h"

其中bsp_led.h里面的代码如下:

#ifndef __BSP_LED_H
#define __BSP_LED_H

#include "applications/main.h"

/* 定义LED_R、LED_G、LED_B、 的引脚 */
#define LEDR_PIN    GET_PIN(H, 10)
#define LEDG_PIN    GET_PIN(H, 11)
#define LEDB_PIN    GET_PIN(H, 12)

/* 定义蜂鸣器的引脚 */
#define SPEEK_PIN   GET_PIN(I, 11)

/* 声明bsp_led线程函数 */
static void bsp_led_thread_entry(void *parameter);

#endif

其中bsp_led.c里面的代码如下:

#include "bsp_led.h"

/***************************************************************
*   函数:  static void bsp_led_sample(int argc, char *argv[])
*   参数:  int argc, char *argv[]
*   返回值:无  
*   功能:  完成相关led对应引脚的初始化设置,创建并启动bsp_led线程
*****************************************************************/
static void bsp_led_sample(int argc, char *argv[])
{
    /* 设置led引脚的模式 */
    rt_pin_mode(LEDR_PIN, PIN_MODE_OUTPUT);
    rt_pin_mode(LEDG_PIN, PIN_MODE_OUTPUT);
    rt_pin_mode(LEDB_PIN, PIN_MODE_OUTPUT);

    /* 设置led引脚的初始输出电平 */
    rt_pin_write(LEDR_PIN, PIN_HIGH);
    rt_pin_write(LEDG_PIN, PIN_HIGH);
    rt_pin_write(LEDB_PIN, PIN_HIGH);

    static rt_thread_t bsp_led_tid = RT_NULL;   /* 定义bsp_led线程的控制块 */

    /* 创建bsp_led线程 */
    bsp_led_tid = rt_thread_create("bsp_led_tid", bsp_led_thread_entry,
                                    RT_NULL, 513, BSP_LED_PRIORITY, 10);

    /* 启动bsp_led线程 */
    if (bsp_led_tid != RT_NULL)
    {
        rt_thread_startup(bsp_led_tid); 
    }   
}

/* 导出bsp_led_sample至FinSH终端 */
MSH_CMD_EXPORT(bsp_led_sample, bsp led sample);

/***************************************************************
*   函数:  static void bsp_led_thread_entry(void *parameter)
*   参数:  空指针
*   返回值:无  
*   功能:  实现led流水运行
*****************************************************************/
static void bsp_led_thread_entry(void *parameter)
{
    while (1)
    {
        /* LED_R 2秒周期运行 */
        rt_pin_write(LEDR_PIN, PIN_LOW);
        rt_thread_mdelay(1000);
        rt_pin_write(LEDR_PIN, PIN_HIGH);
        rt_thread_mdelay(1000);

        /* LED_G 2秒周期运行 */
        rt_pin_write(LEDG_PIN, PIN_LOW);
        rt_thread_mdelay(1000);
        rt_pin_write(LEDG_PIN, PIN_HIGH);
        rt_thread_mdelay(1000);

        /* LED_B 2秒周期运行 */
        rt_pin_write(LEDB_PIN, PIN_LOW);
        rt_thread_mdelay(1000);
        rt_pin_write(LEDB_PIN, PIN_HIGH);
        rt_thread_mdelay(1000);
    }  
}
  • 第二步:

打开stm32f429-hlg-v1.0\board下面的Kconfig文件,在该文件的 menu "BSP module"配置模块下面添加如下图内容:rt-thread:_002STM32F429IGT BSP的PIN设备应用_第3张图片

图3.Kconfig 添加 RT_USING_LED 宏配置

有了该宏,那么在env工具里面就可以很方便的开启或者关闭该宏,如果开启该宏,则在rtconfig.h里面就会生成该宏。

  • 第三步:

打开stm32f429-hlg-v1.0\applications下面的SConscript编译链接脚本文件,在里面添加如下图内容:
rt-thread:_002STM32F429IGT BSP的PIN设备应用_第4张图片

图4.SConscript 添加源文件编译链接宏 RT_USING_LED
  • 第四步:

env里输入menuconfig打开工程配置,开启Enable led,如下图:
rt-thread:_002STM32F429IGT BSP的PIN设备应用_第5张图片

图5.开启 led

然后一直按Esc至保存界面,选Yes保存退出。

  • 第五步:

env输入scons --target=mdk5重新生成keil5工程;输入scons --target=mdk4重新生成keil4工程;输入scons --target=iar重新生成iar工程;输入scons --target=vsc更新VSCode头文件路径。

  • 第六步:

打开keil5工程,然后就可以看到现在的工程目录结构如下图:
rt-thread:_002STM32F429IGT BSP的PIN设备应用_第6张图片

图6.keil 工程目录结构

然后编译之后看看是否有错误或者警告。只要前面步骤没有出错,这里肯定不会要问题。

  • 第七步:

下载程序到开发板。然后打开终端工具。在中断输入例程的导出命令bsp_led_sample,便可以看到开发板led灯三种颜色轮流亮灭。再输入查看线程指令list_thread,便可以看到bsp_led线程的运行基本信息,如下图:
rt-thread:_002STM32F429IGT BSP的PIN设备应用_第7张图片

图7.FinSH 终端

这样一个led灯的bsp就彻底完成了。

二、key的bsp

按键的bsp过程基本上与led的bsp过程一样。在此做一些扩展,加入pin中断操作,关于pin设备的中断管理API请看本文前面的介绍。

完成利用按键的外部中断来操作led灯,按下key1灯亮,按下key2灯灭。硬件图请看图2

  • 第一步:

首先新建两个文件bsp_key.cbsp_key.h;然后把bsp_key.c放入bsp_src文件夹里,bsp_key.h放入bsp_inc文件夹里。同时在
main.h里面添加bsp_key的头文件,如下:

#include "bsp_inc/bsp_key.h"

其中bsp_key.h里面的代码如下:

#ifndef     __BSP_KEY_H
#define     __BSP_KEY_H

#include "applications/main.h"

/* 定义KEY1和KEY2 的引脚 */
#define     KEY1_PIN        GET_PIN(A, 0)
#define     KEY2_PIN        GET_PIN(C, 13)

/* 定义bsp_key线程的优先级 */
#define BSP_KEY_PRIORITY    5

/* 声明函数 */
void ledr_on(void *parameter);
void ledr_off(void *parameter);
static void key_led_entry(void *paraemter);
static void key_led_sample(int argc, char *argv[]);

#endif

其中bsp_led.c里面的代码如下:

#include "bsp_key.h"

/***************************************************************
*   函数:  void bsp_ledr_on(void *parameter)
*   参数:  空指针
*   返回值:无  
*   功能:  按键中断回调函数,实现ledr亮
*****************************************************************/
void bsp_ledr_on(void *parameter)
{
    rt_kprintf("key1 press down! led on!\n");   /*按下key1按键打印信息*/
    rt_pin_write(LEDR_PIN, PIN_LOW);            /*按下key1灯亮*/
}

/***************************************************************
*   函数:  void bsp_ledr_off(void *parameter)
*   参数:  空指针
*   返回值:无  
*   功能:  按键中断回调函数,实现ledr灭
*****************************************************************/
void bsp_ledr_off(void *parameter)
{
    rt_kprintf("key2 press down! led off!\n");   /*按下key2按键打印信息*/
    rt_pin_write(LEDR_PIN, PIN_HIGH);            /*按下key2灯灭*/
}

/***************************************************************
*   函数:  static void bsp_key_entry(void *paraemter)
*   参数:  空指针
*   返回值:无  
*   功能:  按键线程,实现按键中断回调函数绑定,以及使能按键中断
*****************************************************************/
static void bsp_key_entry(void *paraemter)
{
    while (1)
    {
        rt_thread_mdelay(10);

        /*确定按键中断触发模式以及绑定中断回调函数*/
        rt_pin_attach_irq(KEY1_PIN, PIN_IRQ_MODE_RISING, bsp_ledr_on, RT_NULL);
        rt_pin_attach_irq(KEY2_PIN, PIN_IRQ_MODE_RISING, bsp_ledr_off, RT_NULL);

        /*确定按键中断触发模式以及绑定中断回调函数*/
        rt_pin_irq_enable(KEY1_PIN, PIN_IRQ_ENABLE);
        rt_pin_irq_enable(KEY2_PIN, PIN_IRQ_ENABLE);
    }
    
}

/***************************************************************
*   函数:  static void bsp_led_sample(int argc, char *argv[])
*   参数:  int argc, char *argv[]
*   返回值:无  
*   功能:  完成相关led对应引脚的初始化设置,创建并启动bsp_led线程
*****************************************************************/
static void bsp_key_sample(int argc, char *argv[])
{
    /*定义按键线程设备块*/
    static rt_thread_t key_tid = RT_NULL;   

    /*设置按键以及led对应引脚的输入、输出模式*/
    rt_pin_mode(KEY1_PIN, PIN_MODE_INPUT_PULLDOWN);
    rt_pin_mode(KEY2_PIN, PIN_MODE_INPUT_PULLDOWN);
    rt_pin_mode(LEDR_PIN, PIN_MODE_OUTPUT);

    /*设置led的默认输出电平*/
    rt_pin_write(LEDR_PIN, PIN_HIGH);

    /*创建按键线程*/
    key_tid = rt_thread_create("key_tid", bsp_key_entry, RT_NULL,
                                    512, BSP_KEY_PRIORITY, 10);
    /*开启按键线程*/
    if (key_tid != RT_NULL)
    {
        rt_thread_startup(key_tid);
    }
    
}

/*导出bsp_key_sample命令至FinSH终端*/
MSH_CMD_EXPORT(bsp_key_sample, bsp key led sample);
  • 第二步:

打开stm32f429-hlg-v1.0\board下面的Kconfig文件,在该文件的 menu "BSP module"配置模块下面添加如下图内容:
rt-thread:_002STM32F429IGT BSP的PIN设备应用_第8张图片

图8.Kconfig 添加 RT_USING_KEY 宏配置

有了该宏,那么在env工具里面就可以很方便的开启或者关闭该宏,如果开启该宏,则在rtconfig.h里面就会生成该宏。

  • 第三步:

打开stm32f429-hlg-v1.0\applications下面的SConscript编译链接脚本文件,在里面添加如下图内容:
rt-thread:_002STM32F429IGT BSP的PIN设备应用_第9张图片

图9.SConscript 添加源文件编译链接宏 RT_USING_KEY
  • 第四步:

env里输入menuconfig打开工程配置,开启Enable key,如下图:rt-thread:_002STM32F429IGT BSP的PIN设备应用_第10张图片

图10.开启 key

然后一直按Esc至保存界面,选Yes保存退出。

  • 第五步:

env输入scons --target=mdk5重新生成keil5工程;输入scons --target=mdk4重新生成keil4工程;输入scons --target=iar重新生成iar工程;输入scons --target=vsc更新VSCode头文件路径。

  • 第六步:

打开keil5工程,然后就可以看到现在的工程目录结构如下图:
rt-thread:_002STM32F429IGT BSP的PIN设备应用_第11张图片

图11.keil 工程目录结构

然后编译之后看看是否有错误或者警告。只要前面步骤没有出错,这里肯定不会要问题。

  • 第七步:

下载程序到开发板。然后打开终端工具。在中断输入例程的导出命令bsp_key_sample,然后按下key1可以看到对应的输出信息,以及开发板等亮;按下key2,可以看到对应的输出信息,以及开发板灯灭。再输入查看线程指令list_thread,便可以看到bsp_key线程的运行基本信息,如下图:
rt-thread:_002STM32F429IGT BSP的PIN设备应用_第12张图片

图12.FinSH 终端

这样一个使用按键中断控制led灯的bsp就彻底完成了。

总结

有了上一篇文章rt-thread:_001STM32F429IGT BSP前期准备前期准备`完成的模板,在此基础上增加led和key的bsp就非常容易轻松。再结合env工具,可以快速实现工程配置。

文章链接

rt-thread:_001STM32F429IGT BSP前期准备

官网参考链接

RT-Thread PIN设备管理-官网连接

你可能感兴趣的:(操作系统:RT-Thread)