1802|2

155

帖子

1

TA的资源

一粒金砂(高级)

楼主
 

【Luckfox幸狐 RV1106 Linux 开发板测评】六、PWM控制——命令和C方式 [复制链接]

 

本人【Luckfox幸狐 RV1106 Linux 开发板测评】帖子链接:

一、开箱及测试

二、SDK获取与编译镜像

三、GPIO点灯

四、通过PC机共享网络接入Internet和Ubuntu下Python点灯

五、编译Buildroot系统并测试摄像头

 

测试了Luckfox Pro Max加摄像头和RKNN图像识别后,本人准备按测评计划先对板子的各种接口进行实验,本篇测评PWM,依然参考Luckfox Wiki之PWM篇:https://wiki.luckfox.com/zh/Luckfox-Pico/Luckfox-Pico-PWM 。

1、PWM测评准备工作

先看板子的PWM管脚分布,手册说明系统默认开启的是PWM10,即GPIO1_C6_d管脚。

 

 

图6-1 Pro Max板IO分布

 

然后,如本人第三篇GPIO测评一样,通过面包板连接一个LED进行呼吸灯测试,管脚(板子5号脚)连接LED阴极,LED阳极串联1k电阻连接到3V3(板子36号脚)

本机Win10系统依然通过ADB登录开发板,利用echo命令来操作PWM。测试时,个人感觉手册写的测试命令执行顺序有点错乱,经过几次尝试总结命令如下:

// 查看PWM设备
# ls -l /sys/class/pwm
total 0
lrwxrwxrwx    1 root     root             0 Jan  1 12:00 pwmchip10 -> ../../devices/platform/ff490020.pwm/pwm/pwmchip10
lrwxrwxrwx    1 root     root             0 Jan  1 12:00 pwmchip11 -> ../../devices/platform/ff490030.pwm/pwm/pwmchip11
lrwxrwxrwx    1 root     root             0 Jan  1 12:00 pwmchip5 -> ../../devices/platform/ff360010.pwm/pwm/pwmchip5
lrwxrwxrwx    1 root     root             0 Jan  1 12:00 pwmchip6 -> ../../devices/platform/ff360020.pwm/pwm/pwmchip6

// 将PWM10_M1(GPIO1_C6_d)导出到用户空间
# echo 0 > /sys/class/pwm/pwmchip10/export
// 查看PWM10单个通道的属性文件(不做上一步导出到用户空间,这条命令会失败)
# ls /sys/class/pwm/pwmchip10/pwm0/
capture      enable       period       power
duty_cycle   output_type  polarity     uevent

// 使能PWM10通道,但是会提示参数错误
# echo 1 > /sys/class/pwm/pwmchip10/pwm0/enable
sh: write error: Invalid argument

// 但是如果先设置PWM周期——这里单位ns,1000000ns即1KHz频率
# echo 1000000 > /sys/class/pwm/pwmchip10/pwm0/period
// 然后再使能PWM10就成功了——必须先使能,不然没有PWM输出
# echo 1 > /sys/class/pwm/pwmchip10/pwm0/enable

// 此时输出最高值LED最亮(LED是低电平点亮),输出0 LED完全熄灭
# echo 1000000 > /sys/class/pwm/pwmchip10/pwm0/duty_cycle
# echo 0 > /sys/class/pwm/pwmchip10/pwm0/duty_cycle

// 设置PWM极性正常
# echo "normal" > /sys/class/pwm/pwmchip10/pwm0/polarity
// 结果发现输出0 LED最亮了,这说明PWM初始是inversed状态
# echo 0 > /sys/class/pwm/pwmchip10/pwm0/duty_cycle

// 设置PWM极性翻转
# echo "inversed" > /sys/class/pwm/pwmchip10/pwm0/polarity
// 果然又恢复输出最高值LED最亮
# echo 1000000 > /sys/class/pwm/pwmchip10/pwm0/duty_cycle

2、C程序控制PWM

依然使用文档提供的C代码,在虚拟机中建立pwm.c源文件,然后利用luckfox-pico SDK中提供的编译工具链进行编译,得到程序文件pwm。接着,就是拷贝到本机,再通过adb push到开发板自建的目录app下。最后就是开发板上给pwm执行权限,然后运行程序,即得到呼吸灯实验效果。

 

 

图6-2 开发板执行PWM程序

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

// 定义PWM路径
#define PWM_PATH "/sys/class/pwm/pwmchip10"
// 定义周期(纳秒)
#define PERIOD_NS 1000000
// 定义最小占空比(纳秒)
#define MIN_DUTY_CYCLE_NS 0
// 定义最大占空比(纳秒)
#define MAX_DUTY_CYCLE_NS 1000000

int main() {
    // 打开PWM的export文件,准备导出PWM通道
    FILE *pwm_export = fopen(PWM_PATH "/export", "w");
    if (!pwm_export) {
        perror("Failed to open PWM export");
        return 1;
    }
    fprintf(pwm_export, "0"); // 导出第一个PWM通道(索引为0)
    fclose(pwm_export);

    // 打开PWM通道的周期配置文件,设置周期为PERIOD_NS纳秒
    FILE *period_file = fopen(PWM_PATH "/pwm0/period", "w");
    if (!period_file) {
        perror("Failed to open PWM period");
        return 1;
    }
    fprintf(period_file, "%d", PERIOD_NS);
    fclose(period_file);

    // 打开PWM通道的使能文件,启用PWM通道
    FILE *enable_file = fopen(PWM_PATH "/pwm0/enable", "w");
    if (!enable_file) {
        perror("Failed to open PWM enable");
        return 1;
    }
    fprintf(enable_file, "1"); // 启用PWM通道
    fclose(enable_file);

    int direction = 1; // 方向,决定占空比是增加还是减少
    int duty_cycle_ns = 0; // 当前占空比,初始值为0

    while (1) { // 无限循环,使PWM保持持续输出
        duty_cycle_ns += 10000 * direction; // 根据方向增加或减少占空比的值
        if(duty_cycle_ns == MAX_DUTY_CYCLE_NS) // 如果达到最大占空比
            direction = -1; // 改变方向,从增加变为减少
        else if(duty_cycle_ns == MIN_DUTY_CYCLE_NS) // 如果达到最小占空比
            direction = 1; // 改变方向,从减少变为增加

        // 打开PWM通道的占空比配置文件,设置占空比为duty_cycle_ns纳秒
        FILE *duty_cycle_file = fopen(PWM_PATH "/pwm0/duty_cycle", "w");
        if (!duty_cycle_file) {
            perror("Failed to open PWM duty cycle");
            return 1;
        }
        fprintf(duty_cycle_file, "%d", duty_cycle_ns);
        fclose(duty_cycle_file);

        usleep(50000); // 暂停50000微秒(即0.05秒)再更新占空比,以实现PWM效果
    }

    // 最后,别忘了在程序结束前取消导出PWM通道,以释放资源
    FILE *pwm_unexport = fopen(PWM_PATH "/unexport", "w");
    if (!pwm_unexport) {
        perror("Failed to open PWM unexport");
        return 1;
    }
    fprintf(pwm_unexport, "0"); // 取消导出第一个PWM通道(索引为0)
    fclose(pwm_unexport);

    return 0; // 主函数返回0,表示程序正常结束
}

 

最新回复

这种直接调用文件的方式,是不是比较麻烦,应该有对应的第三方C库了吧?   详情 回复 发表于 2024-1-31 18:20
点赞 关注
 
 

回复
举报

7244

帖子

2

TA的资源

版主

沙发
 

这种直接调用文件的方式,是不是比较麻烦,应该有对应的第三方C库了吧?

点评

这两天我专门查询了一下Buildroot相关的知识,它应该算是一种基于文件系统的简化版Linux,应该没有提供接口方面的库。看官方的资料除了操作设备文件,就是更新设备树,而且不行Ubuntu设备树可以单独加载,更新设备树  详情 回复 发表于 2024-1-31 20:46
 
 
 

回复

155

帖子

1

TA的资源

一粒金砂(高级)

板凳
 
wangerxian 发表于 2024-1-31 18:20 这种直接调用文件的方式,是不是比较麻烦,应该有对应的第三方C库了吧?

这两天我专门查询了一下Buildroot相关的知识,它应该算是一种基于文件系统的简化版Linux,应该没有提供接口方面的库。看官方的资料除了操作设备文件,就是更新设备树,而且不像Ubuntu设备树可以单独加载,更新设备树后必须重新编译内核——明天准备尝试一下设备树,我猜想编译内核后,可能只需更新部分img文件,比如rootfs。

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表