Skip to content

Instantly share code, notes, and snippets.

@adnbr
Last active June 12, 2024 10:32
Show Gist options
  • Save adnbr/9289235 to your computer and use it in GitHub Desktop.
Save adnbr/9289235 to your computer and use it in GitHub Desktop.
ADC input directly to PWM output, on an ATtiny13.
/* ---------------------------------------------------------------------
* PWM LED Brightness control for ATtiny13.
* Datasheet for ATtiny13: http://www.atmel.com/images/doc2535.pdf
*
* Pin configuration -
* PB1/OC0B: LED output (Pin 6)
* PB2/ADC1: Potentiometer input (Pin 7)
*
* ~100 bytes.
*
* Find out more: http://bit.ly/1eBhqHc
* -------------------------------------------------------------------*/
// 9.6 MHz, built in resonator
#define F_CPU 9600000
#define LED PB1
#include <avr/io.h>
void adc_setup (void)
{
// Set the ADC input to PB2/ADC1
ADMUX |= (1 << MUX0);
ADMUX |= (1 << ADLAR);
// Set the prescaler to clock/128 & enable ADC
// At 9.6 MHz this is 75 kHz.
// See ATtiny13 datasheet, Table 14.4.
ADCSRA |= (1 << ADPS1) | (1 << ADPS0) | (1 << ADEN);
}
int adc_read (void)
{
// Start the conversion
ADCSRA |= (1 << ADSC);
// Wait for it to finish
while (ADCSRA & (1 << ADSC));
return ADCH;
}
void pwm_setup (void)
{
// Set Timer 0 prescaler to clock/8.
// At 9.6 MHz this is 1.2 MHz.
// See ATtiny13 datasheet, Table 11.9.
TCCR0B |= (1 << CS01);
// Set to 'Fast PWM' mode
TCCR0A |= (1 << WGM01) | (1 << WGM00);
// Clear OC0B output on compare match, upwards counting.
TCCR0A |= (1 << COM0B1);
}
void pwm_write (int val)
{
OCR0B = val;
}
int main (void)
{
int adc_in;
// LED is an output.
DDRB |= (1 << LED);
adc_setup();
pwm_setup();
while (1) {
// Get the ADC value
adc_in = adc_read();
// Now write it to the PWM counter
pwm_write(adc_in);
}
}
@constrictor
Copy link

Dude, you better set PWM prescaler to full clock instead of clock/8. I used this code as a base for my simple project (2 PWMs for LED lamps) and having clock/8 resulted in LED PCB producing a 4.6KHz sound (1.2MHz/256). Obviously changing PWM to 9.6MHz made the sound disappear by shifting to ultrasound.

@chris-pws
Copy link

It appears that you're using an ADC prescaler of clock/8. According to Table 14.4, you'd also need to set the ADPS2 bit to achieve clock/128. While 1.2 MHz is outside of the suggested 50 to 200 kHz input clock for full resolution conversions, Section 14.5 states that an input clock frequency higher than 200 kHz can be used to achieve a higher sampling rate for the desired 8 bit reading.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment