Skip to content

Instantly share code, notes, and snippets.

@Nkawu
Last active April 24, 2022 15:12
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Nkawu/15266a3635b554639f3b to your computer and use it in GitHub Desktop.
Save Nkawu/15266a3635b554639f3b to your computer and use it in GitHub Desktop.
PWM on the ATtiny85 with a complementary waveform & dead time
void setup()
{
// DDRB – Port B Data Direction Register (p64)
// 8-bit R/W [ : :DDB5:DDB4:DDB3:DDB2:DDB1:DDB0]
// PORTB = 1<<DDB1 | 1<<DDB0;
pinMode(0, OUTPUT); // 1<<DDB0: PWM output on pin 0 (^OC1A)
pinMode(1, OUTPUT); // 1<<DDB1: PWM output on pin 1 (OC1A)
// TCCR1 - Timer/Counter1 Control Register (p89)
// 8-bit R/W: [CTC1:PWM1A:COM1A1:COM1A0:CS13:CS12:CS11:CS10]
// Bit 6 – PWM1A: Pulse Width Modulator A Enable (b1 - enables PWM mode based on comparator OCR1A)
// Bits 5:4 – COM1A[1:0]: Comparator A Output Mode, Bits 1 and 0 (b01 - in PWM mode clears OC1A & sets ^OC1A on compare match)
// Bits 3:0 - CS1[3:0]: Clock Select Bits 3, 2, 1, and 0 (b0100 - Timer/Counter1 Prescale Select PCK/8)
TCCR1 = 1<<PWM1A | 0<<COM1A1 | 1<<COM1A0 | 0<<CS13 | 1<<CS12 | 0<<CS11 | 0<<CS10;
// GTCCR – General Timer/Counter1 Control Register (p90)
// 8-bit R/W & W: [ :PWM1B:COM1B1:COM1B0:FOC1B:FOC1A:PSR1: ]
// Bit 6 – PWM1B: Pulse Width Modulator B Enable (b0 - prevents Timer/Counter1 from using pin OC1B)
// Bits 5:4 – COM1B[1:0]: Comparator B Output Mode, Bits 1 and 0 (b00 - in PWM mode disconnects OC1B)
GTCCR = 0<<PWM1B | 0<<COM1B1 | 0<<COM1B0;
// OCR1C – Timer/Counter1 Output Compare RegisterC (p92)
// 8-bit R/W [MSB: : : : : : :LSB]
// Set OCR1B compare value and OCR1C TOP value (0-255)
OCR1C = 205;
// OCR1A –Timer/Counter1 Output Compare RegisterA (p91)
// 8-bit R/W [MSB: : : : : : :LSB]
// Set start duty cycle = (OCR1A + 1)/(OCR1C + 1)
OCR1A = 103; // (103+1)/(205+1) = 0.50 = 50% duty cycle
// f(PWM output) = 16.5Mhz / prescaler / (OCR1C + 1)
// 250kHz = CS13:10-0001 (PCK) + OCR1C-65
// 100kHz = CS13:10-0001 (PCK) + OCR1C-164
// 50kHz = CS13:10-0010 (PCK/2) + OCR1C-164
// 40kHz = CS13:10-0010 (PCK/2) + OCR1C-205 (40.048kHz)
// 20kHz = CS13:10-0011 (PCK/4) + OCR1C-205 (20.024kHz)
// 10kHz = CS13:10-0100 (PCK/8) + OCR1C-205 (10.012kHz)
// DTPS1 – Timer/Counter1 Dead Time Prescaler Register 1 (p106)
// 2-bit RW: [ : : : : : :DTPS11:DTPS10]
// Bits 1:0 - DTPS1[1:0]: Dead Time Prescaler: b11 << prescaler divides the T/C1 clock by 8x
DTPS1 = 1<<DTPS11 | 1<<DTPS10;
// DT1A – Timer/Counter1 Dead Time A (p107)
// 8-bit R/W: [DT1AH3:DT1AH2:DT1AH1:DT1AH0:DT1AL3:DT1AL2:DT1AL1:DT1AL0]
// Bits 7:4 - DT1AH[3:0]: Dead Time Value for OC1A Output (prescaled time/counter clock period multiplied by 0-15)
// Bits 3:0 – DT1AL[3:0]: Dead Time Value for ^OC1A Output (prescaled time/counter clock period multiplied by 0-15)
DT1A = 1<<DT1AH3 | 1<<DT1AH2 | 1<<DT1AH1 | 1<<DT1AH0 | 1<<DT1AL3 | 1<<DT1AL2 | 1<<DT1AL1 | 1<<DT1AL0;
}
void loop()
{
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment