【ODYSSEY-STM32MP157C】驱动 GPIO 实现呼吸灯

本文介绍了如何在ODYSSEY-STM32MP157C开发板上使用Libgpiod库驱动GPIO,通过示例展示了如何控制LED闪烁和实现呼吸灯效果。利用Grove接口和STM32MP157C的GPIO_A14及GPIO_A3,分别实现了简单的LED控制和PWM模式下的呼吸灯效果。
摘要由CSDN通过智能技术生成

Grove 接口

Grove 是一种规范的嵌入式开发套件连接接口定义。

什么是 Grove 系统

Grove 是一个模块化的标准连接器原型系统。Grove 采用积木式组装电子技术。与基于跳线或焊接的系统相比,连接、试验和构建更容易,并简化了学习系统。Grove 系统允许你构建真正的系统。因而它需要一些学习和专业知识才能正确地将物件联接起来。

在这里插入图片描述

Grove 系统由基本处理单元(树干)和具有标准化连接器的各种模块(树枝)组成。基本单元(通常为微处理器)允许从 Grove 模块轻松连接任何输入或输出。每个 Grove 模块通常都可以处理单个功能,例如简单的按钮或更复杂的心率传感器。

如果您使用的处理单元没有 Grove 接口。您可以使用 Grove 转 Pin Header 转接线,从 Raspberry Pi 或 Arduino 的针脚连接到 Grove 模块。

当然,ODYSSEY-STM32MP157C 提供了两个 Grove 接口,一个是数字 Grove 接口,一个是 I2C Grove 接口。用户可以通过这两个 Grove 接口快速搭建项目原型。我整理了一些 Grove 模块资料,有需要的小伙伴可以点击购买。

厂家型号接口链接
Seeed多合一 Grove 传感器套件-点击购买
Seeed1.12寸 OLED 显示屏模块I2C点击购买
Seeed0.96寸 12864 OLED 显示屏模块I2C点击购买
Seeed绿色 LED Grove 模块GPIO点击购买
Seeed白色 LED Grove 模块GPIO点击购买
Seeed可变色 LED Grove 模块GPIO点击购买
Seeed可编程 RGB 全彩 LED 模块GPIO点击购买

快速测试 Grove 模块

想要在 ODYSSEY-STM32MP157C 开发板上测试 Grove 模块非常简单,因为 Seeed Studio 已经为我们提供了一个基于 Python 的 Grove 库(https://github.com/Seeed-Studio/grove.py)。里面有许多测试程序,包括按钮、LED、显示屏、电机等模块。

但是在使用这些库之前,我们还需要做一些工作!如果你已经完成了上一节《【ODYSSEY-STM32MP157C】环境搭建与系统运行》的环境搭建,那么接下来,我们就可以直接来测试 GPIO 了。

首先,安装 Grove.py

sudo pip3 install Seeed-grove.py

然后,下载 grove.py 库源代码

git clone https://github.com/Seeed-Studio/grove.py

进入 grove 目录,运行示例

cd grove.py/grove
sudo python3 grove_gpio.py 5

此时,如果你插上了 Grove Kit 扩展板,并在 5 号 Grove 接口上接入 IO 模块(比如 LED 灯、继电器),将会看到 LED 灯闪烁或继电器开合动作。

在这里插入图片描述

使用 Libgpiod 库

本着勤俭节约的精神,我没有入手 Grove 模块,而是用白嫖的 ODYSSEY-STM32MP157C 开发板 + 现有的 LED 模块来完成实验。没有的小伙伴赶紧上车啦~

那不用 Grove 库,应该怎么操作 GPIO 呢?答案是 —— libgpiod 库!

从 Linux 4.8 开始,不再推荐使用 sysfs 接口(/sys/class/gpio)操作 GPIO,而是建议在用户空间使用字符设备进行操作,libgpiod 就是一个用于操作 GPIO 字符设备的库,同时提供了一些工具,方便开发者进行调试。

  • gpiodetect —— 列出系统上存在的所有 gpiochip,以及它们的名称、标签和 GPIO lines。
  • gpioinfo —— 列出指定 gpiochip 的所有 line,以及它们的名称、使用者、方向、活动状态和其他标志。
  • gpioget —— 读取指定 GPIO line 的值。
  • gpioset —— 设置指定的 GPIO line 的值。
  • gpiofind —— 通过名称找到对应的 gpiochip 及行内偏移量。
  • gpiomon —— 等待指定 GPIO 线上的事件,或指定要监视的事件。

例如:

# gpiodetect 
gpiochip0 [GPIOA] (16 lines)
gpiochip1 [GPIOB] (16 lines)
gpiochip2 [GPIOC] (16 lines)
gpiochip3 [GPIOD] (16 lines)
gpiochip4 [GPIOE] (16 lines)
gpiochip5 [GPIOF] (16 lines)
gpiochip6 [GPIOG] (16 lines)
gpiochip7 [GPIOH] (16 lines)
gpiochip8 [GPIOI] (16 lines)
gpiochip9 [GPIOZ] (16 lines)

控制 LED 闪烁

我在 40 pin 扩展接口的 GPIO_A14(7号管脚)接了一个 LED 模块,而 GPIO_A14 对应 gpiochip0 的 line 14,因此,通过如下命令即可控制 LED 的亮灭。

gpioset gpiochip0 14=1    # 高电平
gpioset gpiochip0 14=0    # 低电平

因此,我们可以通过这种方式写个 shell 脚本来实现 LED 灯闪烁的效果。

#!/bin/bash
while :
do
    gpioset gpiochip0 14=0
    sleep 0.5
    gpioset gpiochip0 14=1
    sleep 0.5
done

运行该 shell 脚本,效果如下:

在这里插入图片描述

实现呼吸灯效果

要实现呼吸灯效果,通常采用 DAC 数模转换PWM 控制 两种方式,当然软件 PWM 也能实现,但从运行效率来讲并不是很好的方法。同时,由于 STM32MP157C 中包含一个 Cortex-M4 核,因此,我们可以在 M4 侧实现呼吸灯,完全采用 STM32 MCU 的编程方法即可。

还是那个 LED 模块,这次选择 GPIO_A3(29号管脚),因为 PA3 有定时器功能,因此可以设置为 PWM 控制输出模式。

  1. 打开 STM32CubeIDE,创建新工程,选择 STM32MP157C 芯片。

  2. 将 PA3 引脚分配给 Cortex-M4 核,配置 PA3 为 TIM2_CH4 模式,配置 Timer2,使能 Channel 4,如下图所示。

    在这里插入图片描述

  3. 接着配置 TIM2 参数。由于 Timer 的频率为 64 MHz,因此预分频系数设置为 64-1,自动重载值设置为 1000-1。所以 PWM 频率为 64,000,000 / 64 / 1000 = 1000 Hz。

    在这里插入图片描述

  4. 接着,我们在一个周期内(比如 1ms)调节 PWM 的占空比(dutyCycle)即可实现呼吸灯效果,main 函数代码如下。

    int main(void)
    {
        /* USER CODE BEGIN 1 */
    	uint16_t dutyCycle = 0;
        /* USER CODE END 1 */
        
        /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
        HAL_Init();
    
        if(IS_ENGINEERING_BOOT_MODE())
        {
            /* Configure the system clock */
            SystemClock_Config();
        }
    
        /* Initialize all configured peripherals */
        MX_GPIO_Init();
        MX_TIM2_Init();
        
        /* USER CODE BEGIN 2 */
        HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_4);
        /* USER CODE END 2 */
    
        /* USER CODE BEGIN WHILE */
        while (1)
        {
    	    while (dutyCycle < 1000)
    	    {
    		    dutyCycle++;
    		    __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_4, dutyCycle);
    		    HAL_Delay(1);
    	    }
    	    HAL_Delay(200);
    
    	    while (dutyCycle > 10)  /* 为了效果好一点,我故意不让LED全灭 */
    	    {
    		    dutyCycle--;
    		    __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_4, dutyCycle);
    		    HAL_Delay(1);
    	    }
    	    HAL_Delay(400);
        }
    }
    
  5. 点击 STM32CubeIDE 工具栏的“锤子”编译工程,将在 /CM4/Debug/ 目录下生成 elf 文件(比如 led_CM4.elf)。

  6. 将刚生成的 led_CM4.elf 文件放到 ODYSSEY-STM32MP157C 的 /lib/firmware 目录,并执行如下操作。

    echo led_CM4.elf > /sys/class/remoteproc/remoteproc0/firmware
    echo start > /sys/class/remoteproc/remoteproc0/state
    

    此时,Cortex-M4 侧的固件已经运行起来了!呼吸灯效果如下:

    在这里插入图片描述



在这里插入图片描述



附录

在这里插入图片描述

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

阿基米东

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

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

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

打赏作者

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

抵扣说明:

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

余额充值