zoukankan      html  css  js  c++  java
  • NRF51822自学笔记(二)PWM

    PWM这个东西我在32上用来电机调速过……通过改变高低电平占空比来实现一些功能。

    keil的nrf51822目录下没有pwm.c..就在网上找了个pwm蜂鸣器的例程……看画风应该是官方的……吧……

    例程的define为NRF51 SETUPA BOARD_PCA10028..修改一下,设置如下。

    然后通过两个灯来实现一下两路pwm波……pin为20和21的LED_2和LED_3
     
    先看main.c(非例程)
    1. #include <stdbool.h>  
    2. #include <stdint.h>  
    3. #include "nrf_delay.h"  
    4. #include "nrf_gpio.h"  
    5. #include "boards.h"  
    6. #include "nrf_pwm.h"  
    7.   
    8. /** 
    9.  * @brief Function for application main entry. 
    10.  */  
    11. int main(void)  
    12. {  
    13.     // Configure LED-pins as outputs  
    14.       nrf_gpio_cfg_output(20);  
    15.       nrf_gpio_cfg_output(21);  
    16.       
    17.       nrf_pwm_config_t pwm_config = PWM_DEFAULT_CONFIG;  
    18.       
    19.           pwm_config.mode             = PWM_MODE_LED_255;  
    20.           pwm_config.num_channels     = 2;  
    21.           pwm_config.gpio_num[0]      = 21;  
    22.           pwm_config.gpio_num[1]      = 20;  
    23.       nrf_pwm_init(&pwm_config);  
    24.       nrf_pwm_set_value(0,20);  
    25.       nrf_pwm_set_value(1,255);  
    26. }  
     
    #include <stdbool.h>
    #include <stdint.h>
    #include "nrf_delay.h"
    #include "nrf_gpio.h"
    #include "boards.h"
    #include "nrf_pwm.h"
    
    /**
     * @brief Function for application main entry.
     */
    int main(void)
    {
        // Configure LED-pins as outputs
    	  nrf_gpio_cfg_output(20);
    	  nrf_gpio_cfg_output(21);
    	
    	  nrf_pwm_config_t pwm_config = PWM_DEFAULT_CONFIG;
        
              pwm_config.mode             = PWM_MODE_LED_255;
              pwm_config.num_channels     = 2;
              pwm_config.gpio_num[0]      = 21;
              pwm_config.gpio_num[1]      = 20;
    	  nrf_pwm_init(&pwm_config);
    	  nrf_pwm_set_value(0,20);
    	  nrf_pwm_set_value(1,255);
    }

    第一步把要操作的灯的pin配置一下,设置成outputs

    第二步用一个结构体来设置一下PWM的一些参数。

              追踪一下PWM_DEFAULT_CONFIG,发现它在PWM.H里

    1. #define PWM_DEFAULT_CONFIG  {.num_channels   = 2,                  
    2.                              .gpio_num       = {8,9,10,11},           
    3.                              .ppi_channel    = {0,1,2,3,4,5,6,7},      
    4.                              .gpiote_channel = {2,3,0,1},            
    5.                              .mode           = PWM_MODE_LED_100};  
     
    #define PWM_DEFAULT_CONFIG  {.num_channels   = 2,                
                                 .gpio_num       = {8,9,10,11},         
                                 .ppi_channel    = {0,1,2,3,4,5,6,7},    
                                 .gpiote_channel = {2,3,0,1},          
                                 .mode           = PWM_MODE_LED_100};

    然后配置mode为PWM_MODE_LED_255,两个通道,两个通道的pin为21和20。把结构体地址传给初始化函数,初始化之后调用nrf_pwm_set_value()来设置一下占空比。

    追踪一下那个mode

    1. typedef enum  
    2. {  
    3.     PWM_MODE_LED_100,   // 0-100 resolution, 156Hz PWM frequency, 32kHz timer frequency (prescaler 9)  
    4.     PWM_MODE_LED_255,   // 8-bit resolution, 122Hz PWM frequency, 32kHz timer frequency (prescaler 9)  
    5.     PWM_MODE_LED_1000,  // 0-1000 resolution, 125Hz PWM frequency, 250kHz timer frequency (prescaler 6)  
    6.       
    7.     PWM_MODE_MTR_100,   // 0-100 resolution, 20kHz PWM frequency, 2MHz timer frequency (prescaler 3)  
    8.     PWM_MODE_MTR_255,   // 8-bit resolution, 31kHz PWM frequency, 8MHz timer frequency (prescaler 1)  
    9.       
    10.     PWM_MODE_BUZZER_255  // 8-bit resolution, 62.5kHz PWM frequency, 16MHz timer frequency (prescaler 0)  
    11. } nrf_pwm_mode_t;  
     
    typedef enum
    {
        PWM_MODE_LED_100,   // 0-100 resolution, 156Hz PWM frequency, 32kHz timer frequency (prescaler 9)
        PWM_MODE_LED_255,   // 8-bit resolution, 122Hz PWM frequency, 32kHz timer frequency (prescaler 9)
        PWM_MODE_LED_1000,  // 0-1000 resolution, 125Hz PWM frequency, 250kHz timer frequency (prescaler 6)
        
        PWM_MODE_MTR_100,   // 0-100 resolution, 20kHz PWM frequency, 2MHz timer frequency (prescaler 3)
        PWM_MODE_MTR_255,   // 8-bit resolution, 31kHz PWM frequency, 8MHz timer frequency (prescaler 1)
        
        PWM_MODE_BUZZER_255  // 8-bit resolution, 62.5kHz PWM frequency, 16MHz timer frequency (prescaler 0)
    } nrf_pwm_mode_t;

    = =一堆枚举常量,LED,蜂鸣器和MTR。在初始化函数里利用它们和switch语句实现了配置………

    1. uint32_t nrf_pwm_init(nrf_pwm_config_t *config)  
    2. {  
    3.     if(config->num_channels == 0 || config->num_channels > PWM_MAX_CHANNELS) return 0xFFFFFFFF;  
    4.       
    5.     switch(config->mode)  
    6.     {  
    7.         case PWM_MODE_LED_100:   // 0-100 resolution, 321Hz PWM frequency, 32kHz timer frequency (prescaler 9)  
    8.             PWM_TIMER->PRESCALER = 9;   
    9.             pwm_max_value = 100;  
    10.             break;  
    11.         case PWM_MODE_LED_255:   // 8-bit resolution, 122Hz PWM frequency, 32kHz timer frequency (prescaler 9)  
    12.             PWM_TIMER->PRESCALER = 9;  
    13.             pwm_max_value = 255;    
    14.             break;  
    15.         case PWM_MODE_LED_1000:  // 0-1000 resolution, 250Hz PWM frequency, 250kHz timer frequency (prescaler 6)  
    16.             PWM_TIMER->PRESCALER = 6;  
    17.             pwm_max_value = 1000;  
    18.             break;  
    19.         case PWM_MODE_MTR_100:   // 0-100 resolution, 20kHz PWM frequency, 2MHz timer frequency (prescaler 3)  
    20.             PWM_TIMER->PRESCALER = 3;  
    21.             pwm_max_value = 100;  
    22.             break;  
    23.         case PWM_MODE_MTR_255:    // 8-bit resolution, 31kHz PWM frequency, 8MHz timer frequency (prescaler 1)    
    24.             PWM_TIMER->PRESCALER = 1;  
    25.             pwm_max_value = 255;  
    26.             break;  
    27.         case PWM_MODE_BUZZER_255:  // 8-bit resolution, 62.5kHz PWM frequency, 16MHz timer frequency (prescaler 0)  
    28.             PWM_TIMER->PRESCALER = 0;  
    29.             pwm_max_value = 255;  
    30.             break;  
    31.         default:  
    32.             return 0xFFFFFFFF;  
    33.     }  
    34.     pwm_cc_update_margin_ticks = pwm_cc_margin_by_prescaler[PWM_TIMER->PRESCALER];  
    35.     pwm_num_channels = config->num_channels;  
    36.     for(int i = 0; i < pwm_num_channels; i++)  
    37.     {  
    38.         pwm_io_ch[i] = (uint32_t)config->gpio_num[i];  
    39.         nrf_gpio_cfg_output(pwm_io_ch[i]);  
    40.         pwm_running[i] = 0;         
    41.         pwm_gpiote_channel[i] = config->gpiote_channel[i];          
    42.     }  
    43.     PWM_TIMER->TASKS_CLEAR = 1;  
    44.     PWM_TIMER->BITMODE = TIMER_BITMODE_BITMODE_16Bit;  
    45.     PWM_TIMER->CC[2] = pwm_next_max_value = pwm_max_value;  
    46.     PWM_TIMER->MODE = TIMER_MODE_MODE_Timer;  
    47.     PWM_TIMER->SHORTS = TIMER_SHORTS_COMPARE2_CLEAR_Msk;  
    48.     PWM_TIMER->EVENTS_COMPARE[0] = PWM_TIMER->EVENTS_COMPARE[1] = PWM_TIMER->EVENTS_COMPARE[2] = PWM_TIMER->EVENTS_COMPARE[3] = 0;       
    49.       
    50.     if(pwm_num_channels > 2)  
    51.     {  
    52.         PWM_TIMER2->TASKS_CLEAR = 1;  
    53.         PWM_TIMER2->BITMODE = TIMER_BITMODE_BITMODE_16Bit;  
    54.         PWM_TIMER2->CC[2] = pwm_next_max_value = pwm_max_value;  
    55.         PWM_TIMER2->MODE = TIMER_MODE_MODE_Timer;  
    56.         PWM_TIMER2->SHORTS = TIMER_SHORTS_COMPARE2_CLEAR_Msk;  
    57.         PWM_TIMER2->EVENTS_COMPARE[0] = PWM_TIMER2->EVENTS_COMPARE[1] = PWM_TIMER2->EVENTS_COMPARE[2] = PWM_TIMER2->EVENTS_COMPARE[3] = 0;               
    58.         PWM_TIMER2->PRESCALER = PWM_TIMER->PRESCALER;  
    59.     }  
    60.   
    61.     for(int i = 0; i < pwm_num_channels && i < 2; i++)  
    62.     {  
    63.         ppi_enable_channel(config->ppi_channel[i*2],  &PWM_TIMER->EVENTS_COMPARE[i], &NRF_GPIOTE->TASKS_OUT[pwm_gpiote_channel[i]]);  
    64.         ppi_enable_channel(config->ppi_channel[i*2+1],&PWM_TIMER->EVENTS_COMPARE[2], &NRF_GPIOTE->TASKS_OUT[pwm_gpiote_channel[i]]);    
    65.         pwm_modified[i] = false;          
    66.     }  
    67.     for(int i = 2; i < pwm_num_channels; i++)  
    68.     {  
    69.         ppi_enable_channel(config->ppi_channel[i*2],  &PWM_TIMER2->EVENTS_COMPARE[i-2], &NRF_GPIOTE->TASKS_OUT[pwm_gpiote_channel[i]]);  
    70.         ppi_enable_channel(config->ppi_channel[i*2+1],&PWM_TIMER2->EVENTS_COMPARE[2], &NRF_GPIOTE->TASKS_OUT[pwm_gpiote_channel[i]]);    
    71.         pwm_modified[i] = false;          
    72.     }  
    73. #if(USE_WITH_SOFTDEVICE == 1)  
    74.     sd_radio_session_open(nrf_radio_signal_callback);  
    75. #else  
    76.     NVIC_SetPriority(PWM_IRQn, 0);  
    77.     NVIC_EnableIRQ(PWM_IRQn);  
    78. #endif  
    79.     apply_pan73_workaround(PWM_TIMER, true);  
    80.     PWM_TIMER->TASKS_START = 1;  
    81.     if(pwm_num_channels > 2)  
    82.     {  
    83.         apply_pan73_workaround(PWM_TIMER2, true);  
    84.         PWM_TIMER2->TASKS_START = 1;  
    85.     }  
    86.     return 0;  
    uint32_t nrf_pwm_init(nrf_pwm_config_t *config)
    {
        if(config->num_channels == 0 || config->num_channels > PWM_MAX_CHANNELS) return 0xFFFFFFFF;
        
        switch(config->mode)
        {
            case PWM_MODE_LED_100:   // 0-100 resolution, 321Hz PWM frequency, 32kHz timer frequency (prescaler 9)
                PWM_TIMER->PRESCALER = 9; 
                pwm_max_value = 100;
                break;
            case PWM_MODE_LED_255:   // 8-bit resolution, 122Hz PWM frequency, 32kHz timer frequency (prescaler 9)
                PWM_TIMER->PRESCALER = 9;
                pwm_max_value = 255;  
                break;
            case PWM_MODE_LED_1000:  // 0-1000 resolution, 250Hz PWM frequency, 250kHz timer frequency (prescaler 6)
                PWM_TIMER->PRESCALER = 6;
                pwm_max_value = 1000;
                break;
            case PWM_MODE_MTR_100:   // 0-100 resolution, 20kHz PWM frequency, 2MHz timer frequency (prescaler 3)
                PWM_TIMER->PRESCALER = 3;
                pwm_max_value = 100;
                break;
            case PWM_MODE_MTR_255:    // 8-bit resolution, 31kHz PWM frequency, 8MHz timer frequency (prescaler 1)	
                PWM_TIMER->PRESCALER = 1;
                pwm_max_value = 255;
                break;
            case PWM_MODE_BUZZER_255:  // 8-bit resolution, 62.5kHz PWM frequency, 16MHz timer frequency (prescaler 0)
                PWM_TIMER->PRESCALER = 0;
                pwm_max_value = 255;
                break;
            default:
                return 0xFFFFFFFF;
        }
        pwm_cc_update_margin_ticks = pwm_cc_margin_by_prescaler[PWM_TIMER->PRESCALER];
        pwm_num_channels = config->num_channels;
        for(int i = 0; i < pwm_num_channels; i++)
        {
            pwm_io_ch[i] = (uint32_t)config->gpio_num[i];
            nrf_gpio_cfg_output(pwm_io_ch[i]);
            pwm_running[i] = 0;       
            pwm_gpiote_channel[i] = config->gpiote_channel[i];        
        }
        PWM_TIMER->TASKS_CLEAR = 1;
        PWM_TIMER->BITMODE = TIMER_BITMODE_BITMODE_16Bit;
        PWM_TIMER->CC[2] = pwm_next_max_value = pwm_max_value;
    	PWM_TIMER->MODE = TIMER_MODE_MODE_Timer;
        PWM_TIMER->SHORTS = TIMER_SHORTS_COMPARE2_CLEAR_Msk;
        PWM_TIMER->EVENTS_COMPARE[0] = PWM_TIMER->EVENTS_COMPARE[1] = PWM_TIMER->EVENTS_COMPARE[2] = PWM_TIMER->EVENTS_COMPARE[3] = 0;     
        
        if(pwm_num_channels > 2)
        {
            PWM_TIMER2->TASKS_CLEAR = 1;
            PWM_TIMER2->BITMODE = TIMER_BITMODE_BITMODE_16Bit;
            PWM_TIMER2->CC[2] = pwm_next_max_value = pwm_max_value;
            PWM_TIMER2->MODE = TIMER_MODE_MODE_Timer;
            PWM_TIMER2->SHORTS = TIMER_SHORTS_COMPARE2_CLEAR_Msk;
            PWM_TIMER2->EVENTS_COMPARE[0] = PWM_TIMER2->EVENTS_COMPARE[1] = PWM_TIMER2->EVENTS_COMPARE[2] = PWM_TIMER2->EVENTS_COMPARE[3] = 0;             
            PWM_TIMER2->PRESCALER = PWM_TIMER->PRESCALER;
        }
    
        for(int i = 0; i < pwm_num_channels && i < 2; i++)
        {
            ppi_enable_channel(config->ppi_channel[i*2],  &PWM_TIMER->EVENTS_COMPARE[i], &NRF_GPIOTE->TASKS_OUT[pwm_gpiote_channel[i]]);
            ppi_enable_channel(config->ppi_channel[i*2+1],&PWM_TIMER->EVENTS_COMPARE[2], &NRF_GPIOTE->TASKS_OUT[pwm_gpiote_channel[i]]);  
            pwm_modified[i] = false;        
        }
        for(int i = 2; i < pwm_num_channels; i++)
        {
            ppi_enable_channel(config->ppi_channel[i*2],  &PWM_TIMER2->EVENTS_COMPARE[i-2], &NRF_GPIOTE->TASKS_OUT[pwm_gpiote_channel[i]]);
            ppi_enable_channel(config->ppi_channel[i*2+1],&PWM_TIMER2->EVENTS_COMPARE[2], &NRF_GPIOTE->TASKS_OUT[pwm_gpiote_channel[i]]);  
            pwm_modified[i] = false;        
        }
    #if(USE_WITH_SOFTDEVICE == 1)
        sd_radio_session_open(nrf_radio_signal_callback);
    #else
        NVIC_SetPriority(PWM_IRQn, 0);
        NVIC_EnableIRQ(PWM_IRQn);
    #endif
        apply_pan73_workaround(PWM_TIMER, true);
        PWM_TIMER->TASKS_START = 1;
        if(pwm_num_channels > 2)
        {
            apply_pan73_workaround(PWM_TIMER2, true);
            PWM_TIMER2->TASKS_START = 1;
        }
        return 0;
    }

    当通道数大于2时,就要使用TIMER2了。下面是设置占空比的

    1. void nrf_pwm_set_value(uint32_t pwm_channel, uint32_t pwm_value)  
    2. {  
    3.     pwm_next_value[pwm_channel] = pwm_value;  
    4.     pwm_modified[pwm_channel] = true;  
    5. #if(USE_WITH_SOFTDEVICE == 1)  
    6.     nrf_radio_request_t radio_request;  
    7.     radio_request.request_type = NRF_RADIO_REQ_TYPE_EARLIEST;  
    8.     radio_request.params.earliest.hfclk = NRF_RADIO_HFCLK_CFG_DEFAULT;  
    9.     radio_request.params.earliest.length_us = 250;  
    10.     radio_request.params.earliest.priority = NRF_RADIO_PRIORITY_HIGH;  
    11.     radio_request.params.earliest.timeout_us = 100000;  
    12.     sd_radio_request(&radio_request);  
    13. #else  
    14.     NVIC_SetPendingIRQ(PWM_IRQn);  
    15. #endif  
    void nrf_pwm_set_value(uint32_t pwm_channel, uint32_t pwm_value)
    {
        pwm_next_value[pwm_channel] = pwm_value;
        pwm_modified[pwm_channel] = true;
    #if(USE_WITH_SOFTDEVICE == 1)
        nrf_radio_request_t radio_request;
        radio_request.request_type = NRF_RADIO_REQ_TYPE_EARLIEST;
        radio_request.params.earliest.hfclk = NRF_RADIO_HFCLK_CFG_DEFAULT;
        radio_request.params.earliest.length_us = 250;
        radio_request.params.earliest.priority = NRF_RADIO_PRIORITY_HIGH;
        radio_request.params.earliest.timeout_us = 100000;
        sd_radio_request(&radio_request);
    #else
        NVIC_SetPendingIRQ(PWM_IRQn);
    #endif
    1. void nrf_pwm_set_values(uint32_t pwm_channel_num, uint32_t *pwm_values)  
    2. {  
    3.     for(int i = 0; i < pwm_channel_num; i++)  
    4.     {  
    5.         pwm_next_value[i] = pwm_values[i];  
    6.         pwm_modified[i] = true;  
    7.     }  
    8. #if(USE_WITH_SOFTDEVICE == 1)  
    9.     nrf_radio_request_t radio_request;  
    10.     radio_request.request_type = NRF_RADIO_REQ_TYPE_EARLIEST;  
    11.     radio_request.params.earliest.hfclk = NRF_RADIO_HFCLK_CFG_DEFAULT;  
    12.     radio_request.params.earliest.length_us = 250;  
    13.     radio_request.params.earliest.priority = NRF_RADIO_PRIORITY_HIGH;  
    14.     radio_request.params.earliest.timeout_us = 100000;  
    15.     sd_radio_request(&radio_request);  
    16. #else  
    17.     NVIC_SetPendingIRQ(PWM_IRQn);  
    18. #endif  
    19. }  
     
    void nrf_pwm_set_values(uint32_t pwm_channel_num, uint32_t *pwm_values)
    {
        for(int i = 0; i < pwm_channel_num; i++)
        {
            pwm_next_value[i] = pwm_values[i];
            pwm_modified[i] = true;
        }
    #if(USE_WITH_SOFTDEVICE == 1)
        nrf_radio_request_t radio_request;
        radio_request.request_type = NRF_RADIO_REQ_TYPE_EARLIEST;
        radio_request.params.earliest.hfclk = NRF_RADIO_HFCLK_CFG_DEFAULT;
        radio_request.params.earliest.length_us = 250;
        radio_request.params.earliest.priority = NRF_RADIO_PRIORITY_HIGH;
        radio_request.params.earliest.timeout_us = 100000;
        sd_radio_request(&radio_request);
    #else
        NVIC_SetPendingIRQ(PWM_IRQn);
    #endif
    }

    这两个函数功能是一样的……区别在后者先设置好了一组数……

    最后看看中断服务函数

    1. void PWM_IRQHandler(void)  
    2. {  
    3.     static uint32_t i, new_capture, old_capture;  
    4.     PWM_TIMER->CC[2] = pwm_max_value = pwm_next_max_value;  
    5.     if(pwm_num_channels > 2) PWM_TIMER2->CC[2] = pwm_max_value;  
    6.     for(i = 0; i < pwm_num_channels; i++)  
    7.     {  
    8.         if(pwm_modified[i])  
    9.         {  
    10.             pwm_modified[i] = false;  
    11.             if(pwm_next_value[i] == 0)  
    12.             {  
    13.                 nrf_gpiote_unconfig(pwm_gpiote_channel[i]);  
    14.                 nrf_gpio_pin_write(pwm_io_ch[i], 0);  
    15.                 pwm_running[i] = 0;  
    16.             }  
    17.             else if (pwm_next_value[i] >= pwm_max_value)  
    18.             {  
    19.                 nrf_gpiote_unconfig(pwm_gpiote_channel[i]);  
    20.                 nrf_gpio_pin_write(pwm_io_ch[i], 1);   
    21.                 pwm_running[i] = 0;  
    22.             }  
    23.             else  
    24.             {  
    25.                 if(i < 2)  
    26.                 {  
    27.                     new_capture = pwm_next_value[i];  
    28.                     old_capture = PWM_TIMER->CC[i];  
    29.                     if(!pwm_running[i])  
    30.                     {  
    31.                         nrf_gpiote_task_config(pwm_gpiote_channel[i], pwm_io_ch[i], NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH);    
    32.                         pwm_running[i] = 1;  
    33.                         PWM_TIMER->TASKS_CAPTURE[3] = 1;  
    34.                         if(PWM_TIMER->CC[3] > new_capture) NRF_GPIOTE->TASKS_OUT[pwm_gpiote_channel[i]] = 1;  
    35.                         PWM_TIMER->CC[i] = new_capture;  
    36.                     }  
    37.                     else  
    38.                     {  
    39.                         while(1)  
    40.                         {  
    41.                             PWM_TIMER->TASKS_CAPTURE[3] = 1;  
    42.                             if(safe_margins_present(PWM_TIMER_CURRENT, old_capture) && safe_margins_present(PWM_TIMER_CURRENT, new_capture)) break;  
    43.                         }  
    44.                         if((PWM_TIMER_CURRENT >= old_capture && PWM_TIMER_CURRENT < new_capture) || (PWM_TIMER_CURRENT < old_capture && PWM_TIMER_CURRENT >= new_capture))  
    45.                         {  
    46.                             NRF_GPIOTE->TASKS_OUT[pwm_gpiote_channel[i]] = 1;  
    47.                         }  
    48.                         PWM_TIMER->CC[i] = new_capture;  
    49.                     }  
    50.                 }  
    51.                 else  
    52.                 {  
    53.                     new_capture = pwm_next_value[i];  
    54.                     old_capture = PWM_TIMER2->CC[i-2];  
    55.                     if(!pwm_running[i])  
    56.                     {  
    57.                         nrf_gpiote_task_config(pwm_gpiote_channel[i], pwm_io_ch[i], NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH);    
    58.                         pwm_running[i] = 1;  
    59.                         PWM_TIMER2->TASKS_CAPTURE[3] = 1;  
    60.                         if(PWM_TIMER2->CC[3] > new_capture) NRF_GPIOTE->TASKS_OUT[pwm_gpiote_channel[i]] = 1;  
    61.                         PWM_TIMER2->CC[i-2] = new_capture;  
    62.                     }  
    63.                     else  
    64.                     {  
    65.                         while(1)  
    66.                         {  
    67.                             PWM_TIMER2->TASKS_CAPTURE[3] = 1;  
    68.                             if(safe_margins_present(PWM_TIMER2_CURRENT, old_capture) && safe_margins_present(PWM_TIMER2_CURRENT, new_capture)) break;  
    69.                         }  
    70.                         if((PWM_TIMER2_CURRENT >= old_capture && PWM_TIMER2_CURRENT < new_capture) || (PWM_TIMER2_CURRENT < old_capture && PWM_TIMER2_CURRENT >= new_capture))  
    71.                         {  
    72.                             NRF_GPIOTE->TASKS_OUT[pwm_gpiote_channel[i]] = 1;  
    73.                         }  
    74.                         PWM_TIMER2->CC[i-2] = new_capture;  
    75.                     }                      
    76.                 }  
    77.             }  
    78.         }  
    79.     }  
     
    void PWM_IRQHandler(void)
    {
        static uint32_t i, new_capture, old_capture;
        PWM_TIMER->CC[2] = pwm_max_value = pwm_next_max_value;
        if(pwm_num_channels > 2) PWM_TIMER2->CC[2] = pwm_max_value;
        for(i = 0; i < pwm_num_channels; i++)
        {
            if(pwm_modified[i])
            {
                pwm_modified[i] = false;
                if(pwm_next_value[i] == 0)
                {
                    nrf_gpiote_unconfig(pwm_gpiote_channel[i]);
                    nrf_gpio_pin_write(pwm_io_ch[i], 0);
                    pwm_running[i] = 0;
                }
                else if (pwm_next_value[i] >= pwm_max_value)
                {
                    nrf_gpiote_unconfig(pwm_gpiote_channel[i]);
                    nrf_gpio_pin_write(pwm_io_ch[i], 1); 
                    pwm_running[i] = 0;
                }
                else
                {
                    if(i < 2)
                    {
                        new_capture = pwm_next_value[i];
                        old_capture = PWM_TIMER->CC[i];
                        if(!pwm_running[i])
                        {
                            nrf_gpiote_task_config(pwm_gpiote_channel[i], pwm_io_ch[i], NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH);  
                            pwm_running[i] = 1;
                            PWM_TIMER->TASKS_CAPTURE[3] = 1;
                            if(PWM_TIMER->CC[3] > new_capture) NRF_GPIOTE->TASKS_OUT[pwm_gpiote_channel[i]] = 1;
                            PWM_TIMER->CC[i] = new_capture;
                        }
                        else
                        {
                            while(1)
                            {
                                PWM_TIMER->TASKS_CAPTURE[3] = 1;
                                if(safe_margins_present(PWM_TIMER_CURRENT, old_capture) && safe_margins_present(PWM_TIMER_CURRENT, new_capture)) break;
                            }
                            if((PWM_TIMER_CURRENT >= old_capture && PWM_TIMER_CURRENT < new_capture) || (PWM_TIMER_CURRENT < old_capture && PWM_TIMER_CURRENT >= new_capture))
                            {
                                NRF_GPIOTE->TASKS_OUT[pwm_gpiote_channel[i]] = 1;
                            }
                            PWM_TIMER->CC[i] = new_capture;
                        }
                    }
                    else
                    {
                        new_capture = pwm_next_value[i];
                        old_capture = PWM_TIMER2->CC[i-2];
                        if(!pwm_running[i])
                        {
                            nrf_gpiote_task_config(pwm_gpiote_channel[i], pwm_io_ch[i], NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH);  
                            pwm_running[i] = 1;
                            PWM_TIMER2->TASKS_CAPTURE[3] = 1;
                            if(PWM_TIMER2->CC[3] > new_capture) NRF_GPIOTE->TASKS_OUT[pwm_gpiote_channel[i]] = 1;
                            PWM_TIMER2->CC[i-2] = new_capture;
                        }
                        else
                        {
                            while(1)
                            {
                                PWM_TIMER2->TASKS_CAPTURE[3] = 1;
                                if(safe_margins_present(PWM_TIMER2_CURRENT, old_capture) && safe_margins_present(PWM_TIMER2_CURRENT, new_capture)) break;
                            }
                            if((PWM_TIMER2_CURRENT >= old_capture && PWM_TIMER2_CURRENT < new_capture) || (PWM_TIMER2_CURRENT < old_capture && PWM_TIMER2_CURRENT >= new_capture))
                            {
                                NRF_GPIOTE->TASKS_OUT[pwm_gpiote_channel[i]] = 1;
                            }
                            PWM_TIMER2->CC[i-2] = new_capture;
                        }                    
                    }
                }
            }
        }

    然后运行一下~会看见占空比不同,两个led灯的亮度不同。占空比为255的LED_1要比占空比为20的LED_1亮

  • 相关阅读:
    廖大python实战项目第六天
    廖大python实战教程第七天
    廖大python实战项目第五天
    Map的遍历方法及字符计数
    事务详解
    java设计模式详解
    程序员常见一些英文缩写
    Hibernate小笔记
    Myeclipse有关的问题
    hibernate对象的三种状态及转换
  • 原文地址:https://www.cnblogs.com/ldgforever/p/5854179.html
Copyright © 2011-2022 走看看