Created
April 28, 2015 13:12
-
-
Save vindolin/7a08116ce926a596e6e0 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
#define F_CPU 8000000UL | |
#include <avr/io.h> | |
#include <avr/interrupt.h> | |
#include <util/delay.h> | |
#include <avr/sleep.h> | |
#include <avr/power.h> | |
const uint8_t MINPWM = 1; | |
const uint8_t MAXPWM = 255; | |
const uint8_t STEP = 1; | |
enum { UP, DOWN }; | |
uint16_t ReadChannel(uint8_t mux) { | |
uint8_t i; | |
uint16_t result; | |
ADMUX = mux; // ADCn Kanal waehlen | |
ADMUX &= ~_BV(REFS1) | ~_BV(REFS0); // VCC als Referenzspannung | |
//ADMUX |= _BV(REFS1) | _BV(REFS0); // interne Referenzspannung nutzen | |
ADCSRA = _BV(ADEN) | _BV(ADPS1) | _BV(ADPS0); // Frequenzvorteiler setzen auf 8 (1) und ADC aktivieren (1) | |
/* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest | |
also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */ | |
ADCSRA |= _BV(ADSC); // eine ADC-Wandlung | |
while ( ADCSRA & _BV(ADSC) ) { | |
; // auf Abschluss der Konvertierung warten | |
} | |
result = ADCW; // ADCW muss einmal gelesen werden, sonst wird Ergebnis der nächsten Wandlung nicht übernommen. | |
/* Eigentliche Messung - Mittelwert aus 4 aufeinanderfolgenden Wandlungen */ | |
result = 0; | |
for(i=0; i<4; i++ ) { | |
ADCSRA |= _BV(ADSC); // eine Wandlung "single conversion" | |
while ( ADCSRA & _BV(ADSC) ) { | |
; // auf Abschluss der Konvertierung warten | |
} | |
result += ADCW; // Wandlungsergebnisse aufaddieren | |
} | |
result /= 4; // Summe durch vier teilen = arithm. Mittelwert | |
ADCSRA &= ~_BV(ADEN); // ADC deaktivieren (2) | |
return result; | |
} | |
uint16_t ReadTemp(void) { | |
uint8_t i; | |
uint16_t result; | |
ADMUX = 4; // ADCn Kanal waehlen | |
// ADC Voltage reference selection, internal 1.1v | |
ADMUX &= ~_BV(REFS0); //0 | |
ADMUX |= _BV(REFS1); //1 | |
ADMUX &= ~_BV(REFS2); //0 | |
// Disable digital input of pin PB4 (ADC channel2) | |
DIDR0 |= _BV(ADC2D); | |
// Turn ADC on | |
ADCSRA |= _BV(ADEN); | |
/* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest | |
also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */ | |
ADCSRA |= _BV(ADSC); // eine ADC-Wandlung | |
while ( ADCSRA & _BV(ADSC) ) { | |
; // auf Abschluss der Konvertierung warten | |
} | |
result = ADCW; // ADCW muss einmal gelesen werden, sonst wird Ergebnis der nächsten Wandlung nicht übernommen. | |
/* Eigentliche Messung - Mittelwert aus 4 aufeinanderfolgenden Wandlungen */ | |
result = 0; | |
for(i=0; i<4; i++ ) { | |
ADCSRA |= _BV(ADSC); // eine Wandlung "single conversion" | |
while ( ADCSRA & _BV(ADSC) ) { | |
; // auf Abschluss der Konvertierung warten | |
} | |
result += ADCW; // Wandlungsergebnisse aufaddieren | |
} | |
result /= 4; // Summe durch vier teilen = arithm. Mittelwert | |
ADCSRA &= ~_BV(ADEN); // ADC deaktivieren (2) | |
return result; | |
} | |
ISR ( TIM0_OVF_vect ) { | |
static uint8_t direction = UP; | |
static uint8_t pwm = MINPWM; | |
if(direction == UP && pwm + STEP < MAXPWM) { | |
pwm+=STEP; | |
} else if(direction == DOWN && pwm - STEP > MINPWM) { | |
pwm-=STEP; | |
} else { | |
direction = !direction; | |
return; | |
} | |
// OCR0A = pwm; | |
OCR0B = ReadTemp() / 4; | |
} | |
void ioinit(void) { | |
// be green :) | |
if(1) { | |
power_timer1_disable(); | |
power_usi_disable(); | |
} | |
DDRB = _BV(PB0) | _BV(PB1) | _BV(PB2); // pins as output | |
PORTB |= _BV(PB2); | |
OCR0A = 0; // start value for PWM | |
OCR0B = 0; // start value for PWM | |
// WGM00,WGM01,WGM02 = mode 7, Fast PWM | |
// COM0B0, COM0B1 = set OC0A/OC0B on compare match | |
TCCR0A |= _BV(WGM00) | _BV(WGM01) | _BV(COM0A1) | _BV(COM0A0) | _BV(COM0B1) | _BV(COM0B0); | |
TCCR0B |= _BV(CS00) | _BV(CS01); // CLK/64 prescaler | |
TIMSK = _BV(TOIE0); // overflow interrupt | |
sei(); // enable interrupts | |
} | |
int main(void) { | |
ioinit(); | |
for(;;) { | |
// PORTB ^= _BV(PB2); // toggle pin PB2 | |
_delay_ms(1000); | |
sleep_mode(); | |
} | |
return 0; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment