4
4
5
5
// set pwm frequency to 32KHz
6
6
void _pinHighFrequency (const int pin){
7
+ bool high_fq = false ;
8
+ // set 32kHz frequency if requested freq is higher than the middle of the range (14kHz)
9
+ // else set the 4kHz
10
+ if (frequency >= 0.5 *(_PWM_FREQUENCY_MAX-_PWM_FREQUENCY_MIN)) high_fq=true ;
7
11
// High PWM frequency
8
- // https://sites.google.com/site/qeewiki/books/avr-guide/timers-on-the-atmega328
12
+ // https://sites.google.com/site/qeewiki/books/avr-guide/timers-on-the-ATmega2560
9
13
// https://forum.arduino.cc/index.php?topic=72092.0
10
14
if (pin == 13 || pin == 4 ) {
11
15
TCCR0A = ((TCCR0A & 0b11111100 ) | 0x01 ); // configure the pwm phase-corrected mode
12
- TCCR0B = ((TCCR0B & 0b11110000 ) | 0x01 ); // set prescaler to 1
16
+ if (high_fq) TCCR0B = ((TCCR0B & 0b11110000 ) | 0x01 ); // set prescaler to 1 - 32kHz
17
+ else TCCR0B = ((TCCR0B & 0b11110000 ) | 0x02 ); // set prescaler to 2 - 4kHz
13
18
}
14
19
else if (pin == 12 || pin == 11 )
15
- TCCR1B = ((TCCR1B & 0b11111000 ) | 0x01 ); // set prescaler to 1
20
+ if (high_fq) TCCR1B = ((TCCR1B & 0b11110000 ) | 0x01 ); // set prescaler to 1 - 32kHz
21
+ else TCCR1B = ((TCCR1B & 0b11110000 ) | 0x02 ); // set prescaler to 2 - 4kHz
16
22
else if (pin == 10 || pin == 9 )
17
- TCCR2B = ((TCCR2B & 0b11111000 ) | 0x01 ); // set prescaler to 1
23
+ if (high_fq) TCCR2B = ((TCCR2B & 0b11110000 ) | 0x01 ); // set prescaler to 1 - 32kHz
24
+ else TCCR2B = ((TCCR2B & 0b11110000 ) | 0x02 ); // set prescaler to 2 - 4kHz
18
25
else if (pin == 5 || pin == 3 || pin == 2 )
19
- TCCR3B = ((TCCR2B & 0b11111000 ) | 0x01 ); // set prescaler to 1
26
+ if (high_fq) TCCR3B = ((TCCR3B & 0b11110000 ) | 0x01 ); // set prescaler to 1 - 32kHz
27
+ else TCCR3B = ((TCCR3B & 0b11110000 ) | 0x02 ); // set prescaler to 2 - 4kHz
20
28
else if (pin == 8 || pin == 7 || pin == 6 )
21
- TCCR4B = ((TCCR4B & 0b11111000 ) | 0x01 ); // set prescaler to 1
29
+ if (high_fq) TCCR4B = ((TCCR4B & 0b11110000 ) | 0x01 ); // set prescaler to 1 - 32kHz
30
+ else TCCR4B = ((TCCR4B & 0b11110000 ) | 0x02 ); // set prescaler to 2 - 4kHz
22
31
else if (pin == 44 || pin == 45 || pin == 46 )
23
- TCCR5B = ((TCCR5B & 0b11111000 ) | 0x01 ); // set prescaler to 1
32
+ if (high_fq) TCCR5B = ((TCCR5B & 0b11110000 ) | 0x01 ); // set prescaler to 1 - 32kHz
33
+ else TCCR5B = ((TCCR5B & 0b11110000 ) | 0x02 ); // set prescaler to 2 - 4kHz
24
34
25
35
}
26
36
27
37
28
38
// function setting the high pwm frequency to the supplied pins
29
39
// - Stepper motor - 2PWM setting
30
- // - hardware speciffic
40
+ // - hardware specific
41
+ // supports Arduino/ATmega2560
31
42
void * _configure1PWM (long pwm_frequency,const int pinA) {
43
+ if (!pwm_frequency || !_isset (pwm_frequency) ) pwm_frequency = _PWM_FREQUENCY; // default frequency 32kHz
44
+ else pwm_frequency = _constrain (pwm_frequency, _PWM_FREQUENCY_MIN, _PWM_FREQUENCY_MAX); // constrain to 4-32kHz max
32
45
// High PWM frequency
33
46
// - always max 32kHz
34
- _pinHighFrequency (pinA);
47
+ _pinHighFrequency (pinA, pwm_frequency );
35
48
GenericDriverParams* params = new GenericDriverParams {
36
49
.pins = { pinA },
37
50
.pwm_frequency = pwm_frequency
38
51
};
39
52
return params;
40
53
}
41
54
42
-
43
55
// function setting the high pwm frequency to the supplied pins
44
56
// - Stepper motor - 2PWM setting
45
- // - hardware speciffic
46
- void * _configure2PWM (long pwm_frequency,const int pinA, const int pinB) {
57
+ // - hardware specific
58
+ // supports Arduino/ATmega2560
59
+ void * _configure2PWM (long pwm_frequency,const int pinA, const int pinB) {
60
+ if (!pwm_frequency || !_isset (pwm_frequency) ) pwm_frequency = _PWM_FREQUENCY; // default frequency 32kHz
61
+ else pwm_frequency = _constrain (pwm_frequency, _PWM_FREQUENCY_MIN, _PWM_FREQUENCY_MAX); // constrain to 4-32kHz max
47
62
// High PWM frequency
48
63
// - always max 32kHz
49
- _pinHighFrequency (pinA);
50
- _pinHighFrequency (pinB);
64
+ _pinHighFrequency (pinA, pwm_frequency );
65
+ _pinHighFrequency (pinB, pwm_frequency );
51
66
GenericDriverParams* params = new GenericDriverParams {
52
67
.pins = { pinA, pinB },
53
68
.pwm_frequency = pwm_frequency
@@ -57,31 +72,35 @@ void* _configure2PWM(long pwm_frequency,const int pinA, const int pinB) {
57
72
58
73
// function setting the high pwm frequency to the supplied pins
59
74
// - BLDC motor - 3PWM setting
60
- // - hardware speciffic
75
+ // - hardware specific
76
+ // supports Arduino/ATmega2560
61
77
void * _configure3PWM (long pwm_frequency,const int pinA, const int pinB, const int pinC) {
78
+ if (!pwm_frequency || !_isset (pwm_frequency) ) pwm_frequency = _PWM_FREQUENCY; // default frequency 32kHz
79
+ else pwm_frequency = _constrain (pwm_frequency, _PWM_FREQUENCY_MIN, _PWM_FREQUENCY_MAX); // constrain to 4-32kHz max
62
80
// High PWM frequency
63
81
// - always max 32kHz
64
- _pinHighFrequency (pinA);
65
- _pinHighFrequency (pinB);
66
- _pinHighFrequency (pinC);
82
+ _pinHighFrequency (pinA, pwm_frequency );
83
+ _pinHighFrequency (pinB, pwm_frequency );
84
+ _pinHighFrequency (pinC, pwm_frequency );
67
85
GenericDriverParams* params = new GenericDriverParams {
68
86
.pins = { pinA, pinB, pinC },
69
87
.pwm_frequency = pwm_frequency
70
88
};
89
+ // _syncAllTimers();
71
90
return params;
72
91
}
73
92
74
93
// function setting the pwm duty cycle to the hardware
75
94
// - Stepper motor - 2PWM setting
76
- // - hardware speciffic
95
+ // - hardware specific
77
96
void _writeDutyCycle1PWM (float dc_a, void * params){
78
97
// transform duty cycle from [0,1] to [0,255]
79
98
analogWrite (((GenericDriverParams*)params)->pins [0 ], 255 .0f *dc_a);
80
99
}
81
100
82
101
// function setting the pwm duty cycle to the hardware
83
102
// - Stepper motor - 2PWM setting
84
- // - hardware speciffic
103
+ // - hardware specific
85
104
void _writeDutyCycle2PWM (float dc_a, float dc_b, void * params){
86
105
// transform duty cycle from [0,1] to [0,255]
87
106
analogWrite (((GenericDriverParams*)params)->pins [0 ], 255 .0f *dc_a);
@@ -90,7 +109,7 @@ void _writeDutyCycle2PWM(float dc_a, float dc_b, void* params){
90
109
91
110
// function setting the pwm duty cycle to the hardware
92
111
// - BLDC motor - 3PWM setting
93
- // - hardware speciffic
112
+ // - hardware specific
94
113
void _writeDutyCycle3PWM (float dc_a, float dc_b, float dc_c, void * params){
95
114
// transform duty cycle from [0,1] to [0,255]
96
115
analogWrite (((GenericDriverParams*)params)->pins [0 ], 255 .0f *dc_a);
@@ -100,14 +119,16 @@ void _writeDutyCycle3PWM(float dc_a, float dc_b, float dc_c, void* params){
100
119
101
120
// function setting the high pwm frequency to the supplied pins
102
121
// - Stepper motor - 4PWM setting
103
- // - hardware speciffic
122
+ // - hardware specific
104
123
void * _configure4PWM (long pwm_frequency,const int pin1A, const int pin1B, const int pin2A, const int pin2B) {
124
+ if (!pwm_frequency || !_isset (pwm_frequency) ) pwm_frequency = _PWM_FREQUENCY; // default frequency 32kHz
125
+ else pwm_frequency = _constrain (pwm_frequency, _PWM_FREQUENCY_MIN, _PWM_FREQUENCY_MAX); // constrain to 4-32kHz max
105
126
// High PWM frequency
106
127
// - always max 32kHz
107
- _pinHighFrequency (pin1A);
108
- _pinHighFrequency (pin1B);
109
- _pinHighFrequency (pin2A);
110
- _pinHighFrequency (pin2B);
128
+ _pinHighFrequency (pin1A,pwm_frequency );
129
+ _pinHighFrequency (pin1B,pwm_frequency );
130
+ _pinHighFrequency (pin2A,pwm_frequency );
131
+ _pinHighFrequency (pin2B,pwm_frequency );
111
132
GenericDriverParams* params = new GenericDriverParams {
112
133
.pins = { pin1A, pin1B, pin2A, pin2B },
113
134
.pwm_frequency = pwm_frequency
@@ -117,7 +138,7 @@ void* _configure4PWM(long pwm_frequency,const int pin1A, const int pin1B, const
117
138
118
139
// function setting the pwm duty cycle to the hardware
119
140
// - Stepper motor - 4PWM setting
120
- // - hardware speciffic
141
+ // - hardware specific
121
142
void _writeDutyCycle4PWM (float dc_1a, float dc_1b, float dc_2a, float dc_2b, void * params) {
122
143
// transform duty cycle from [0,1] to [0,255]
123
144
analogWrite (((GenericDriverParams*)params)->pins [0 ], 255 .0f *dc_1a);
@@ -128,45 +149,79 @@ void _writeDutyCycle4PWM(float dc_1a, float dc_1b, float dc_2a, float dc_2b, vo
128
149
129
150
130
151
// function configuring pair of high-low side pwm channels, 32khz frequency and center aligned pwm
131
- // supports Arudino /ATmega2560
152
+ // supports Arduino /ATmega2560
132
153
// https://ww1.microchip.com/downloads/en/devicedoc/atmel-2549-8-bit-avr-microcontroller-atmega640-1280-1281-2560-2561_datasheet.pdf
133
154
// https://docs.arduino.cc/hacking/hardware/PinMapping2560
134
- int _configureComplementaryPair (int pinH, int pinL) {
155
+ int _configureComplementaryPair (const int pinH,const int pinL, long frequency) {
156
+ bool high_fq = false ;
157
+ // set 32kHz frequency if requested freq is higher than the middle of the range (14kHz)
158
+ // else set the 4kHz
159
+ if (frequency >= 0.5 *(_PWM_FREQUENCY_MAX-_PWM_FREQUENCY_MIN)) high_fq=true ;
160
+ // High PWM frequency
161
+ // https://sites.google.com/site/qeewiki/books/avr-guide/timers-on-the-ATmega2560
162
+ // https://forum.arduino.cc/index.php?topic=72092.0
163
+ if (pin == 13 || pin == 4 ) {
164
+ TCCR0A = ((TCCR0A & 0b11111100 ) | 0x01 ); // configure the pwm phase-corrected mode
165
+ if (high_fq) TCCR0B = ((TCCR0B & 0b11110000 ) | 0x01 ); // set prescaler to 1 - 32kHz
166
+ else TCCR0B = ((TCCR0B & 0b11110000 ) | 0x02 ); // set prescaler to 2 - 4kHz
167
+ }
168
+ else if (pin == 12 || pin == 11 )
169
+ if (high_fq) TCCR1B = ((TCCR1B & 0b11110000 ) | 0x01 ); // set prescaler to 1 - 32kHz
170
+ else TCCR1B = ((TCCR1B & 0b11110000 ) | 0x02 ); // set prescaler to 2 - 4kHz
171
+ else if (pin == 10 || pin == 9 )
172
+ if (high_fq) TCCR2B = ((TCCR2B & 0b11110000 ) | 0x01 ); // set prescaler to 1 - 32kHz
173
+ else TCCR2B = ((TCCR2B & 0b11110000 ) | 0x02 ); // set prescaler to 2 - 4kHz
174
+ else if (pin == 5 || pin == 3 || pin == 2 )
175
+ if (high_fq) TCCR3B = ((TCCR3B & 0b11110000 ) | 0x01 ); // set prescaler to 1 - 32kHz
176
+ else TCCR3B = ((TCCR3B & 0b11110000 ) | 0x02 ); // set prescaler to 2 - 4kHz
177
+ else if (pin == 8 || pin == 7 || pin == 6 )
178
+ if (high_fq) TCCR4B = ((TCCR4B & 0b11110000 ) | 0x01 ); // set prescaler to 1 - 32kHz
179
+ else TCCR4B = ((TCCR4B & 0b11110000 ) | 0x02 ); // set prescaler to 2 - 4kHz
180
+ else if (pin == 44 || pin == 45 || pin == 46 )
181
+ if (high_fq) TCCR5B = ((TCCR5B & 0b11110000 ) | 0x01 ); // set prescaler to 1 - 32kHz
182
+ else TCCR5B = ((TCCR5B & 0b11110000 ) | 0x02 ); // set prescaler to 2 - 4kHz
183
+
135
184
if ( (pinH == 4 && pinL == 13 ) || (pinH == 13 && pinL == 4 ) ){
136
185
// configure the pwm phase-corrected mode
137
186
TCCR0A = ((TCCR0A & 0b11111100 ) | 0x01 );
138
187
// configure complementary pwm on low side
139
188
if (pinH == 13 ) TCCR0A = 0b10110000 | (TCCR0A & 0b00001111 ) ;
140
189
else TCCR0A = 0b11100000 | (TCCR0A & 0b00001111 ) ;
141
- // set prescaler to 1 - 32kHz freq
142
- TCCR0B = ((TCCR0B & 0b11110000 ) | 0x01 );
190
+ // set frequency
191
+ if (high_fq) TCCR0B = ((TCCR0B & 0b11110000 ) | 0x01 ); // set prescaler to 1 - 32kHz
192
+ else TCCR0B = ((TCCR0B & 0b11110000 ) | 0x02 ); // set prescaler to 2 - 4kHz
143
193
}else if ( (pinH == 11 && pinL == 12 ) || (pinH == 12 && pinL == 11 ) ){
144
- // set prescaler to 1 - 32kHz freq
145
- TCCR1B = ((TCCR1B & 0b11111000 ) | 0x01 );
194
+ // set frequency
195
+ if (high_fq) TCCR1B = ((TCCR1B & 0b11110000 ) | 0x01 ); // set prescaler to 1 - 32kHz
196
+ else TCCR1B = ((TCCR1B & 0b11110000 ) | 0x02 ); // set prescaler to 2 - 4kHz
146
197
// configure complementary pwm on low side
147
198
if (pinH == 11 ) TCCR1A = 0b10110000 | (TCCR1A & 0b00001111 ) ;
148
199
else TCCR1A = 0b11100000 | (TCCR1A & 0b00001111 ) ;
149
200
}else if ((pinH == 10 && pinL == 9 ) || (pinH == 9 && pinL == 10 ) ){
150
- // set prescaler to 1 - 32kHz freq
151
- TCCR2B = ((TCCR2B & 0b11111000 ) | 0x01 );
201
+ // set frequency
202
+ if (high_fq) TCCR2B = ((TCCR2B & 0b11110000 ) | 0x01 ); // set prescaler to 1 - 32kHz
203
+ else TCCR2B = ((TCCR2B & 0b11110000 ) | 0x02 ); // set prescaler to 2 - 4kHz
152
204
// configure complementary pwm on low side
153
205
if (pinH == 10 ) TCCR2A = 0b10110000 | (TCCR2A & 0b00001111 ) ;
154
206
else TCCR2A = 0b11100000 | (TCCR2A & 0b00001111 ) ;
155
207
}else if ((pinH == 5 && pinL == 2 ) || (pinH == 2 && pinL == 5 ) ){
156
- // set prescaler to 1 - 32kHz freq
157
- TCCR3B = ((TCCR3B & 0b11111000 ) | 0x01 );
208
+ // set frequency
209
+ if (high_fq) TCCR3B = ((TCCR3B & 0b11110000 ) | 0x01 ); // set prescaler to 1 - 32kHz
210
+ else TCCR3B = ((TCCR3B & 0b11110000 ) | 0x02 ); // set prescaler to 2 - 4kHz
158
211
// configure complementary pwm on low side
159
212
if (pinH == 5 ) TCCR3A = 0b10110000 | (TCCR3A & 0b00001111 ) ;
160
213
else TCCR3A = 0b11100000 | (TCCR3A & 0b00001111 ) ;
161
214
}else if ((pinH == 6 && pinL == 7 ) || (pinH == 7 && pinL == 6 ) ){
162
- // set prescaler to 1 - 32kHz freq
163
- TCCR4B = ((TCCR4B & 0b11111000 ) | 0x01 );
215
+ // set frequency
216
+ if (high_fq) TCCR4B = ((TCCR4B & 0b11110000 ) | 0x01 ); // set prescaler to 1 - 32kHz
217
+ else TCCR4B = ((TCCR4B & 0b11110000 ) | 0x02 ); // set prescaler to 2 - 4kHz
164
218
// configure complementary pwm on low side
165
219
if (pinH == 6 ) TCCR4A = 0b10110000 | (TCCR4A & 0b00001111 ) ;
166
220
else TCCR4A = 0b11100000 | (TCCR4A & 0b00001111 ) ;
167
221
}else if ((pinH == 46 && pinL == 45 ) || (pinH == 45 && pinL == 46 ) ){
168
- // set prescaler to 1 - 32kHz freq
169
- TCCR5B = ((TCCR5B & 0b11111000 ) | 0x01 );
222
+ // set frequency
223
+ if (high_fq) TCCR5B = ((TCCR5B & 0b11110000 ) | 0x01 ); // set prescaler to 1 - 32kHz
224
+ else TCCR5B = ((TCCR5B & 0b11110000 ) | 0x02 ); // set prescaler to 2 - 4kHz
170
225
// configure complementary pwm on low side
171
226
if (pinH == 46 ) TCCR5A = 0b10110000 | (TCCR5A & 0b00001111 ) ;
172
227
else TCCR5A = 0b11100000 | (TCCR5A & 0b00001111 ) ;
@@ -177,48 +232,59 @@ int _configureComplementaryPair(int pinH, int pinL) {
177
232
}
178
233
179
234
// Configuring PWM frequency, resolution and alignment
180
- // - BLDC driver - 6PWM setting
235
+ // - BLDC driver - setting
181
236
// - hardware specific
182
- // supports Arudino/ATmega328
237
+ // supports Arduino/ATmega2560
183
238
void * _configure6PWM (long pwm_frequency, float dead_zone, const int pinA_h, const int pinA_l, const int pinB_h, const int pinB_l, const int pinC_h, const int pinC_l) {
239
+ if (!pwm_frequency || !_isset (pwm_frequency) ) pwm_frequency = _PWM_FREQUENCY; // default frequency 32kHz
240
+ else pwm_frequency = _constrain (pwm_frequency, _PWM_FREQUENCY_MIN, _PWM_FREQUENCY_MAX); // constrain to 4-32kHz max
184
241
// High PWM frequency
185
242
// - always max 32kHz
186
243
int ret_flag = 0 ;
187
- ret_flag += _configureComplementaryPair (pinA_h, pinA_l);
188
- ret_flag += _configureComplementaryPair (pinB_h, pinB_l);
189
- ret_flag += _configureComplementaryPair (pinC_h, pinC_l);
244
+ ret_flag += _configureComplementaryPair (pinA_h, pinA_l, pwm_frequency );
245
+ ret_flag += _configureComplementaryPair (pinB_h, pinB_l, pwm_frequency );
246
+ ret_flag += _configureComplementaryPair (pinC_h, pinC_l, pwm_frequency );
190
247
if (ret_flag!=0 ) return SIMPLEFOC_DRIVER_INIT_FAILED;
191
248
GenericDriverParams* params = new GenericDriverParams {
192
249
.pins = { pinA_h, pinA_l, pinB_h, pinB_l, pinC_h, pinC_l },
193
250
.pwm_frequency = pwm_frequency,
194
251
.dead_zone = dead_zone
195
252
};
253
+ // _syncAllTimers();
196
254
return params;
197
255
}
198
256
199
257
// function setting the
200
- void _setPwmPair (int pinH, int pinL, float val, int dead_time)
258
+ void _setPwmPair (int pinH, int pinL, float val, int dead_time, PhaseState ps )
201
259
{
202
260
int pwm_h = _constrain (val-dead_time/2 ,0 ,255 );
203
261
int pwm_l = _constrain (val+dead_time/2 ,0 ,255 );
262
+ // determine the phase state and set the pwm accordingly
263
+ // deactivate phases if needed
264
+ if ((ps == PhaseState::PHASE_OFF) || (ps == PhaseState::PHASE_LO)){
265
+ digitalWrite (pinH, LOW);
266
+ }else {
267
+ analogWrite (pinH, pwm_h);
268
+ }
269
+ if ((ps == PhaseState::PHASE_OFF) || (ps == PhaseState::PHASE_HI)){
270
+ digitalWrite (pinL, LOW);
271
+ }else {
272
+ if (pwm_l == 255 || pwm_l == 0 )
273
+ digitalWrite (pinL, pwm_l ? LOW : HIGH);
274
+ else
275
+ analogWrite (pinL, pwm_l);
276
+ }
204
277
205
- analogWrite (pinH, pwm_h);
206
- if (pwm_l == 255 || pwm_l == 0 )
207
- digitalWrite (pinL, pwm_l ? LOW : HIGH);
208
- else
209
- analogWrite (pinL, pwm_l);
210
278
}
211
279
212
280
// Function setting the duty cycle to the pwm pin (ex. analogWrite())
213
281
// - BLDC driver - 6PWM setting
214
282
// - hardware specific
215
- // supports Arudino /ATmega328
283
+ // supports Arduino /ATmega328
216
284
void _writeDutyCycle6PWM (float dc_a, float dc_b, float dc_c, PhaseState *phase_state, void * params){
217
- _setPwmPair (((GenericDriverParams*)params)->pins [0 ], ((GenericDriverParams*)params)->pins [1 ], dc_a*255.0 , ((GenericDriverParams*)params)->dead_zone *255.0 );
218
- _setPwmPair (((GenericDriverParams*)params)->pins [2 ], ((GenericDriverParams*)params)->pins [3 ], dc_b*255.0 , ((GenericDriverParams*)params)->dead_zone *255.0 );
219
- _setPwmPair (((GenericDriverParams*)params)->pins [4 ], ((GenericDriverParams*)params)->pins [5 ], dc_c*255.0 , ((GenericDriverParams*)params)->dead_zone *255.0 );
220
-
221
- _UNUSED (phase_state);
285
+ _setPwmPair (((GenericDriverParams*)params)->pins [0 ], ((GenericDriverParams*)params)->pins [1 ], dc_a*255.0 , ((GenericDriverParams*)params)->dead_zone *255.0 , phase_state[0 ]);
286
+ _setPwmPair (((GenericDriverParams*)params)->pins [2 ], ((GenericDriverParams*)params)->pins [3 ], dc_b*255.0 , ((GenericDriverParams*)params)->dead_zone *255.0 , phase_state[1 ]);
287
+ _setPwmPair (((GenericDriverParams*)params)->pins [4 ], ((GenericDriverParams*)params)->pins [5 ], dc_c*255.0 , ((GenericDriverParams*)params)->dead_zone *255.0 , phase_state[2 ]);
222
288
}
223
289
224
290
#endif
0 commit comments