Fast PWM on ATTiny85

I am trying to create a buck converter around the ATTiny85. To do this, I need to have a PWM signal with a frequency around 250kHz and a controllable duty cycle. I have gotten the code to work for a 250kHz signal, but I am struggling controlling the duty cycle. I would like to have a potentiometer connected to one of the pins for testing. Below is my code with a fixed 50% duty cycle.

void setup(){
  DDRB |= (1<<PB1);     //  Set pin PB1 as output

  PLLCSR |= (1<<PLLE);    // PLL enable for asynchronous mode

  while ((PLLCSR & (1<<PLOCK)) == 0x00)
  {
      // Do nothing until plock bit is set
  }

  PLLCSR |= (1<<PCKE); // Sets the timer/clock1 source to RC oscillator

  TCCR1 =
          (1<<CTC1)   | // Clear Timer/Counter1 on match with OCR1A
          (1<<PWM1A)  | // Enable PWM mode
                        // Using OCR1A and reset after compare match with OCR1C
          (1<<COM1A1) | // Clear the PB1(OC1A) output line on compare match          
          (1<<CS10);    // Timer/Counter1 clock set to PCK (no prescale)

  //  Counter will count and reset
  //  after reaching this value (Sets frequency)
  OCR1C = 255;  //Set to 255 for 250kHz

  OCR1A = 125;  // Duty cycle of about 50%

}

void loop(){
  
}

I have gotten that code to run fine on my board, but I cannot control the duty cycle with it. Below is what I tried so I could connect a potentiometer, but it does not work. I am looking for any help to see what I am doing wrong.

int val = 0;
void setup(){
  DDRB |= (1<<PB1);     //  Set pin PB1 as output

  PLLCSR |= (1<<PLLE);    // PLL enable for asynchronous mode

  while ((PLLCSR & (1<<PLOCK)) == 0x00)
  {
      // Do nothing until plock bit is set
  }

  PLLCSR |= (1<<PCKE); // Sets the timer/clock1 source to RC oscillator

  TCCR1 =
          (1<<CTC1)   | // Clear Timer/Counter1 on match with OCR1A
          (1<<PWM1A)  | // Enable PWM mode
                        // Using OCR1A and reset after compare match with OCR1C
          (1<<COM1A1) | // Clear the PB1(OC1A) output line on compare match          
          (1<<CS10);    // Timer/Counter1 clock set to PCK (no prescale)

  //  Set PWM TOP value - counter will count and reset
  //  after reaching this value
  OCR1C = 255;  //Set to 255 for 250kHz

  ADMUX = 0x22;   // Sets Vcc as reference, sets ADC2(PB4) as input, left adjusts
  
  ADCSRA = 0xA4;  // Turn on the ADC, Turn on auto-trigger
                  // Set division factor-16

  ADCSRB = 0x00;   // Free running mode

  ADCSRA |= (1<<ADSC); //Start ADC

}

void loop(){
  while (ADCSRA & (0<<ADIF))
  {
    //do nothing while conversion in progress
  }
  ADCSRA |= (0<<ADIF); // Clear flag
  
  OCR1A = ADCH; //Set the counter compare register to the pot value
}

Thanks in advance!

The ADC output is (ADCH << 8) | ADCL, and its only 10 bit.

Perhaps

  OCR1A = ((ADCH & 3) << 6) | (ADCL >> 2); //Set the counter compare register to the top 8 bits of the pot value

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.