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 = 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的頻率。

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_instance     Pointer to the driver instance structure.
 * @param[in] p_sequence     Sequence to be played back.
 * @param[in] playback_count Number of playbacks to be performed (must not be 0).
 * @param[in] flags          Additional 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 * const   p_instance,
                                  nrf_pwm_sequence_t const * p_sequence,
                                  uint16_t                   playback_count,
                                  uint32_t                   flags);

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);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章