| | |
| | | * |
| | | */ |
| | | #include "pwm.h" |
| | | |
| | | static volatile uint32_t timer_outcnt = 0; |
| | | /***************************************************************************************************** |
| | | Timer2 is used to capture hall input |
| | | APB1 is 48M ,so Timer0 clock is 48M,after prescaler 480 is 0.1M(10us) |
| | | Timer2 is used to speed cal |
| | | APB1 is 64M ,so Timer2 clock is 64M,after prescaler 480 is 0.1M(10us) |
| | | input pin: |
| | | PA15-CO |
| | | PB4-AO |
| | |
| | | *****************************************************************************************************/ |
| | | 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]); |
| | | timercontralcfg.prescaler = 4799; //48Mhz /4800 =0.01Mhz = 100us |
| | | timercontralcfg.alignedmode = TIMER_COUNTER_EDGE; |
| | | timercontralcfg.counterdirection = TIMER_COUNTER_UP; |
| | | timercontralcfg.period = PERIOD_CAP; //100us*10000=1s |
| | | |
| | | 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); |
| | | timer_interrupt_flag_clear(TIMER2, TIMER_INT_UP); |
| | | timer_interrupt_enable(TIMER2, TIMER_INT_UP); |
| | | nvic_irq_enable(TIMER2_IRQn, 1); |
| | | timer_prescaler_config(TIMER2, 47, TIMER_PSC_RELOAD_NOW); //48Mhz /48 =1Mhz = 1us |
| | | } |
| | | |
| | | /***************************************************************************************************** |
| | |
| | | *****************************************************************************************************/ |
| | | static void Timer0Init(void) |
| | | { |
| | | uint16_t Duty = 0; |
| | | uint16_t Duty = PERIOD_CMP / 10; |
| | | timer_parameter_struct timercontralcfg; |
| | | timer_oc_parameter_struct timeroutcfg[3]; |
| | | timer_break_parameter_struct timer_breakpara; |
| | | |
| | | //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) |
| | | timercontralcfg.prescaler = 0; //counter prescaler is 0 |
| | | timercontralcfg.alignedmode = TIMER_COUNTER_EDGE; //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 64M |
| | | 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].outputstate = TIMER_CCX_ENABLE; //channel enable |
| | | timeroutcfg[0].outputnstate = TIMER_CCXN_DISABLE; //channel complementary DISABLE |
| | | timeroutcfg[0].ocidlestate = TIMER_OC_IDLE_STATE_LOW; |
| | | timeroutcfg[0].ocnidlestate = TIMER_OCN_IDLE_STATE_HIGH; |
| | | timeroutcfg[0].ocnidlestate = TIMER_OCN_IDLE_STATE_LOW; |
| | | |
| | | 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].outputstate = TIMER_CCX_ENABLE; //channel enable |
| | | timeroutcfg[1].outputnstate = TIMER_CCXN_DISABLE; //channel complementary DISABLE |
| | | timeroutcfg[1].ocidlestate = TIMER_OC_IDLE_STATE_LOW; |
| | | timeroutcfg[1].ocnidlestate = TIMER_OCN_IDLE_STATE_HIGH; |
| | | timeroutcfg[1].ocnidlestate = TIMER_OCN_IDLE_STATE_LOW; |
| | | |
| | | 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].outputstate = TIMER_CCX_ENABLE; //channel enable |
| | | timeroutcfg[2].outputnstate = TIMER_CCXN_DISABLE; //channel complementary DISABLE |
| | | timeroutcfg[2].ocidlestate = TIMER_OC_IDLE_STATE_LOW; |
| | | timeroutcfg[2].ocnidlestate = TIMER_OCN_IDLE_STATE_HIGH; |
| | | timeroutcfg[2].ocnidlestate = TIMER_OCN_IDLE_STATE_LOW; |
| | | |
| | | timer_channel_output_config(TIMER0, TIMER_CH_0, &timeroutcfg[0]); |
| | | timer_channel_output_config(TIMER0, TIMER_CH_1, &timeroutcfg[1]); |
| | |
| | | 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_0, TIMER_OC_MODE_PWM1); //set pwm1 mode first low then high |
| | | 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_channel_output_shadow_config(TIMER0, TIMER_CH_0, TIMER_OC_SHADOW_ENABLE); //shadow ENable |
| | | timer_channel_output_shadow_config(TIMER0, TIMER_CH_1, TIMER_OC_SHADOW_ENABLE); |
| | | timer_channel_output_shadow_config(TIMER0, TIMER_CH_2, TIMER_OC_SHADOW_ENABLE); |
| | | |
| | | timer_interrupt_enable(TIMER0, TIMER_INT_CH0); |
| | | timer_interrupt_enable(TIMER0, TIMER_INT_CH1); |
| | | timer_interrupt_enable(TIMER0, TIMER_INT_CH2); |
| | | /* configure TIMER break function */ |
| | | timer_break_struct_para_init(&timer_breakpara); |
| | | /* automatic output enable, break, dead time and lock configuration*/ |
| | | timer_breakpara.runoffstate = TIMER_ROS_STATE_DISABLE; |
| | | timer_breakpara.ideloffstate = TIMER_IOS_STATE_DISABLE; |
| | | timer_breakpara.deadtime = 255; |
| | | timer_breakpara.breakpolarity = TIMER_BREAK_POLARITY_LOW; |
| | | timer_breakpara.outputautostate = TIMER_OUTAUTO_ENABLE; |
| | | timer_breakpara.protectmode = TIMER_CCHP_PROT_0; |
| | | timer_breakpara.breakstate = TIMER_BREAK_ENABLE; |
| | | timer_break_config(TIMER0, &timer_breakpara); |
| | | |
| | | timer_primary_output_config(TIMER0, ENABLE); |
| | | timer_auto_reload_shadow_enable(TIMER0); |
| | |
| | | Timer0Init(); |
| | | Timer2Init(); |
| | | timer_enable(TIMER0); |
| | | timer_enable(TIMER2); |
| | | } |
| | | |
| | | void SetPwmDuty(uint16_t ch, uint32_t duty) |
| | | { |
| | | uint32_t duty_temp = (PERIOD_CMP >= duty) ? (PERIOD_CMP - duty) : 0; |
| | | timer_channel_output_pulse_value_config(TIMER0, ch, duty); |
| | | } |
| | | |
| | |
| | | { |
| | | TIMER_CAR(TIMER0) = period; |
| | | } |
| | | |
| | | extern void StartSpeedTime(void) |
| | | { |
| | | timer_enable(TIMER2); |
| | | } |
| | | |
| | | extern void StopSpeedTime(void) |
| | | { |
| | | timer_disable(TIMER2); |
| | | } |
| | | extern void TIMER2_IRQHandler_CallBack(void) |
| | | { |
| | | timer_outcnt++; |
| | | } |
| | | |
| | | extern uint32_t GetSpeedTimerOutcnt(void) |
| | | { |
| | | uint32_t rtn = timer_outcnt; |
| | | timer_outcnt = 0; |
| | | return rtn; |
| | | } |