嵌入式硬件篇---龙芯PWM生成


文章目录


前言

本文简单介绍了龙芯2k1000中的PWM生成。


1. 头文件引入

c 复制代码
#include <stdio.h>    // 标准输入输出(如printf)
#include <stdlib.h>   // 系统调用(如open/close)
#include <time.h>     // 时间相关函数(未直接使用)
#include <fcntl.h>    // 文件控制选项(如O_WRONLY)
#include <unistd.h>   // POSIX API(如write/close)
#include <sys/mman.h> // 内存映射(未直接使用)

作用

作用:提供文件操作和系统调用的基础支持。

2. 导出PWM通道 pwm_export

c 复制代码
int pwm_export(unsigned int pwm) {
    int fd;
    // 根据pwm编号选择对应的sysfs路径
    if (pwm == 0) {
        fd = open("/sys/class/pwm/pwmchip0/export", O_WRONLY);
    } else if (pwm == 1) {
        fd = open("/sys/class/pwm/pwmchip1/export", O_WRONLY);
    } // ... 其他pwm编号类似
    if (fd < 0) {
        printf("Failed export PWM%d\n", pwm);
        return -1;
    }
    write(fd, "0", 2); // 导出通道0(假设每个pwmchip只有一个通道)
    close(fd);
    return 0;
}

功能

功能:通过写入export文件激活PWM通道。

关键点

假设每个pwmchip仅支持一个通道(pwm0 )。

写入"0"表示导出该芯片的通道0

问题

write(fd, "0", 2) 中的长度参数应为1(仅写入字符'0'),多出的\0可能导致内核解析错误。
缺少对pwm参数的合法性检查(如传入pwm=4会导致未定义行为)。

3. 取消导出PWM通道 pwm_unexport

c 复制代码
int pwm_unexport(unsigned int pwm) {
    // 类似pwm_export,操作unexport文件
    write(fd, "0", 2); // 取消导出通道0
}

作用

作用:清理已导出的PWM通道。

注意

注意:需与pwm_export配对使用。

4. 启用/禁用PWM pwm_enable/pwm_disable

c 复制代码
int pwm_enable(unsigned int pwm) {
    // 打开对应通道的enable文件
    write(fd, "1", 2); // 启用PWM输出
}

功能

功能:通过写入1或0控制PWM输出开关。

改进建议

使用write(fd, "1", 1)避免多余的空字符。

检查write返回值确保操作成功。

5. 配置周期和占空比 pwm_config

c 复制代码
int pwm_config(unsigned int pwm, unsigned int period, unsigned int duty_cycle) {
    // 写入周期(单位:纳秒)
    write(fd, buf_p, len_p);
    // 写入占空比(单位:纳秒)
    write(fd, buf_d, len_d);
}

作用

作用:设置PWM波形参数。

关键点

period为完整周期时间,duty_cycle为高电平时间。

需确保duty_cycle <= period,否则配置失败。

示例

示例:若period=20000000(20ms),duty_cycle=1500000(1.5ms),则占空比为7.5%。

6. 设置极性 pwm_polarity

c 复制代码
int pwm_polarity(int pwm, int polarity) {
    if (polarity == 1) {
        write(fd, "normal", 6);   // 正常极性(高电平有效)
    } else if (polarity == 0) {
        write(fd, "inversed", 8); // 反向极性(低电平有效)
    }
}

功能

功能:控制PWM信号的极性。

潜在问题

字符串"inversed"可能是拼写错误,某些驱动要求"inverted"。

需确认龙芯2K1000的PWM驱动支持的极性模式。

7.龙芯2K1000适配说明

7.1 硬件特性

PWM控制器数量

PWM控制器数量:假设支持4个独立PWM控制器(pwmchip0~pwmchip3)。

通道支持

通道支持:每个控制器可能仅支持单通道(pwm0),需参考《龙芯2K1000硬件手册》。

7.2关键问题与优化建议

问题1:写入长度错误

write(fd, "0", 2); // 错误:多写入一个空字符

修复

修复:改为write(fd, "0", 1),仅写入字符'0'。

问题2:路径生成冗余

c 复制代码
优化:提取公共路径生成逻辑:
const char* get_pwm_path(int pwm, const char* file) {
    static char path[128];
    snprintf(path, sizeof(path), "/sys/class/pwm/pwmchip%d/pwm0/%s", pwm, file);
    return path;
}

问题3:错误处理不足

c 复制代码
增强:检查所有系统调用的返回值:
if (write(fd, buf, len) != len) {
    perror("Write failed");
    return -1;
}

问题4:参数合法性校验

c 复制代码
if (pwm < 0 || pwm > 3) {
    printf("Invalid PWM chip number: %d\n", pwm);
    return -1;
}

7.3完整优化示例

c 复制代码
// 辅助函数:生成PWM路径
const char* get_pwm_path(int pwm, const char* file) {
    static char path[128];
    snprintf(path, sizeof(path), "/sys/class/pwm/pwmchip%d/pwm0/%s", pwm, file);
    return path;
}

// 导出PWM通道(优化后)
int pwm_export(unsigned int pwm) {
    if (pwm > 3) { // 校验参数合法性
        printf("Invalid PWM chip: %d\n", pwm);
        return -1;
    }
    char export_path[64];
    snprintf(export_path, sizeof(export_path), "/sys/class/pwm/pwmchip%d/export", pwm);
    int fd = open(export_path, O_WRONLY);
    if (fd < 0) {
        perror("Failed to open export file");
        return -1;
    }
    if (write(fd, "0", 1) != 1) { // 修正写入长度
        perror("Failed to export PWM");
        close(fd);
        return -1;
    }
    close(fd);
    return 0;
}

7.4应用场景示例

c 复制代码
int main() {
    pwm_export(0);          // 导出PWM0
    pwm_config(0, 20000000, 1500000); // 20ms周期,1.5ms高电平
    pwm_polarity(0, 1);     // 正常极性
    pwm_enable(0);          // 启动PWM输出
    sleep(5);
    pwm_disable(0);         // 停止输出
    pwm_unexport(0);        // 清理
    return 0;
}

8.总结

功能

功能:完整控制PWM的初始化、参数配置和输出管理

优势

优势:基于sysfs接口,代码简洁,兼容性强

改进方向

  1. 修复写入长度和拼写错误。
  2. 提取公共逻辑减少冗余。
  3. 增强错误处理和参数校验。
  4. 支持多通道(若硬件允许)。

相关推荐
来自晴朗的明天10 小时前
15、隔离 DC-DC 电源电路(18S12 模块)
单片机·嵌入式硬件·硬件工程
9呀10 小时前
【ros2】OccupancyGrid消息里的resolution
人工智能·机器人
我送炭你添花10 小时前
电子世界的奇妙冒险:从一个电阻开始(系列目录)
人工智能·单片机·嵌入式硬件·fpga开发
熵减纪元10 小时前
人形机器人周末炸场:Atlas后空翻回归、宇树零下47度暴走、中国Bolt跑出10m/s | 2.8日报
人工智能·机器人·人形机器人
硅谷秋水10 小时前
REALM:用于机器人操作泛化能力的真实-仿真验证基准测试
人工智能·机器学习·计算机视觉·语言模型·机器人
VekiSon10 小时前
Linux内核驱动——设备树原理与应用
linux·c语言·arm开发·嵌入式硬件
国科安芯10 小时前
火箭传感器控制单元的抗辐照MCU选型与环境适应性验证
单片机·嵌入式硬件·架构·risc-v·安全性测试
LS_learner11 小时前
树莓派(ARM64 架构)Ubuntu 24.04 (Noble) 系统 `apt update` 报错解决方案
嵌入式硬件
云空12 小时前
日常高频英语口语实用表达播客
人工智能·机器人
大江东去浪淘尽千古风流人物12 小时前
【VLN】VLN从理论到实践的完整指南VLN-Tutorial
机器人·大模型·概率论·端侧部署·巨身智能