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

相关推荐
星辰pid5 小时前
STM32控制四自由度机械臂(SG90舵机)(硬件篇)(简单易复刻)
stm32·单片机·嵌入式硬件·机械臂
威桑6 小时前
STM32 专有名词缩写整合
stm32·单片机·嵌入式硬件
SKYDROID云卓小助手8 小时前
无人设备遥控器之自动调整编码技术篇
人工智能·嵌入式硬件·算法·自动化·信号处理
所念皆星海9118 小时前
图灵完备之路(数电学习三分钟)----数据选择器与总线
嵌入式硬件·通信·数电
Blossom.1188 小时前
机器学习在智能建筑中的应用:能源管理与环境优化
人工智能·python·深度学习·神经网络·机器学习·机器人·sklearn
智者知已应修善业9 小时前
【51单片机节日彩灯控制器设计】2022-6-11
c语言·经验分享·笔记·单片机·嵌入式硬件·51单片机
开-悟10 小时前
嵌入式编程-使用AI查找BUG的启发
c语言·人工智能·嵌入式硬件·bug
Mr.Winter`11 小时前
障碍感知 | 基于3D激光雷达的三维膨胀栅格地图构建(附ROS C++仿真)
人工智能·机器人·自动驾驶·ros·具身智能·环境感知
许白掰12 小时前
【stm32】HAL库开发——CubeMX配置RTC,单片机工作模式和看门狗
stm32·单片机·嵌入式硬件·学习·实时音视频
AiTEN_Robot13 小时前
AGV 无人叉车关键技术问题解析:精准定位算法 / 安全避障逻辑 / 系统对接协议全方案
人工智能·机器人·自动化·制造