tao_z
2021-06-30 945ba42f7550d5a203e43d82b43ed82dc981d9e9
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/**
 * @file pwm.c
 * @author Ethan.Tao (tzj0429@163.com)
 * @brief 
 * @version 0.1
 * @date 2020-12-12
 * 
 * @copyright Copyright (c) 
 * 
 */
#include "pwm.h"
static volatile uint32_t timer_outcnt = 0;
/*****************************************************************************************************
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
                    PB5-BO
*****************************************************************************************************/
static void Timer2Init(void)
{
    timer_parameter_struct timercontralcfg;
 
    timer_deinit(TIMER2);
 
    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_UP);
    timer_interrupt_enable(TIMER2, TIMER_INT_UP);
    nvic_irq_enable(TIMER2_IRQn, 1);
}
 
/*****************************************************************************************************
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 = 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_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_DISABLE; //channel complementary DISABLE
    timeroutcfg[0].ocidlestate = TIMER_OC_IDLE_STATE_LOW;
    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_DISABLE; //channel complementary  DISABLE
    timeroutcfg[1].ocidlestate = TIMER_OC_IDLE_STATE_LOW;
    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_DISABLE; //channel complementary  DISABLE
    timeroutcfg[2].ocidlestate = TIMER_OC_IDLE_STATE_LOW;
    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_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 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_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);
 
    /* 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);
}
 
void TimerInit(void)
{
    rcu_periph_clock_enable(RCU_TIMER2);
    rcu_periph_clock_enable(RCU_TIMER0);
    Timer0Init();
    Timer2Init();
    timer_enable(TIMER0);
}
 
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);
}
 
void SetPwmPeriod(uint32_t period)
{
    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;
}