Linux pwm(应用)

/****************************.c*****************************************/

/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <errno.h>
#include <error.h>
#include <getopt.h>
#include <paths.h>
#include <pwd.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include "fan_control.h"

#define PWM_IOCTL_BASE 'P'
#define PWM_CONFIG    _IOW(PWM_IOCTL_BASE, 1 , struct pwm_config)
#define PWM_ENABLE    _IOW(PWM_IOCTL_BASE, 2 , int)
#define PWM_DISABLE   _IOW(PWM_IOCTL_BASE, 3 , int)
#define GROUP_PWM_CONFIG    _IOW(PWM_IOCTL_BASE, 4, struct pwm_config_group)


struct pwm_config {
    int pwm_id;        //id,0对应pwm0,类推
    int duty_ns;       //占空比时间,单位ns
    int period_ns;     //周期时间,单位ns
    int pwm_polarity;  // 0表示 PWM_POLARITY_NORMAL, 1表示PWM_POLARITY_INVERSED
};

struct pwm_config_group {
    int pwm_id[4];        //id,0对应pwm0,类推
    int duty_ns;       //占空比时间,单位ns
    int period_ns;     //周期时间,单位ns
    int pwm_polarity;  // 0表示 PWM_POLARITY_NORMAL, 1表示PWM_POLARITY_INVERSED
    
    int group_channel;      //组使用 0表示不使用,1表示使用第零组,2表示使用第一组
    int group_run_count;    //组脉冲数
};

static int pwmFd = 0;
const int pwmID = 0;
const int periodNs=1000*1000*10;   //5ms

static void initPwmFd() {
    FILE* fp = fopen("/proc/devices","r");
    char *line = NULL;
    size_t len = 0;
    size_t read = 0;
    int major = 0;

    if (fp == NULL) return;
    while ( (read = getline(&line,&len, fp)) != -1) {  //line是字符指针,read是读取的字节数
        char *x = strstr(line, "sunxi-pwm-dev");    //返回"sunxi-pwm-dev"在line的位置指针
        if (x!=NULL) {
            char *numStr = calloc(sizeof(char), 64);
            strncpy(numStr,line,x-line-1);   //拷贝主设备号
            major = atoi(numStr);
            free(numStr);
            break;
        }
    }
    fclose(fp);
    if (line)
        free(line);
    if (major <= 0) {
        printf("error find pwm node\n");
        return;
    }
    dev_t devT = makedev(major,0);
    if (mknod("/dev/fan", S_IFCHR | 0660, makedev(major, 0))) {
        if (errno != EEXIST) {
            printf("error mknod %d\n",errno);
        }
    }
    if (pwmFd<=0)
        pwmFd = open("/dev/fan",O_RDWR | O_CLOEXEC);
    if (pwmFd <=0) {
        printf("open /dev/fan fail!\n");
    }
}

int enableFan(int percent) {
    int ret = 0;
    struct pwm_config config = {pwmID, 0, periodNs, 0, 0, 0};
    if (percent < 0 ) percent = 0;
    if (percent > 100 ) percent = 100;
    printf("enable fan  %d%\n",percent);
    initPwmFd();
    if (pwmFd<=0) {
        printf("ioctl fd open fail %d \n",errno);
        return -1;
    }
    if (percent == 0) {
        //ret = ioctl(pwmFd, PWM_CONFIG, &config);
        //printf("config ret %d\n",ret);
        //if (ret<0) return ret;
        //return ioctl(pwmFd, PWM_ENABLE, pwmID);
    }
    int dutyNs = percent * (periodNs/100);
    dutyNs = dutyNs>periodNs?periodNs:dutyNs;
    config.duty_ns=dutyNs;
    ret = ioctl(pwmFd, PWM_CONFIG, &config);
    if (ret<0) return ret;
    ioctl(pwmFd, PWM_ENABLE, pwmID);
    return ret;
}

int enableMotor(int period_ns, int run_count, int polarity) {
    int ret = 0;
    struct pwm_config_group config = {{0, 1, 2, 3}, 0, periodNs, 0, 1, 0};

    initPwmFd();
    if (pwmFd<=0) {
        printf("ioctl fd open fail %d \n",errno);
        return -1;
    }

    if (period_ns < 10) {
        printf("the first number less than 10ns \n");
        return -1;
    }
    
    config.period_ns = period_ns;
    config.duty_ns = period_ns*3/8;
    config.pwm_polarity = polarity;
    
    config.group_channel = 1;
    config.group_run_count = run_count;
    
    ret = ioctl(pwmFd, GROUP_PWM_CONFIG, &config);
    if (ret<0) return ret;
//    ioctl(pwmFd, PWM_ENABLE, pwmID);
    return ret;
}

 

 

 

/*****************************.h**************************/


#ifndef FAN_CONTROL_H
#define FAN_CONTROL_H

#ifdef __cplusplus
extern "C" {
#endif

int enableFan(int percent);
int enableMotor(int period_ns, int run_count, int polarity);

#ifdef __cplusplus
}
#endif

#endif
 

/***************************main*************************/

/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <errno.h>
#include <error.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "fan_control.h"

void printHelp(const char * cmd) {
    printf("\n");
    printf("usage:\n");
    printf("%s [percent]\n",cmd);
    printf("[percent] :  0 ~ 100\n");
}


int main(int argc, char** argv) {
#if 0
    if (argc != 2) {
        printHelp(*argv);
        return -1;
    }
    enableFan(atoi(*(argv+1)));
#endif    

#if 1
    if (argc != 4) {
        printHelp(*argv);
        return -1;
    }
//    enableFan(atoi(*(argv+1)));
    enableMotor(atoi(*(argv+1)),atoi(*(argv+2)),atoi(*(argv+3)));
#endif
    return 0;
}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值