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

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 传感器套件 - 点击购买
Seeed 1.12寸 OLED 显示屏模块 I2C 点击购买
Seeed 0.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 侧的固件已经运行起来了!呼吸灯效果如下:

    在这里插入图片描述



在这里插入图片描述



附录

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/luckydarcy/article/details/108815555
今日推荐