Mega Tiny Core PWM demo for ATtiny1617

Thread Starter

robotDR

Joined Mar 17, 2020
93
Hi All,

Using the Mega Tiny Core:
https://github.com/SpenceKonde/megaTinyCore/tree/master

I'm using Demo 2. It works on PB0 as the demo is by default. But when I try and change the pin, it doesn't work. I'm using PWM capable pins too. I tried basically them all and it wont work.

This example is from the example pull down menu in arduino ide after loading the core.

However the demo is written slightly different on the git webpage and seems to imply PB1 and or PC1 can be used. When I copy paste this code into a new script, I can get now get PB1 to work but not PC1 or PB0.

So whats the difference?

Code from example pull down in ide:

Code:
/* Example 2: Variable frequency and duty cycle PWM
 * https://github.com/SpenceKonde/megaTinyCore/blob/master/megaavr/extras/TakingOverTCA0.md
 *
 * This generates PWM similar to the first example (though without the silly interrupt to change the duty cycle),
 * but takes it a step further and into more practical territory with two functions to set the duty cycle and frequency.
 * Calling those instead of this PWMDemo() function is all you'd need to make use of this.
 * Somewhere I think I have the same functionality implemented for the classic AVR "Timer1" style 16-bit timers.
 */
#if defined(MILLIS_USE_TIMERA0) || defined(__AVR_ATtinyxy2__)
  #error "This sketch takes over TCA0, don't use for millis here.  Pin mappings on 8-pin parts are different"
#endif

unsigned int Period = 0xFFFF;

void setup() {                // We will be outputting PWM on PB0
  pinMode(PIN_PB0, OUTPUT);   // PB0 - TCA0 WO0, pin7 on 14-pin parts
  takeOverTCA0();             // This replaces disabling and resettng the timer, required previously.
  TCA0.SINGLE.CTRLB = (TCA_SINGLE_CMP0EN_bm | TCA_SINGLE_WGMODE_SINGLESLOPE_gc);
  TCA0.SINGLE.PER   = Period; // Count all the way up to 0xFFFF
  //                             At 20MHz, this gives ~305Hz PWM
  TCA0.SINGLE.CMP0  = 0;
  TCA0.SINGLE.CTRLA = TCA_SINGLE_ENABLE_bm; // enable the timer with no prescaler
}

void loop() {

  PWMDemo(70000);   // 70kHz

}

void PWMDemo(unsigned long frequency) {
  setFrequency(frequency);
  setDutyCycle(128);// ~50%
  delay(4000);

}

void setDutyCycle(byte duty) {
  TCA0.SINGLE.CMP0 = map(duty, 0, 255, 0, Period);
}

void setFrequency(unsigned long freqInHz) {
  unsigned long tempperiod = (F_CPU / freqInHz);
  byte presc = 0;
  while (tempperiod > 65536 && presc < 7) {
    presc++;
    tempperiod      = tempperiod >> (presc > 4 ? 2 : 1);
  }
  Period            = tempperiod;
  TCA0.SINGLE.CTRLA = (presc << 1) | TCA_SINGLE_ENABLE_bm;
  TCA0.SINGLE.PER   = Period;
}
Code from git webpage:

Code:
#if defined(MILLIS_USE_TIMERA0) || defined(__AVR_ATtinyxy2__)
  #error "This sketch takes over TCA0, don't use for millis here.  Pin mappings on 8-pin parts are different"
#endif

// picked more or less randomly, other than the fact that everything has it, so it makes a good example :-)
#if defined(MEGATINYCORE)
  uint8_t OutputPin = PIN_PB1;
#else
  uint8_t OutputPin = PIN_PC1;
#endif
unsigned int Period   = 0xFFFF;

void setup() {

  pinMode(OutputPin, OUTPUT);
  #if defined MEGATINYCORE
  #if defined PORTMUX_TCAROUTEA
  PORTMUX.TCAROUTEA   &= 1 << 1;
  #elif defined PORTMUX_CTRLC
  PORTMUX.CTRLC   &= 1 << 1;
  #endif
  #else
  PORTMUX.TCAROUTEA = (PORTMUX.TCAROUTEA & ~(PORTMUX_TCA0_gm)) | PORTMUX_TCA0_PORTC_gc;
  #endif
  takeOverTCA0();                             // This replaces disabling and resettng the timer, required previously.
  TCA0.SINGLE.CTRLB   = (TCA_SINGLE_CMP1EN_bm | TCA_SINGLE_WGMODE_SINGLESLOPE_gc);
                                              // Single slope PWM mode, PWM on WO0
  TCA0.SINGLE.PER     = Period;               // Count all the way up to 0xFFFF
  TCA0.SINGLE.CMP1    = 0;                    // At 20MHz, this gives ~305Hz PWM
  TCA0.SINGLE.CTRLA   = TCA_SINGLE_ENABLE_bm; // Enable the timer with no prescaler
}

void loop() {
  PWMDemo(150000);    // 150kHz
  PWMDemo(70000);     // 70kHz
  PWMDemo(15000);     // 15kHz
  PWMDemo(3000);      // 3kHz
  PWMDemo(120);       // 120Hz
  PWMDemo(35);        // 35Hz
  PWMDemo(13);        // 13Hz
}

void PWMDemo(unsigned long frequency){
  setFrequency(frequency);
  setDutyCycle(64); // ~25%
  delay(4000);
  setDutyCycle(128);// ~50%
  delay(4000);
  setDutyCycle(192);// ~75%
  delay(4000);
}

void setDutyCycle(byte duty) {
  TCA0.SINGLE.CMP1 = map(duty, 0, 255, 0, Period);
}

void setFrequency(unsigned long freqInHz) {
  unsigned long tempperiod = (F_CPU / freqInHz);
  byte presc = 0;
  while (tempperiod > 65536 && presc < 7) {
    presc++;
    tempperiod = tempperiod >> (presc > 4 ? 2 : 1);
  }
  Period = tempperiod;
  TCA0.SINGLE.CTRLA = (presc << 1) | TCA_SINGLE_ENABLE_bm;
  TCA0.SINGLE.PER = Period;
}
Thank you!
 
Top