tao_z
2021-06-14 b150690b6ebe42a4ffd50278d761b8994121eb94
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
/**
 * @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;
}