嵌入式硬件篇---龙芯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. 支持多通道(若硬件允许)。

相关推荐
公子无缘1 小时前
【嵌入式】复刻SQFMI开源的Watchy墨水屏电子表——(2)软件部分
c语言·嵌入式硬件·物联网·开源·esp32
wFitting1 小时前
Ubuntu22.04 安装 Isaac gym 中出现的问题
机器人
量子纠缠BUG3 小时前
DeepSeek:开启机器人智能化的革命性突破
人工智能·机器人
youngerwang3 小时前
【嵌入式硬件测试之道连载之开篇语+第一章】
网络·功能测试·嵌入式硬件·深度学习·硬件架构·硬件工程·测试覆盖率
单片机学习之路3 小时前
使用STM32CubeMX+DMA+空闲中断实现串口接收和发送数据(STM32G070CBT6)
stm32·单片机·嵌入式硬件
猫猫的小茶馆3 小时前
【STM32】NVIC(嵌套向量中断控制器)
c语言·stm32·单片机·嵌入式硬件·mcu·51单片机
水水阿水水4 小时前
STM32U575RIT6单片机(四)
stm32·单片机·嵌入式硬件
Ms.Yue6 小时前
51单片机学习记录
嵌入式硬件·学习·51单片机
程序员JerrySUN7 小时前
深入解析音频编解码器(Audio CODEC):硬件、接口与驱动开发
linux·驱动开发·嵌入式硬件·音视频