基于Dragonboard 410c的自动感应调色灯软件编码实现

       前面我们已经完成整个自动感应调色灯的软件方案设计,现在我们根据这个软件方案来看一下具体实施。


   1) 距离感应模块驱动,主要用到了超声波模块US-100,接下来看一下主要用到的函数:

//定义机构体 

 struct us100_data{    
    int enable;
    int poll_time;      
 
    int cmd_gpio;         
    int echo_gpio;    
    int irq;
 
    ktime_t last_ktime;
    ktime_t now_ktime;
    int distance;
    struct mutex data_lock;
    bool data_ready;
    wait_queue_head_t data_queue;
 
    struct work_struct y;
    struct delayed_work cmd_work;
    
};


//计算距离为毫米

static void report_work_func(struct work_struct* work){

..........
    mutex_lock(&data->data_lock);
    data->distance = diff_time*170*1000/1000000000UL;    
    mutex_unlock(&data->data_lock);

..........


//周期性发射超声波

static void cmd_work_func(struct work_struct* work){

.....

gpio_set_value(data->cmd_gpio,1);
 udelay(12);
gpio_set_value(data->cmd_gpio,0);

.....

}


static int us100_probe(struct platform_device *pdev){

..............

result = parse_dt(pdev,data);   //解析设备树

..............

data->irq = gpio_to_irq(data->echo_gpio);

result = request_irq(data->irq,hs100_interrupt_handler,IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING,"hs100_time_count",data);  //申请中断

INIT_WORK(&data->report_work,report_work_func);
INIT_DELAYED_WORK(&data->cmd_work,cmd_work_func);

.............


     2) 调色模块软件设计,主要用到了pwm控制模块pca9685,让我们看一下主要用到的函数:

//pwm的基本逻辑控制

static int pca9685_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,  int duty_ns, int period_ns){

............

//改变周期

if (period_ns != pca->period_ns) { 
        prescale = DIV_ROUND_CLOSEST(PCA9685_OSC_CLOCK_MHZ * period_ns,
                         PCA9685_COUNTER_RANGE * 1000) - 1;

        if (prescale >= PCA9685_PRESCALE_MIN &&
            prescale <= PCA9685_PRESCALE_MAX) {
            regmap_update_bits(pca->regmap, PCA9685_MODE1,
                       MODE1_SLEEP, MODE1_SLEEP);
            regmap_write(pca->regmap, PCA9685_PRESCALE, prescale);
            regmap_update_bits(pca->regmap, PCA9685_MODE1,
                       MODE1_SLEEP, 0x0);
...........

            pca->period_ns = period_ns;

        } 

............

//改变duty时间

pca->duty_ns = duty_ns;

    if (duty_ns < 1) {
        if (pwm->hwpwm >= PCA9685_MAXCHAN)
            reg = PCA9685_ALL_LED_OFF_H;
        else
            reg = LED_N_OFF_H(pwm->hwpwm);

        regmap_write(pca->regmap, reg, LED_FULL);

        return 0;
    }

............

周期与duty时间相等时

if (duty_ns == period_ns) {

        if (pwm->hwpwm >= PCA9685_MAXCHAN)
            reg = PCA9685_ALL_LED_OFF_L;
        else
            reg = LED_N_OFF_L(pwm->hwpwm);

        regmap_write(pca->regmap, reg, 0x0);

        if (pwm->hwpwm >= PCA9685_MAXCHAN)
            reg = PCA9685_ALL_LED_OFF_H;
        else
            reg = LED_N_OFF_H(pwm->hwpwm);

        regmap_write(pca->regmap, reg, 0x0);

 
        if (pwm->hwpwm >= PCA9685_MAXCHAN)
            reg = PCA9685_ALL_LED_ON_H;
        else
            reg = LED_N_ON_H(pwm->hwpwm);

        regmap_write(pca->regmap, reg, LED_FULL);

        return 0;
    }

............



   3) 自动感应调色模块软件设计,主要是读取超声波节点的值,通过这个值来改变pwm节点的值,从而改变灯的颜色。


static const char *path[] = {
    "/sys/devices/soc.0/78ba000.i2c/i2c-6/6-0040/pwm/pwmchip1/pwm0/period",
    "/sys/devices/soc.0/78ba000.i2c/i2c-6/6-0040/pwm/pwmchip1/pwm0/duty",
    "/sys/devices/soc.0/78ba000.i2c/i2c-6/6-0040/pwm/pwmchip1/pwm1/period",
    "/sys/devices/soc.0/78ba000.i2c/i2c-6/6-0040/pwm/pwmchip1/pwm1/duty",
    "/sys/devices/soc.0/78ba000.i2c/i2c-6/6-0040/pwm/pwmchip1/pwm2/period",
    "/sys/devices/soc.0/78ba000.i2c/i2c-6/6-0040/pwm/pwmchip1/pwm2/duty",
    "/sys/devices/soc.0/sonar.65/value",
    "/sys/devices/soc.0/sonar.65/enable",
    };

static const char *pvalue[] = {"1000000", "2000000", "3000000", "10000000", "20000000", "30000000"};

static const char *dvalue[] = {"1000000", "2000000", "3000000", "10000000", "20000000", "30000000"};

void r_sonar ( int num){
    int fd;
    int dl = 0;
    int l = 0;
    static int l1 = 0;
    static int n = 1;
    static int i = 0;

    static char buf2[8] = {'\0'};
    
    num++;
    printf("The num is --------------%d\n",num);
    fd = open(path[6], O_RDONLY );
    if( -1 == fd ){
        printf("failed to open fd: %d\n", errno);
    }

    if( -1 == read( fd, buf2, SIZE ) ){
        printf("failed to read fd\n");
        close(fd);
    }
    close(fd);
    l = atoi(buf2);
    if(l > 2000){
        l = 0;    
    }
    printf("------l-----%d\n", l);
    dl = abs(l1 - l);
    l1 = l;
    printf("-----dl----%d\n", dl);

    if(50 < dl && dl < 300){
            printf("-----n-----%d\n", n);
        if(n == 1)
        {
            w_pwm1(pvalue[4], dvalue[3]);
            w_pwm2(pvalue[4], dvalue[4]);
            w_pwm3(pvalue[4], dvalue[4]);
        }

        if(n == 2)
        {
            w_pwm1(pvalue[4], dvalue[4]);
            w_pwm2(pvalue[4], dvalue[3]);
            w_pwm3(pvalue[4], dvalue[4]);
        }

        if(n == 3)
        {
            w_pwm1(pvalue[4], dvalue[4]);
            w_pwm2(pvalue[4], dvalue[4]);
            w_pwm3(pvalue[4], dvalue[3]);
        }

        if(n == 4)
        {
            w_pwm1(pvalue[5], dvalue[i]);
            w_pwm2(pvalue[5], dvalue[i]);
            w_pwm3(pvalue[5], dvalue[i]);    
            i++;
            if(i == 5){
                i = 0;
            }
            n = 0;
        }

        if(l > 100){
            printf("---n++----l=%d\n", l);
            n++;
        }
    }
}

static int w_pwm1 (const char *period1, const char *duty_cycle1 ){
    int fd1;
    int fd2;
    int re;
    char buf3[64] = {'\0'};

    fd1 = open(path[0], O_RDWR);
    if ( -1 >= fd1 ){
        printf("failed to open fd1\n");
        return -1;
    }else{
        printf("open fd1=%d\n", fd1);
    }
    
    re = write(fd1, period1, 8);
    if(-1 >= re){
        if(errno)
        {    
            printf("errno = %d\n", errno);
            perror("fd1 write");
            printf("error: %s\n",strerror(errno));
        }
        close(fd1);
        printf("failed to write fd1\n");
        return -1;
    }
    
    fd2 = open( path[1], O_RDWR );
    if ( -1 >= fd2 ){
        printf("failed to open fd2\n");
        return -1;
    }

    re = write(fd2, duty_cycle1, 8);
    if(-1 >= re){
        if(errno)
        {    
            printf("errno = %d\n", errno);
            perror("fd2 write");
            printf("error: %s\n",strerror(errno));
        }
        close(fd2);
        printf("failed to write fd2\n");
        return -1;
    }
    close( fd1 );
    close( fd2 );
    return 0;
}

static int w_pwm2 (const char *period2, const char *duty_cycle2 ){
    int fd4;
    int fd5;
    int re;

    fd4 = open( path[2], O_RDWR );
    if ( -1 >= fd4 ){
        printf("failed to open fd4\n");
        return -1;
    }
    
    re = write (fd4, period2, 8);
    if(-1 >= re){
        printf("failed to write fd4\n");
        close(fd4);
        return -1;
    }

    fd5 = open( path[3], O_RDWR );
    if (-1 >= fd5){
        printf("failed to open fd5\n");
        return -1;
    }
    
    re = write (fd5, duty_cycle2, 8);
    if(-1 >= re){
        printf("failed to write fd5\n");
        close(fd5);
        return -1;
    }

    close( fd4 );
    close( fd5 );
    return 0;
}

static int w_pwm3 (const char *period3, const char *duty_cycle3 ){
    int fd7;
    int fd8;
    int re;

    fd7 = open( path[4], O_RDWR );
    if ( -1 >= fd7 ){
        printf("failed to open fd7\n");
        return -1;
    }
    
    re = write (fd7, period3, 8);
    if(-1 >= re){
        printf("failed to write fd7\n");
        close(fd7);
        return -1;
    }

    fd8 = open( path[5], O_RDWR );
    if ( -1 >= fd8 ){
        printf("failed to open fd8\n");
        return -1;
    }
    
    re = write (fd8, duty_cycle3, 8);
    if(-1 >= re){
        printf("failed to write fd8\n");
        close(fd8);
        return -1;
    }

    close( fd7 );
    close( fd8 );
    return 0;
}

int main(void){
int res = 0;

typedef void (*sighandler_t)(int);

if(signal(SIGALRM, r_sonar) == SIG_ERR)
{
    printf("The signal is failed----------\n");
}else{
    r_sonar(0);
}

struct itimerval tick;
memset(&tick, 0, sizeof(tick) );
tick.it_value.tv_sec = 1;
tick.it_value.tv_usec = 0;
tick.it_interval.tv_sec = 1;
tick.it_interval.tv_usec = 0;
res = setitimer(ITIMER_REAL, &tick, NULL);
if(res){
        printf("set timer failed!!/n");
    }else{
        printf("The timer is running--------------\n");
    }
while(1);

r_sonar(0);
return 0;
}

  以上就是就是根据软件方案各个模块涉及到的核心代码,后面将会在此基础上进行改善,下篇blog中将会给出主要的调试过程、操作方法及实现效果。












 


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值