您的位置:首页 > 编程语言 > Go语言

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

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



   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中将会给出主要的调试过程、操作方法及实现效果。

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: