NRF52832输出互补PWM

特别说明:本文章需要使用过此pwm模块才会看明白,小白还是先去看看NRF52832芯片的pwm模块,如何再来看如何输出互补pwm。

初步使用NRF52832芯片的pwm模块,因为模块不能直接输出互补pwm,实现思路是用中央对齐方式去实现。

互补pwm有啥用,哈哈哈,旱的旱死,****

先看看pwm的一些工作模式:

要先理解这几种模式的特点

1-共用模式:4个通道共用极性,比较值,意思就是说4路pwm的方向一样,占空比一样

2-分组模式:2个通道分组共用一个极性和比较值,和共用模式类似,只是分成了2分

3-独立加载模式:每个通道极性独立,比较值独立,就是说可以随意改变占空比,和输出方向

4-波形模式:这个模式下只能使用前3个通道,后一个通道RAM用做计数值,也就是计数周期,即频率。(后面会用到这个)

------------------------

使用过这个芯片的pwm模块的看到这应该不陌生。

下面再说一下pwm模块的计数方式,这个也是实现互补的关键

1-向上计数  :计数器从0 -  count

2-向下计数  :计数器从count -0

3-中心对齐计数,先向上计数,如何向下计数,所以整个周期会变成长,即频率会变成其它两种的一半,(要实现双边死区,需要使用这一种)

直接看代码吧:

#include <stdio.h>
#include <string.h>
#include "nrf_drv_pwm.h"
#include "app_util_platform.h"
#include "app_error.h"
#include "boards.h"
//#include "bsp.h"
#include "nrf_delay.h"
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"

static nrf_drv_pwm_t m_pwm0 = NRF_DRV_PWM_INSTANCE(0);


// This is for tracking PWM instances being used, so we can unintialize only
// the relevant ones when switching from one demo to another.
#define USED_PWM(idx) (1UL << idx)
static uint8_t m_used = 0;

static uint16_t /*const*/ seq_values[] =
    {
        0<<15|1500,
				1<<15|1000,
				0<<15|1000,
				2000
    };
nrf_pwm_sequence_t  seq =
{
		.values.p_common = seq_values,//要回放的序列
		.length          = NRF_PWM_VALUES_LENGTH(seq_values),//长度
		.repeats         = 0,//重复次数为0
		.end_delay       = 0//结束的时候是否需要增加附带周期
};

static nrf_drv_pwm_config_t  config0 =
    {
        .output_pins =
        {
            BSP_LED_0 | NRF_DRV_PWM_PIN_INVERTED, // channel 0 
            BSP_LED_1 | NRF_DRV_PWM_PIN_INVERTED, // 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_16MHz,//  16MHz
				.count_mode   = PWM_MODE_UPDOWN_UpAndDown,//计数模式 中心对齐
        .top_value    = 2500,//计数器定点值,决定周期
				.load_mode    = NRF_PWM_LOAD_WAVE_FORM,//波形模式
        .step_mode    = NRF_PWM_STEP_AUTO//自动,重复次数后刷新
    };

static void demo(void)
{
    NRF_LOG_INFO("Demo");

    
    APP_ERROR_CHECK(nrf_drv_pwm_init(&m_pwm0, &config0, NULL));//初始化PWM
	
    m_used |= USED_PWM(0);//使用PWM0模块

       
   (void)nrf_drv_pwm_simple_playback(&m_pwm0, &seq, 1, NRF_DRV_PWM_FLAG_LOOP);

		

}


static int AARcount =200;    //这个就是计数周期,即pwm频率

static void demo1(void)
{
    
		char deal =10;          //这里就是死区时间了
    seq_values[0]=1<<15|AARcount/2;			//通道0极性为1 ,比较值是计数值的一半,即占空比是50%
    seq_values[1]=0<<15|AARcount/2+deal;  //通道1极性为0
		
		seq_values[3]=AARcount;        //最大计算值



}

static void demo2(void)
{
    
    seq_values[0]=1<<15|AARcount/2;
    seq_values[1]=0<<15|AARcount/2+10;
		
		seq_values[3]=AARcount;

  

}

		


//主函数,调用PWM输出。

int main(void)
{
    APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
    NRF_LOG_DEFAULT_BACKENDS_INIT();

    NRF_LOG_INFO("PWM example started.");
    demo();
		
    for (;;)
    {
				//demo2();
				nrf_delay_ms(2000);
				demo1();
				nrf_delay_ms(2000);

        NRF_LOG_FLUSH();
    }
}


/** @} */

这个代码是清风的例子改的,基本思路就是使用中央对齐,然后两个通道极性输出相反即可实现互补pwm,关键只要理解前面提到的pwm模块的两个特点即可。

实际波形如下,可以看到高低变化的时候有明显的死区,可以自行软件调节死区大小。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值