This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Pwm minimum frequency setting

hi, I would like to use pwm to output the 1HZ waveform to drive the motor, but when I set the frequency to be 1HZ, I can not find the device and cause 51822 to reset. This is my code:

    Motor_Pwm_Init(1000000,1,1);
    Motor_Duty_Set(50,50);

    void Motor_Pwm_Init(uint32_t freq,uint32_t MotorLeft_Polarity,uint32_t MotorRight_Polarity)
{

	uint32_t err_code;
	
	app_pwm_disable(&PWM1);
	app_pwm_uninit(&PWM1);
	app_pwm_config_t pwm1_cfg = APP_PWM_DEFAULT_CONFIG_2CH(freq,MOTOR_LEFT_PIN,MOTOT_RIGHT_PIN);   //set pwm frequency	
	
	pwm1_cfg.pin_polarity[0] = MotorLeft_Polarity;					//Polarity of active state on pin.
    pwm1_cfg.pin_polarity[1] = MotorRight_Polarity;
	
	err_code = app_pwm_init(&PWM1,&pwm1_cfg,NULL);																						//  Init the PWM
    APP_ERROR_CHECK(err_code);

	app_pwm_enable(&PWM1);	
	
}

    uint8_t Motor_Duty_Set(uint32_t DutyLeft,uint32_t DutyRight)
{
	uint8_t TimeOut = 0;
	wdt_feed();
	while (app_pwm_channel_duty_set(&PWM1,(uint8_t) 0, DutyLeft) == NRF_ERROR_BUSY)
	{
		
	}
}
  • I used the pwm_library example in the SDK. This is the main.c code I used:

    #include <stdbool.h>
    #include <stdint.h>
    #include "nrf.h"
    #include "app_error.h"
    #include "bsp.h"
    #include "nrf_delay.h"
    #include "app_pwm.h"
    
    APP_PWM_INSTANCE(PWM1,1);                   // Create the instance "PWM1" using TIMER1.
    
    
     void Motor_Pwm_Init(uint32_t freq,uint32_t MotorLeft_Polarity,uint32_t MotorRight_Polarity)
    {
    
        uint32_t err_code;
    
        app_pwm_disable(&PWM1);
        app_pwm_uninit(&PWM1);
        app_pwm_config_t pwm1_cfg = APP_PWM_DEFAULT_CONFIG_2CH(freq,3,4);   //set pwm frequency  
    
        pwm1_cfg.pin_polarity[0] = MotorLeft_Polarity;                  //Polarity of active state on pin.
        pwm1_cfg.pin_polarity[1] = MotorRight_Polarity;
    
        err_code = app_pwm_init(&PWM1,&pwm1_cfg,NULL);           //  Init the PWM
        APP_ERROR_CHECK(err_code);
    
        app_pwm_enable(&PWM1);  
    
    }
    
    uint8_t Motor_Duty_Set(uint32_t DutyLeft,uint32_t DutyRight)
    {
        uint8_t TimeOut = 0;
        //wdt_feed();
        while (app_pwm_channel_duty_set(&PWM1,(uint8_t) 0, DutyLeft) == NRF_ERROR_BUSY)
        {
    
        }
        
        while (app_pwm_channel_duty_set(&PWM1,(uint8_t) 1, DutyLeft) == NRF_ERROR_BUSY)
        {
    
        }
    }
    
    int main(void)
    {
        
        Motor_Pwm_Init(1000000,1,1);
        Motor_Duty_Set(50,50);
        
        while (true)
        {
    
        }
    
    }
    
    
    /** @} */
    
  • Through repeated tests, I found the problem is that when I only set a pin of duty, it is working properly, but the two set at the same time duty, the program stuck, and then reset

    uint8_t Motor_Duty_Set(uint32_t DutyLeft,uint32_t DutyRight)
    

    { uint8_t TimeOut = 0; //wdt_feed(); while (app_pwm_channel_duty_set(&PWM1,(uint8_t) 0, DutyLeft) == NRF_ERROR_BUSY) { wdt_feed(); #if 0 if(TimeOut ++ > 200) { TimeOut = 0; return 0; } #endif }

    wdt_feed();
    #if 0
    while (app_pwm_channel_duty_set(&PWM1,(uint8_t) 1, DutyRight) == NRF_ERROR_BUSY)
    {
    	#if 0
    	if(TimeOut ++ > 200)
    	{
    		TimeOut = 0;
    		return 0;	
    	}	
    	#endif
    }
    #endif
    //wdt_feed();
    //return 1;
    

    }

    So that you can work and output the correct 1hz waveform, should I only open the left, the right side of the code shielded

    But when I try to set the duty cycle of both channels, the device is reset, the code is as follows

    uint8_t Motor_Duty_Set(uint32_t DutyLeft,uint32_t DutyRight)
    

    { uint8_t TimeOut = 0; //wdt_feed(); while (app_pwm_channel_duty_set(&PWM1,(uint8_t) 0, DutyLeft) == NRF_ERROR_BUSY) { wdt_feed(); #if 0 if(TimeOut ++ > 200) { TimeOut = 0; return 0; } #endif }

    wdt_feed();
    #if 1
    while (app_pwm_channel_duty_set(&PWM1,(uint8_t) 1, DutyRight) == NRF_ERROR_BUSY)
    {
    	#if 0
    	if(TimeOut ++ > 200)
    	{
    		TimeOut = 0;
    		return 0;	
    	}	
    	#endif
    }
    #endif
    //wdt_feed();
    //return 1;
    

    }

    enter code here
    
  • Could it be a timeout from the WDT that is causing the issues?

    See this post about how to debug and find the reason for the reset.

Related