• nRF51822 的两路 PWM 极性


      忙了一阵这个PWM,玩着玩着终于发现了些规律。Nordic 也挺会坑爹的。

      nRF51822 是没有硬件 PWM 的,只能靠一系列难以理解的 PPI /GPIOTE/TIMER来实现,其实我想说,我醉了。

      幸好SDK有这个的demo,不然真的很醉。这里说的是SDK9.0.0。

      即便是有SDK,相信很多人都像我一样,看下去会觉得晕头转向的,不过知道几个函数的应用就可以了。

      先记下怎么开始用一个PWM。这里我要用2路极性相反的PWM。

    先来初始化两个个PWM实例,名字是PWM1、PWM2,用硬件Timer1/Timer2作为基础,千万要切记Timer1/Timer2没被占用,然后记得打开Timer1/Timer2的宏。

    #define TIMER1_ENABLED 1
    #define TIMER2_ENABLED 1
    APP_PWM_INSTANCE(PWM1,1);
    APP_PWM_INSTANCE(PWM1,1);

    然后初始化一个PWM。

    void pwm_init(uint32_t freq)
    {
        static uint8_t flag=0;
        
        uint32_t period_us = 1000000UL/freq;
    
         /* 2-channel PWM, 200Hz, output on DK LED pins. */
        app_pwm_config_t pwm_cfg = APP_PWM_DEFAULT_CONFIG_1CH(period_us, BEEF_PIN_E1);
        app_pwm_config_t pwm_cfg2 = APP_PWM_DEFAULT_CONFIG_1CH(period_us, BEEF_PIN_E2);
    
    //    pwm_cfg2.pin_polarity[0] = APP_PWM_POLARITY_ACTIVE_HIGH;
        /* Switch the polarity of the second channel. */
    //  pwm_cfg.pin_polarity[0] = APP_PWM_POLARITY_ACTIVE_LOW;
    #if 1
        if(flag)
            pwm_cfg2.pin_polarity[0] = APP_PWM_POLARITY_ACTIVE_LOW;
        else
            pwm_cfg2.pin_polarity[0] = APP_PWM_POLARITY_ACTIVE_HIGH;
    #endif
    
        flag = !flag;
        /* Initialize and enable PWM. */
        ret_code_t err_code;
        err_code = app_pwm_init(&PWM1,&pwm_cfg,pwm_ready_callback);
        APP_ERROR_CHECK(err_code); 
        err_code = app_pwm_init(&PWM2,&pwm_cfg2,pwm_ready_callback);
        APP_ERROR_CHECK(err_code); 
    
    }

    上面的代码你会注意到,我用了一个 flag 。这就是我想要说的重点。

    这个函数是可以反复使用以修改 PWM的频率的,在再次使用时,先uninit它,如下:

    void pwm_uninit(void)
    {
        app_pwm_uninit(&PWM1);
        app_pwm_uninit(&PWM2);
    }

    我要说的重点是,第二次使用pwm_init()后然后enable_pwm,你就会发现这两路 的PWM的极性变成一样的了,所以我用一个flag,每次切换一下。解决了这个问题。

    另外我发现修改占空比时,要等上一段时间才能修改完成,这点非常奇怪,懒得去追究原因了,所以才用了两个定时器来做这两路PWM。

    void pwm_on(void)
    {
    
        app_pwm_enable(&PWM1);
        app_pwm_enable(&PWM2);
    
        app_pwm_channel_duty_set(&PWM1, 0, 50);
        app_pwm_channel_duty_set(&PWM2, 0, 50);
    
    //    ready_flag = false;
    //    while (app_pwm_channel_duty_set(&PWM1, 0, 50) == NRF_ERROR_BUSY);
    //    while(!ready_flag);
     //   APP_ERROR_CHECK(app_pwm_channel_duty_set(&PWM1, 1, 50));
    }

    就是这两个怪事。记下来。

  • 相关阅读:
    haffman树
    树状打印二叉树
    迷宫
    Linux(CentOS7)下安装RabbitMQ
    MySQL 5.6以上版本group by中的子查询失效
    Aop失效的场景以及解决办法
    关于Eureka服务端和客户端的一些相关配置说明
    Mybatis之通用mapper使用注解的方式写动态sql-小结
    MongoDB之源生基础概念与语句测试
    MongoDB的可视化工具(Studio 3T)的安装
  • 原文地址:https://www.cnblogs.com/ceibacity/p/5459484.html
Copyright © 2020-2023  润新知