打造一个通用性MCU架构,支持CX32/AT32/NRF51/NRF52等。 OS支持RTX4/RTX5/FreeRtos。 采用VsCode+GCC组合,VsCode+KEIL5,超强开发方式。 QQ群:524408033

LiSun

打造一个通用性MCU架构,支持CX32/AT32/NRF51/NRF52等。 OS支持RTX4/RTX5/FreeRtos。 采用VsCode+GCC组合,VsCode+KEIL5,超强开发方式。 QQ群:524408033

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

NRF51系列的PWM是由TIM+PPI+GPIO组成的,下面依次介绍:

Programmable Peripheral Interconnect (PPI)

The Programmable Peripheral Interconnect (PPI) enables peripherals to interact autonomously with each other using tasks and events independent of the CPU. The PPI allows precise synchronization between peripherals when real-time application constraints exist and eliminates the need for CPU activity to implement behavior which can be predefined using PPI.

可编程外设互连(PPI)使外设能够使用独立于CPU的任务和事件相互自主交互。 当存在实时应用限制时,PPI允许外设之间的精确同步,并消除了CPU活动实现行为的需要,这些行为可以使用PPI预定义。

The PPI system has in addition to the fully programmable peripheral interconnections, a set of channels where the event (EEP) and task (TEP) endpoints are set in hardware. These fixed channels can be individually enabled, disabled, or added to PPI channel groups in the same way as ordinary PPI channels. See the nRF51 Series Reference Manual for more information.

除了完全可编程的外设互连外,PPI系统还有一组通道,事件(EEP)和任务(TEP)端点在硬件中设置。 这些固定通道可以像普通PPI通道一样单独启用、禁用或添加到PPI通道组。

Timer/counters (TIMER)

The timer/counter runs on the high-frequency clock source (HFCLK) and includes a 4 bit (1/2X) prescaler that can divide the HFCLK.

The TIMER will start requesting the 1 MHz mode of the HFCLK for values of the prescaler that gives fTIMER less or equal to 1 MHz. If the timer module is the only one requesting the HFCLK, the system will automatically switch to using the 1 MHz mode resulting in a decrease in the current consumption. See the parameters I1v2XO16,1M, I1v2XO32,1M, I1v2RC16,1M in Table 32 on page 48 and ITIMER0/1/2,1M in Table 52 on page 62.

The task/event and interrupt features make it possible to use the PPI system for timing and counting tasks between any system peripheral including any GPIO of the device. The PPI system also enables the TIMER task/event features to generate periodic output and PWM signals to any GPIO. The number of input/outputs used at the same time is limited by the number of GPIOTE channels.

定时器/计数器运行在高频时钟源(HFCLK)上,包括一个4位(1/2X)预分器,可以分割HFCLK。

TIMER将开始请求HFCLK的1 MHz模式,以获取使fTIMER小于或等于1 MHz的预分频器的值。 如果定时器模块是唯一一个请求HFCLK的模块,系统将自动切换到使用1 MHz模式,导致当前消耗减少。 参见第48页表32中的I1v2XO16,1M, I1v2XO32,1M, I1v2RC16,1M和第62页表52中的ITIMER0/1/2,1M参数。

任务/事件和中断特性使PPI系统能够在任何系统外设(包括设备的任何GPIO)之间对任务进行计时和计数。 PPI系统还使TIMER任务/事件功能产生周期性输出和PWM信号到任何GPIO。 同时使用的输入/输出数量受GPIOTE通道数量的限制。

InstanceBit-widthCapture/Compare registers
TIMER08/16/24/324
TIMER18/164
TIMER28/164
  • TIMER0不推荐当PWM使用,因为ble协议栈中使用了。

[nrf52] low_power_pwm pwm_library pwm_driver 三者区别

/********************************************************************************
* @file    bsp_pwm.c
* @author  jianqiang.xue
* @version V1.0.0
* @date    2021-08-10
* @brief   参考:https://blog.csdn.net/zhi_Alanwu/article/details/102972721
********************************************************************************/

/* Includes ------------------------------------------------------------------*/
#include <stdbool.h>
#include <stdint.h>

#include "RTE_Components.h"
#include CMSIS_device_header
#include "app_pwm.h"
#include "bsp_gpio.h"
#include "bsp_pwm.h"


/* Private Includes ----------------------------------------------------------*/
#include "business_gpio.h"
#include "business_function.h"

/* Private Variables ---------------------------------------------------------*/
static bool g_pwm_init = false;

#if BS_TIM1_EN
// Create the instance "PWM1" using TIMER1.
APP_PWM_INSTANCE(PWM1, 1);
/* 2-channel PWM*/
static app_pwm_config_t pwm1_cfg = APP_PWM_DEFAULT_CONFIG_2CH(BS_TIM1_PRESCALER, BS_TIM1_CH1_PIN, BS_TIM1_CH2_PIN);
#endif

#if BS_TIM2_EN
// Create the instance "PWM2" using TIMER2.
APP_PWM_INSTANCE(PWM2, 2);
/* 2-channel PWM*/
static app_pwm_config_t pwm2_cfg = APP_PWM_DEFAULT_CONFIG_2CH(BS_TIM2_PRESCALER, BS_TIM2_CH1_PIN, BS_TIM2_CH2_PIN);
#endif

/* Public Function Prototypes -----------------------------------------------*/
/**
 * @brief  PWN功能初始化,使用定时器和ppi来模拟PWM功能
 * @note   NULL
 * @retval None
 */
void bsp_pwm_init(void)
{
    if (g_pwm_init)
    {
        return;
    }

#if BS_TIM1_EN
    pwm1_cfg.pin_polarity[0] = (app_pwm_polarity_t)BS_TIM1_LEVEL_LOGIC;
    pwm1_cfg.pin_polarity[1] = (app_pwm_polarity_t)BS_TIM1_LEVEL_LOGIC;
    /* Initialize and enable PWM. */
    APP_ERROR_CHECK(app_pwm_init(&PWM1, &pwm1_cfg, NULL));
    app_pwm_enable(&PWM1);
    g_pwm_init = true;
#endif

#if BS_TIM2_EN
    pwm2_cfg.pin_polarity[0] = (app_pwm_polarity_t)BS_TIM2_LEVEL_LOGIC;
    pwm2_cfg.pin_polarity[1] = (app_pwm_polarity_t)BS_TIM2_LEVEL_LOGIC;
    /* Initialize and enable PWM. */
    APP_ERROR_CHECK(app_pwm_init(&PWM2, &pwm2_cfg, NULL));
    app_pwm_enable(&PWM2);
    g_pwm_init = true;
#endif
}

/**
 * @brief  PWN功能关闭
 * @note   NULL
 * @retval None
 */
void bsp_pwm_deinit(void)
{
    if (!g_pwm_init)
    {
        return;
    }
#if BS_TIM1_EN
    app_pwm_disable(&PWM1);
    app_pwm_uninit(&PWM1);
    g_pwm_init = false;
#endif
#if BS_TIM2_EN
    app_pwm_disable(&PWM2);
    app_pwm_uninit(&PWM2);
    g_pwm_init = false;
#endif
}

/**
 * @brief  设置PWM占空比
 * @note   NULL
 * @param  pwmx: PWM组号
 * @param  val: 0-100 PWM值
 * @retval None
 */
void bsp_pwm_set_pulse(bsp_pwm_t pwmx, uint16_t val)
{
#if BS_TIM1_EN || BS_TIM2_EN
    if (!g_pwm_init)
    {
        return;
    }
#endif
    if (pwmx == BSP_PWM_0)
    {
#if BS_TIM1_EN && BS_PWM0_EN
        app_pwm_channel_duty_set(&PWM1, 0, val);
#endif
    }
    else if (pwmx == BSP_PWM_1)
    {
#if BS_TIM1_EN && BS_PWM1_EN
        app_pwm_channel_duty_set(&PWM1, 1, val);
#endif
    }
    else if (pwmx == BSP_PWM_2)
    {
#if BS_TIM2_EN && BS_PWM2_EN
        app_pwm_channel_duty_set(&PWM2, 0, val);
#endif
    }
    else if (pwmx == BSP_PWM_3)
    {
#if BS_TIM2_EN && BS_PWM3_EN
        app_pwm_channel_duty_set(&PWM2, 1, val);
#endif
    }
}

/********************************************************************************
* @file    bsp_pwm.h
* @author  jianqiang.xue
* @version V1.0.0
* @date    2021-04-18
* @brief   NULL
********************************************************************************/

#ifndef __BSP_PWM_H
#define __BSP_PWM_H

/* Includes ------------------------------------------------------------------*/
#include <stdint.h>

/* Public enum ---------------------------------------------------------------*/
typedef enum
{
    BSP_PWM_0 = 0,
    BSP_PWM_1,
    BSP_PWM_2,
    BSP_PWM_3,
    BSP_PWM_4,
    BSP_PWM_5,
    BSP_PWM_6,
    BSP_PWM_7,
    BSP_PWM_8,
    BSP_PWM_9,
    BSP_PWM_10,
    BSP_PWM_11
} bsp_pwm_t;

/* Public Function Prototypes ------------------------------------------------*/

void bsp_pwm_init(void);
void bsp_pwm_deinit(void);

void bsp_pwm_set_pulse(bsp_pwm_t pwmx, uint16_t val);

#endif

posted on 2022-08-13 11:00  xuejianqiang  阅读(56)  评论(0编辑  收藏  举报
打造一个通用性MCU架构,支持CX32/AT32/NRF51/NRF52等。 OS支持RTX4/RTX5/FreeRtos。 采用VsCode+GCC组合,VsCode+KEIL5,超强开发方式。 QQ群:524408033