/**
|
* @file pwm.c
|
* @author Ethan.Tao (tzj0429@163.com)
|
* @brief
|
* @version 0.1
|
* @date 2020-12-12
|
*
|
* @copyright Copyright (c)
|
*
|
*/
|
#include "pwm.h"
|
|
/*****************************************************************************************************
|
Timer2 is used to capture hall input
|
APB1 is 48M ,so Timer0 clock is 48M,after prescaler 480 is 0.1M(10us)
|
input pin:
|
PA15-CO
|
PB4-AO
|
PB5-BO
|
*****************************************************************************************************/
|
static void Timer2Init(void)
|
{
|
|
timer_ic_parameter_struct capturecfg[2];
|
timer_parameter_struct timercontralcfg;
|
|
timer_deinit(TIMER2);
|
|
capturecfg[0].icfilter = 0; //no filter
|
capturecfg[0].icpolarity = TIMER_IC_POLARITY_BOTH_EDGE; //both edge
|
capturecfg[0].icprescaler = TIMER_IC_PSC_DIV1;
|
capturecfg[0].icselection = TIMER_IC_SELECTION_DIRECTTI; //input and icy is mapped on TIy
|
|
capturecfg[1].icfilter = 0;
|
capturecfg[1].icpolarity = TIMER_IC_POLARITY_BOTH_EDGE;
|
capturecfg[1].icprescaler = TIMER_IC_PSC_DIV1;
|
capturecfg[1].icselection = TIMER_IC_SELECTION_DIRECTTI;
|
|
timercontralcfg.prescaler = 0;
|
timercontralcfg.alignedmode = 0;
|
timercontralcfg.counterdirection = 0;
|
timercontralcfg.period = PERIOD_CAP;
|
|
timer_input_capture_config(TIMER2, TIMER_CH_0, &capturecfg[0]);
|
timer_input_capture_config(TIMER2, TIMER_CH_1, &capturecfg[1]);
|
|
timer_init(TIMER2, &timercontralcfg);
|
|
timer_interrupt_flag_clear(TIMER2, TIMER_INT_CH0);
|
timer_interrupt_flag_clear(TIMER2, TIMER_INT_CH1);
|
timer_interrupt_flag_clear(TIMER2, TIMER_INT_TRG);
|
|
timer_interrupt_enable(TIMER2, TIMER_INT_CH0);
|
timer_hall_mode_config(TIMER2, TIMER_HALLINTERFACE_ENABLE);
|
timer_interrupt_enable(TIMER2, TIMER_INT_TRG);
|
nvic_irq_enable(TIMER2_IRQn, 1);
|
timer_prescaler_config(TIMER2, 47, TIMER_PSC_RELOAD_NOW); //48Mhz /48 =1Mhz = 1us
|
}
|
|
/*****************************************************************************************************
|
Timer0 is used to generente PWM
|
APB2 is 48M and prescaler is 1,so Timer0 clock is 48M
|
output pin:
|
PA10-HIN1-TIME0_CH2
|
PA9 -HIN2-TIME0_CH1
|
PA8 -HIN3-TIME0_CH0
|
PB1-LIN1-TIME0_CH2_N
|
PB0-LIN2-TIME0_CH0_N
|
PA7-LIN3-TIME0_CH0_N
|
*****************************************************************************************************/
|
static void Timer0Init(void)
|
{
|
uint16_t Duty = 0;
|
timer_parameter_struct timercontralcfg;
|
timer_oc_parameter_struct timeroutcfg[3];
|
|
//config timer0
|
timercontralcfg.prescaler = 0; //counter prescaler is 0
|
timercontralcfg.alignedmode = TIMER_COUNTER_CENTER_UP; //center align and counter style depend on dir set
|
timercontralcfg.counterdirection = TIMER_COUNTER_UP; //counter style is up
|
timercontralcfg.clockdivision = TIMER_CKDIV_DIV1; //Timer0 is 48M
|
timercontralcfg.period = PERIOD_CMP; // set period(counter value 0~2^15)
|
timer_init(TIMER0, &timercontralcfg);
|
|
timeroutcfg[0].ocpolarity = TIMER_OC_POLARITY_HIGH; //channel output polarity is high
|
timeroutcfg[0].ocnpolarity = TIMER_OCN_POLARITY_HIGH;
|
timeroutcfg[0].outputstate = TIMER_CCX_ENABLE; //channel enable
|
timeroutcfg[0].outputnstate = TIMER_CCXN_ENABLE; //channel complementary enable
|
timeroutcfg[0].ocidlestate = TIMER_OC_IDLE_STATE_LOW;
|
timeroutcfg[0].ocnidlestate = TIMER_OCN_IDLE_STATE_HIGH;
|
|
timeroutcfg[1].ocpolarity = TIMER_OC_POLARITY_HIGH; //channel output polarity is high
|
timeroutcfg[1].ocnpolarity = TIMER_OCN_POLARITY_HIGH;
|
timeroutcfg[1].outputstate = TIMER_CCX_ENABLE; //channel enable
|
timeroutcfg[1].outputnstate = TIMER_CCXN_ENABLE; //channel complementary enable
|
timeroutcfg[1].ocidlestate = TIMER_OC_IDLE_STATE_LOW;
|
timeroutcfg[1].ocnidlestate = TIMER_OCN_IDLE_STATE_HIGH;
|
|
timeroutcfg[2].ocpolarity = TIMER_OC_POLARITY_HIGH; //channel output polarity is high
|
timeroutcfg[2].ocnpolarity = TIMER_OCN_POLARITY_HIGH;
|
timeroutcfg[2].outputstate = TIMER_CCX_ENABLE; //channel enable
|
timeroutcfg[2].outputnstate = TIMER_CCXN_ENABLE; //channel complementary enable
|
timeroutcfg[2].ocidlestate = TIMER_OC_IDLE_STATE_LOW;
|
timeroutcfg[2].ocnidlestate = TIMER_OCN_IDLE_STATE_HIGH;
|
|
timer_channel_output_config(TIMER0, TIMER_CH_0, &timeroutcfg[0]);
|
timer_channel_output_config(TIMER0, TIMER_CH_1, &timeroutcfg[1]);
|
timer_channel_output_config(TIMER0, TIMER_CH_2, &timeroutcfg[2]);
|
|
timer_channel_output_pulse_value_config(TIMER0, TIMER_CH_0, Duty); //set duty
|
timer_channel_output_pulse_value_config(TIMER0, TIMER_CH_1, Duty);
|
timer_channel_output_pulse_value_config(TIMER0, TIMER_CH_2, Duty);
|
|
timer_channel_output_mode_config(TIMER0, TIMER_CH_0, TIMER_OC_MODE_PWM1); //set pwm1 mode
|
timer_channel_output_mode_config(TIMER0, TIMER_CH_1, TIMER_OC_MODE_PWM1);
|
timer_channel_output_mode_config(TIMER0, TIMER_CH_2, TIMER_OC_MODE_PWM1);
|
|
timer_channel_output_shadow_config(TIMER0, TIMER_CH_0, TIMER_OC_SHADOW_DISABLE); //shadow disable
|
timer_channel_output_shadow_config(TIMER0, TIMER_CH_1, TIMER_OC_SHADOW_DISABLE);
|
timer_channel_output_shadow_config(TIMER0, TIMER_CH_2, TIMER_OC_SHADOW_DISABLE);
|
|
timer_interrupt_enable(TIMER0, TIMER_INT_CH0);
|
timer_interrupt_enable(TIMER0, TIMER_INT_CH1);
|
timer_interrupt_enable(TIMER0, TIMER_INT_CH2);
|
|
timer_primary_output_config(TIMER0, ENABLE);
|
timer_auto_reload_shadow_enable(TIMER0);
|
}
|
|
void TimerInit(void)
|
{
|
// rcu_periph_clock_enable(RCU_TIMER2);
|
rcu_periph_clock_enable(RCU_TIMER0);
|
Timer0Init();
|
// Timer2Init();
|
timer_enable(TIMER0);
|
// timer_enable(TIMER2);
|
}
|
|
void SetPwmDuty(uint16_t ch, uint32_t duty)
|
{
|
timer_channel_output_pulse_value_config(TIMER0, ch, duty);
|
}
|
|
void SetPwmPeriod(uint32_t period)
|
{
|
TIMER_CAR(TIMER0) = period;
|
}
|