7
7
Built by Khoi Hoang https://github.com/khoih-prog/ATtiny_PWM
8
8
Licensed under MIT license
9
9
10
- Version: 1.1 .0
10
+ Version: 1.2 .0
11
11
12
12
Version Modified By Date Comments
13
13
------- ----------- ---------- -----------
14
14
1.0.0 K Hoang 08/11/2022 Initial coding for AVR ATtiny (ATtiny3217, etc.) using megaTinyCore
15
15
1.0.1 K Hoang 22/01/2023 Add `PWM_StepperControl` example
16
16
1.1.0 K Hoang 25/01/2023 Add `PWM_manual` example and function. Catch low frequency error
17
+ 1.2.0 K Hoang 27/01/2023 Add `PWM_SpeedTest` example and faster `setPWM_DCPercentageInt_manual` function
17
18
*****************************************************************************************************************************/
18
19
19
20
#pragma once
146
147
// /////////////////////////////////////////////////////////////////////////////
147
148
148
149
#ifndef AT_TINY_PWM_VERSION
149
- #define AT_TINY_PWM_VERSION F (" ATtiny_PWM v1.1 .0" )
150
+ #define AT_TINY_PWM_VERSION F (" ATtiny_PWM v1.2 .0" )
150
151
151
152
#define AT_TINY_PWM_VERSION_MAJOR 1
152
- #define AT_TINY_PWM_VERSION_MINOR 1
153
+ #define AT_TINY_PWM_VERSION_MINOR 2
153
154
#define AT_TINY_PWM_VERSION_PATCH 0
154
155
155
- #define AT_TINY_PWM_VERSION_INT 1001000
156
+ #define AT_TINY_PWM_VERSION_INT 1002000
156
157
#endif
157
158
158
159
// //////////////////////////////////////
@@ -306,43 +307,22 @@ class ATtiny_PWM
306
307
307
308
PWM_LOGDEBUG3 (" setPeriod_TimerD0: pwmPeriod =" , pwmPeriod, " , _actualFrequency =" , _actualFrequency);
308
309
}
309
-
310
- // /////////////////////////////////////////
310
+
311
311
// /////////////////////////////////////////
312
312
313
- public:
314
-
315
- // dutycycle from 0-65535 for 0%-100% to make use of 16-bit top register
316
- bool setPWM_Int (const uint8_t & pin, const float & frequency, uint16_t dutycycle)
313
+ bool setPWM_Reg (const uint8_t & pin, uint16_t dutycycle)
317
314
{
318
- dutycycle = map (dutycycle, 0 , MAX_16BIT, 0 , MAX_8BIT);
319
-
320
- if (frequency != _frequency)
321
- {
322
- PWM_LOGDEBUG1 (" setPWM_Int: new freq =" , frequency);
323
-
324
- _frequency = frequency;
325
- }
326
-
315
+ dutycycle >>= 8 ;
316
+
327
317
uint8_t bit_mask = digitalPinToBitMask (pin);
328
318
329
- if (bit_mask == NOT_A_PIN)
330
- {
331
- PWM_LOGERROR1 (" setPWM_Int: NOT_A_PIN, pin =" , pin);
332
-
333
- return false ;
334
- }
335
-
336
319
volatile uint8_t *timer_cmp_out;
337
320
338
321
switch (_timer)
339
322
{
340
323
case TIMERA0:
341
- {
342
- if ( frequency < F_CPU / ( 64 * 256 ) )
343
- PWM_LOGERROR1 (" setPWM_Int: frequency must be >=" , F_CPU / ( 64 * 256 ) );
344
-
345
- setPeriod_TimerA0 (1000000UL / frequency);
324
+ {
325
+ setPeriod_TimerA0 (1000000UL / _frequency);
346
326
347
327
// start from 0, so to add 1 to DC and period
348
328
dutycycle = (( (uint32_t ) (pwmPeriod + 1 ) * (dutycycle + 1 ) ) ) >> 8 ;
@@ -375,9 +355,6 @@ class ATtiny_PWM
375
355
TCA0.SPLIT .CTRLB |= bit_mask;
376
356
}
377
357
378
- PWM_LOGDEBUG5 (" setPWM_Int: TCA0 pin =" , pin, " dutycycle =" , dutycycle,
379
- " , actual DC% =" , ((float ) dutycycle + 1 ) * 100 / (pwmPeriod + 1 ));
380
-
381
358
break ;
382
359
383
360
// /////////////////////////////////////////
@@ -393,11 +370,6 @@ class ATtiny_PWM
393
370
// dutycycle = (( (uint32_t) (pwmPeriod + 1) * (dutycycle + 1) ) ) >> 8;
394
371
// ////
395
372
396
- PWM_LOGDEBUG3 (" setPWM_Int: TIMERD0, _dutycycle =" , _dutycycle, " , dutycycle =" , dutycycle);
397
-
398
- if ( frequency < F_CPU / ( 32 * 256 ) )
399
- PWM_LOGERROR1 (" setPWM_Int: frequency must be >=" , F_CPU / ( 32 * 256 ) );
400
-
401
373
uint8_t oldSREG = SREG;
402
374
403
375
cli ();
@@ -458,11 +430,34 @@ class ATtiny_PWM
458
430
break ;
459
431
}
460
432
461
- pinMode (pin, OUTPUT);
433
+ return true ;
434
+ }
462
435
463
- _PWMEnabled = true ;
436
+ // /////////////////////////////////////////
437
+ // /////////////////////////////////////////
464
438
465
- return true ;
439
+ public:
440
+
441
+ // dutycycle from 0-65535 for 0%-100% to make use of 16-bit top register
442
+ bool setPWM_Int (const uint8_t & pin, const float & frequency, uint16_t dutycycle)
443
+ {
444
+ if (frequency != _frequency)
445
+ {
446
+ PWM_LOGDEBUG1 (" setPWM_Int: new freq =" , frequency);
447
+
448
+ _frequency = frequency;
449
+ }
450
+
451
+ if ( setPWM_Reg (pin, dutycycle) )
452
+ {
453
+ pinMode (pin, OUTPUT);
454
+
455
+ _PWMEnabled = true ;
456
+
457
+ return true ;
458
+ }
459
+
460
+ return false ;
466
461
}
467
462
468
463
// /////////////////////////////////////////
@@ -511,15 +506,26 @@ class ATtiny_PWM
511
506
return setPWM_Int (pin, _frequency, DCValue);
512
507
}
513
508
509
+ // /////////////////////////////////////////
510
+
511
+ // Faster than setPWM_DCPercentage_manual by not using float
512
+ // DCPercentage from 0-65535 for 0.0f - 100.0f
513
+ bool setPWM_DCPercentageInt_manual (const uint8_t & pin, const uint16_t & DCPercentage)
514
+ {
515
+ return ( setPWM_Reg ( pin, DCPercentage ) );
516
+ }
517
+
514
518
// /////////////////////////////////////////
515
519
516
520
// DCPercentage from 0.0f - 100.0f for 0-65535
517
521
bool setPWM_DCPercentage_manual (const uint8_t & pin, const float & DCPercentage)
518
522
{
523
+ _dutycycle = ( DCPercentage * MAX_16BIT ) / 100 .0f ;
524
+
519
525
// Convert to DCValue based on resolution = MAX_16BIT
520
526
PWM_LOGDEBUG3 (F (" setPWM_DCPercentage_manual: DCPercentage =" ), DCPercentage, F (" , dc =" ), ( DCPercentage * MAX_16BIT ) / 100 .0f );
521
527
522
- return setPWM_manual (pin, ( DCPercentage * MAX_16BIT ) / 100 . 0f );
528
+ return setPWM_Int (pin, _frequency, _dutycycle );
523
529
}
524
530
525
531
// /////////////////////////////////////////
0 commit comments