接口放在driver_pwm.c
参数:两路pwm的通道、频率、占空比、占空比等级(如100级、255级等)
注意占空比等级要和pwm_init和pwm_update里面的相同
void pwm_update_complementation_ctrl(enum pwm_channel_t channel_a, uint32_t frequency_a, uint16_t high_duty_a,
enum pwm_channel_t channel_b, uint32_t frequency_b, uint16_t high_duty_b, uint16_t duty_cycle_lvl)
{
enum pwm_channel_t chl_tmp = (high_duty_a > high_duty_b)?channel_b:channel_a;
enum pwm_channel_t chl_delay_start;
uint32_t frequency_x,frequency_y;
uint16_t high_duty_x,high_duty_y;
uint32_t delay_cnt = 0;
if(chl_tmp == channel_a)
{
chl_delay_start = channel_b;
frequency_x = frequency_a;
high_duty_x = high_duty_a;
frequency_y = frequency_b;
high_duty_y = high_duty_b;
}
else
{
chl_delay_start = channel_a;
frequency_x = frequency_b;
high_duty_x = high_duty_b;
frequency_y = frequency_a;
high_duty_y = high_duty_a;
}
// co_printf("chl_tmp:%d %d %d\r\n",chl_tmp,pwm_ctrl->channel[chl_tmp].cur_cnt,pwm_ctrl->channel[chl_tmp].total_cnt);
GLOBAL_INT_DISABLE();
pwm_ctrl->channel[chl_delay_start].ctrl.en = 0;
pwm_ctrl->channel[chl_delay_start].ctrl.out_en = 0;
pwm_ctrl->channel[chl_tmp].ctrl.en = 0;
pwm_ctrl->channel[chl_tmp].ctrl.out_en = 0;
pwm_init(chl_delay_start,frequency_y,high_duty_y);
pwm_init(chl_tmp,frequency_x,high_duty_x);
pwm_ctrl->channel[chl_tmp].cur_cnt = 0;
pwm_ctrl->channel[chl_delay_start].cur_cnt = 0;
pwm_ctrl->channel[chl_delay_start].ctrl.out_en = 1;
pwm_ctrl->channel[chl_delay_start].ctrl.en = 1;
pwm_ctrl->channel[chl_tmp].ctrl.out_en = 1;
pwm_ctrl->channel[chl_tmp].ctrl.en = 1;
//delay_cnt = pwm_ctrl->channel[chl_tmp].total_cnt * ((duty_cycle_lvl-high_duty_a) - (duty_cycle_lvl-high_duty_b-high_duty_a)/2)/duty_cycle_lvl;
delay_cnt = pwm_ctrl->channel[chl_tmp].total_cnt * (duty_cycle_lvl+high_duty_y-high_duty_x)/(2*duty_cycle_lvl);
//co_printf("delay_cnt:%d %d %d\r\n",delay_cnt,pwm_ctrl->channel[chl_tmp].cur_cnt,pwm_ctrl->channel[chl_tmp].total_cnt);
while(pwm_ctrl->channel[chl_tmp].cur_cnt < delay_cnt)
pwm_ctrl->channel[chl_delay_start].cur_cnt = 1;
GLOBAL_INT_RESTORE();
}
/**************************************以下为旧版本********************************************/
high1_duty < 50%
high2_duty > 50%
high1_duty+high2_duty < 100%
duty_cycle_lvl = 100
delay = low1_t-(low2_t-high1_t)/2
delay = (total_t-high1_t) - (total_t-high2_t-high1_t)/2 = total_t/2 + high2_t/2 - high1_t/2
total_t = 1/period s
high2_t = high2_duty*total_t / duty_cycle_lvl
high1_t = high1_duty*total_t / duty_cycle_lvl
delay = 1/(2*period) + high2_duty/(2*duty_cycle_lvl*period) - high1_duty/(2*duty_cycle_lvl*period)
delay = (1000*1000) * (duty_cycle_lvl+high2_duty- high1_duty)/(2*duty_cycle_lvl*period) // us
start pwm1
delay
start pwm2
uint32_t pwm_set_period = 2000; // 2k
uint8_t duty_cycle1 = 50;
uint8_t duty_cycle2 = 40;
uint16_t duty_cycle_lvl = 100;
void dev_pwm_change(void)
{
uint16_t delay_time = 0;
system_set_port_mux(GPIO_PORT_D, GPIO_BIT_4, PORTD4_FUNC_PWM4);
system_set_port_mux(GPIO_PORT_D, GPIO_BIT_5, PORTD5_FUNC_PWM5);
pwm_stop(PWM_CHANNEL_4);
pwm_stop(PWM_CHANNEL_5);
duty_cycle2 = 90-duty_cycle1;
pwm_init(PWM_CHANNEL_4,pwm_set_period,duty_cycle1);
pwm_init(PWM_CHANNEL_5,pwm_set_period,duty_cycle2);
if(duty_cycle2>duty_cycle1)
{
delay_time = (1000*1000)*(duty_cycle_lvl+duty_cycle2-duty_cycle1)/(2*pwm_set_period*duty_cycle_lvl*10); // unit 10us
pwm_start(PWM_CHANNEL_4);
GLOBAL_INT_DISABLE();
co_delay_10us(delay_time);
pwm_start(PWM_CHANNEL_5);
GLOBAL_INT_RESTORE();
}
else
{
delay_time = (1000*1000)*(duty_cycle_lvl+duty_cycle1-duty_cycle2)/(2*pwm_set_period*duty_cycle_lvl*10); // unit 10us
pwm_start(PWM_CHANNEL_5);
GLOBAL_INT_DISABLE();
co_delay_10us(delay_time);
pwm_start(PWM_CHANNEL_4);
GLOBAL_INT_RESTORE();
}
co_printf("=delay=%dus\r\n",delay_time);
if(duty_cycle1 < 80)
duty_cycle1 += 10;
else
duty_cycle1 = 10;
}
调用参考: