NRF51822自学笔记PWM
Posted 玉缙-Glen
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NRF51822自学笔记PWM相关的知识,希望对你有一定的参考价值。
PWM这个东西我在32上用来电机调速过……通过改变高低电平占空比来实现一些功能。
keil的nrf51822目录下没有pwm.c..就在网上找了个pwm蜂鸣器的例程……看画风应该是官方的……吧……
例程的define为NRF51 SETUPA BOARD_PCA10028..修改一下,设置如下。
- #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);
- }
#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里
- #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};
#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
- 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;
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语句实现了配置………
- 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;
- }
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了。下面是设置占空比的
- 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
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
- 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
- }
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 }
这两个函数功能是一样的……区别在后者先设置好了一组数……
最后看看中断服务函数
- 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;
- }
- }
- }
- }
- }
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亮
以上是关于NRF51822自学笔记PWM的主要内容,如果未能解决你的问题,请参考以下文章
[异常解决] Keil安装好nRF51822开发环境,运行DEMO报错:Error:“GPIOTE_CONFIG_NUM_OF_LOW_POWER_ENVENTS” is undefined(代码片段
[嵌入式方案][nrf51822][LSC-01] BLE模块 从机 AT指令 BLE HID NUS 密码配对 自动回连 电量显示 OTA DFU DTM 定频 4路PWM 2路ADC4路自定义IO
相比于nrf51822蓝牙模块,nrf52832蓝牙模块性能怎么样?