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通道数量的限制。
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 #include #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 /* 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
上一篇:[单片机框架][bsp层][nrf51822][nrf51422][nrf51802][bsp_led] LED配置和使用
下一篇:[单片机框架][bsp层][nrf51822][nrf51422][nrf51802][bsp_adc] ADC配置和使用
推荐阅读最新更新时间:2024-11-12 01:24
设计资源 培训 开发板 精华推荐
- DC1996A-F,具有 LTC2321 双路 12 位、2Msps 串行高速 SAR ADC 的演示板
- 140W、320V 交流转直流单路输出电源,用于日光灯镇流器
- 爱心打地鼠:基于stc89c52单片机设计的一块菜菜打地鼠游戏
- DEVKIT-S12ZVC: 9S12ZVCA192 MCU评估开发板
- 用于电源管理的 1.2V、2.7V、3.3V DC 到 DC 多输出电源
- ADS1018IDGST模块
- music-box-8051
- TB2926HQ 45W x 4ch BTL 音频电源典型应用
- 【广西师大校赛】实用音频放大器
- 使用 NXP Semiconductors 的 TDA8933 的参考设计