-
Notifications
You must be signed in to change notification settings - Fork 13
/
pwm.c
executable file
·156 lines (121 loc) · 5.07 KB
/
pwm.c
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
/*
* EGG Electric Unicycle firmware
*
* Copyright (C) Casainho, 2015, 2106.
*
* Released under the GPL License, Version 3
*/
#include "stm32f10x.h"
#include "stm32f10x_tim.h"
#include "stm32f10x_rcc.h"
#include "main.h"
#include "gpio.h"
#include "pwm.h"
// This interrupt fire after the end on the PWM period (49us) - TIM1 UPdate event
void PWM_PERIOD_INTERRUPT (void)
{
/* Clear TIMx TIM_IT_Update pending interrupt bit */
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
}
void pwm_init (void)
{
GPIO_InitTypeDef GPIO_InitStructure;
// mosfets drivers pins
GPIO_InitStructure.GPIO_Pin = PHASE_A_SHUTDOWN__PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(PHASE_A_SHUTDOWN__PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = PHASE_A_HO_LO__PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(PHASE_A_HO_LO__PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = PHASE_B_SHUTDOWN__PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(PHASE_B_SHUTDOWN__PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = PHASE_B_HO_LO__PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(PHASE_B_HO_LO__PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = PHASE_C_SHUTDOWN__PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(PHASE_C_SHUTDOWN__PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = PHASE_C_HO_LO__PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(PHASE_C_HO_LO__PORT, &GPIO_InitStructure);
RCC_APB1PeriphClockCmd (RCC_APB1Periph_TIM3, ENABLE);
// reset TIM3
TIM_DeInit (TIM3);
/* Time Base configuration */
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned1;
TIM_TimeBaseStructure.TIM_Period = PWM_VALUE_DUTY_CYCLE_MAX; // 72MHz clock (PCLK1), 72MHz/4608 = 15.625KHz (BUT PWM center aligned mode needs twice the frequency)
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 1; // will fire the TIMx_UP_IRQHandler at every PWM period (64us)
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
/* Configures the TIMx Update Request Interrupt source (SETS the CR1->URS bit)*/
TIM_UpdateRequestConfig(TIM3,TIM_UpdateSource_Regular);
/* TIMx_ARR register is buffered and so the duty-cycle value is just updated (shadow registers) at Update Event */
TIM_ARRPreloadConfig(TIM3, ENABLE);
// NVIC_InitTypeDef NVIC_InitStructure;
// /* Configure and enable TIMx interrupt */
// NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = TIM3_PRIORITY;
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
// NVIC_Init(&NVIC_InitStructure);
//
// /* Enable Update Event interrupt */
// TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
/* Channel 1, 2, 3 Configuration in PWM mode */
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;
TIM_OCInitStructure.TIM_Pulse = 0; // start with 0% duty cycle
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
TIM_OC1Init(TIM3, &TIM_OCInitStructure);
TIM_OC3Init(TIM3, &TIM_OCInitStructure);
TIM_OC4Init(TIM3, &TIM_OCInitStructure);
TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1;
TIM_BDTRInitStructure.TIM_DeadTime = 0;
TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;
TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_Low;
TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
TIM_BDTRConfig(TIM3, &TIM_BDTRInitStructure);
/* TIM3 counter enable */
TIM_Cmd (TIM3, ENABLE);
/* TIM3 Main Output Disable */
TIM_CtrlPWMOutputs (TIM3, ENABLE);
}
void enable_phase_a (void)
{
GPIO_SetBits (PHASE_A_SHUTDOWN__PORT, PHASE_A_SHUTDOWN__PIN);
}
void enable_phase_b (void)
{
GPIO_SetBits (PHASE_B_SHUTDOWN__PORT, PHASE_B_SHUTDOWN__PIN);
}
void enable_phase_c (void)
{
GPIO_SetBits (PHASE_C_SHUTDOWN__PORT, PHASE_C_SHUTDOWN__PIN);
}
void set_pwm_phase_a (unsigned int value)
{
TIM_SetCompare4 (TIM3, value);
}
void set_pwm_phase_b (unsigned int value)
{
TIM_SetCompare3 (TIM3, value);
}
void set_pwm_phase_c (unsigned int value)
{
TIM_SetCompare1(TIM3, value);
}