nRF52 PWM 使用

SDK15.2
1. nRF52 PWM 模块 2. 使能PWM模块 在sdk_config.h文件使能PWM Module

#define NRFX_PWM_ENABLED 1 #define PWM_ENABLED 1 #define PWM0_ENABLED 1 #define NRFX_PWM0_ENABLED 0

总共支持4个PWM,分别是 PWM0, PWM1, PWM2, PWM3.
3. 实例化PWM
static nrf_drv_pwm_t m_pwm0 = NRF_DRV_PWM_INSTANCE(0);

4. 初始化PWM
nrf_drv_pwm_config_t const config0 = { .output_pins = { 3 | NRF_DRV_PWM_PIN_INVERTED,// channel 0 NRF_DRV_PWM_PIN_NOT_USED,// channel 1 NRF_DRV_PWM_PIN_NOT_USED,// channel 2 NRF_DRV_PWM_PIN_NOT_USED,// channel 3 }, .irq_priority = APP_IRQ_PRIORITY_LOWEST, .base_clock = NRF_PWM_CLK_500kHz, .count_mode = NRF_PWM_MODE_UP, .top_value = https://www.it610.com/article/800, .load_mode = NRF_PWM_LOAD_COMMON, .step_mode = NRF_PWM_STEP_AUTO}; APP_ERROR_CHECK(nrf_drv_pwm_init(&m_pwm0, &config0, pwm_handler));

配置信息包好输出引脚,中断优先级,基础频率,计数模式,计数最大阈值,加载序列模式和step模式。
4.1 输出引脚设置
  • 使用NRF_DRV_PWM_PIN_INVERTED可以设置空闲引脚的电平为高电平。不使用时空闲引脚的电平为低电平。
  • 不使用引脚,需要设置为NRF_DRV_PWM_PIN_NOT_USED
4.2 加载模式设置
PWM模块可以播放存在RAM中的Multiple duty cycle array(sequences)。也就是存一系列占空比值compare到RAM中,通过Decoder可以把这些值自动写入到寄存器。
  • NRF_PWM_LOAD_COMMON 4通道共用一个配置,通常使用这种模式即可。
  • NRF_PWM_LOAD_GROUPED 1,2通道使用第一个值;3,4通道使用第二个值。依次类推。
  • NRF_PWM_LOAD_INDIVIDUAL 完全独立,1通道对应第一个值,4通道对应第四个值。
  • NRF_PWM_LOAD_WAVE_FORM 1,2,3独立,第四个值写入 top value
4.3 基础频率和顶值设置
基础频率和顶值设置可以决定PWM的频率。
【nRF52 PWM 使用】
4.4 回调函数
typedef enum { NRFX_PWM_EVT_FINISHED, ///< Sequence playback finished. NRFX_PWM_EVT_END_SEQ0, /**< End of sequence 0 reached. Its data can be safely modified now. */ NRFX_PWM_EVT_END_SEQ1, /**< End of sequence 1 reached. Its data can be safely modified now. */ NRFX_PWM_EVT_STOPPED,///< The PWM peripheral has been stopped. } nrfx_pwm_evt_type_t; void brnc_drv_motor_pwm_handler(nrf_drv_pwm_evt_type_t event_type) { if (event_type == NRF_DRV_PWM_EVT_FINISHED) { } }

5. 播放 5.1 播放参数设置
static nrf_pwm_values_common_t seq_values[] = { 0, 200, 400, 600, 800 }; nrf_pwm_sequence_t const seq = { .values.p_common = seq_values, .length= NRF_PWM_VALUES_LENGTH(seq_values), .repeats= 0, .end_delay= 0 };

5.2 播放
nrf_drv_pwm_simple_playback(&m_pwm0, &seq, 3, NRF_DRV_PWM_FLAG_LOOP); nrf_drv_pwm_simple_playback(&m_pwm0, &seq, 3, NRFX_PWM_FLAG_STOP);

/** * @brief Function for starting a single sequence playback. * * To take advantage of the looping mechanism in the PWM peripheral, both * sequences must be used (single sequence can be played back only once by * the peripheral). Therefore, the provided sequence is internally set and * played back as both sequence 0 and sequence 1. Consequently, if end of * sequence notifications are required, events for both sequences should be * used (that means that both the @ref NRFX_PWM_FLAG_SIGNAL_END_SEQ0 flag * and the @ref NRFX_PWM_FLAG_SIGNAL_END_SEQ1 flag should be specified and * the @ref NRFX_PWM_EVT_END_SEQ0 event and the @ref NRFX_PWM_EVT_END_SEQ1 * event should be handled in the same way). * * Use the @ref NRFX_PWM_FLAG_START_VIA_TASK flag if you want the playback * to be only prepared by this function, and you want to start it later by * triggering a task (using PPI for instance). The function will then return * the address of the task to be triggered. * * @note The array containing the duty cycle values for the specified sequence *must be in RAM and cannot be allocated on stack. *For detailed information, see @ref nrf_pwm_sequence_t. * * @param[in] p_instancePointer to the driver instance structure. * @param[in] p_sequenceSequence to be played back. * @param[in] playback_count Number of playbacks to be performed (must not be 0). * @param[in] flagsAdditional options. Pass any combination of *@ref nrfx_pwm_flag_t "playback flags", or 0 *for default settings. * * @return Address of the task to be triggered to start the playback if the @ref *NRFX_PWM_FLAG_START_VIA_TASK flag was used, 0 otherwise. */ uint32_t nrfx_pwm_simple_playback(nrfx_pwm_t const * constp_instance, nrf_pwm_sequence_t const * p_sequence, uint16_tplayback_count, uint32_tflags);

6. 停止与卸载 6.1 停止
bool nrfx_pwm_stop(nrfx_pwm_t const * const p_instance, bool wait_until_stopped);

6.2 卸载
void nrfx_pwm_uninit(nrfx_pwm_t const * const p_instance);

    推荐阅读