Last active
June 12, 2024 10:32
-
-
Save adnbr/9289235 to your computer and use it in GitHub Desktop.
ADC input directly to PWM output, on an ATtiny13.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* --------------------------------------------------------------------- | |
* 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); | |
} | |
} |
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
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.