// Analisi del progetto su Minute di Analisi giorno 15/05
#include "wiring_private.h" // utili funzioni sbi e cbi
// Gestione flag binaria
#define RFLAG GPIOR0
// Definizioni per Scheduler Componenti
#define ADCRATE 20
volatile uint8_t adccnt=ADCRATE;
// Lettore ADC
volatile union {
uint32_t v32;
uint8_t v[4]; // Vettore grb
} grb;
volatile uint32_t ogrb = 0;
// Flag binaria per stampa
#define FSTAMPA 0
// Definisco dove far uscire il segnale: PORT, DDR e NBIT, quanti LED e vettore (GRB)
#define PORT PORTB
#define DDR DDRB
#define NBIT PB0
//
void setup() {
Serial.begin(9600); // Per debug
// Inizializza ADC
ADCSRB = 0;
ADCSRA = _BV(ADEN) | _BV(ADIE) | 7; // ADIE = AD Interrupt Enable
// Inizializza scheduler su COMPA
OCR0A = 0;
cbi(TCCR0A, WGM00); // Normal mode
cbi(TCCR0A, WGM01); // Normal mode
cbi(TCCR0B, WGM02); // Normal mode
sbi(TIMSK0, OCIE0A);
// Inizializza PWM su TIMER2
TCCR2A = _BV(COM2B1) | _BV(WGM21) | _BV(WGM20); // Fast PWM
TCCR2B = _BV(WGM22) | 1; // No Prescaler
sbi(DDRD, DDD3); // OC2B su PD3
sbi(DDRD, DDD2); // OC2B su PD2
cbi(PORTD, PD3);
OCR2A = 20;
OCR2B = 12;
sbi(TIMSK2, OCIE2B);
}
///////////////////////
void loop() {
if (bit_is_set(RFLAG, FSTAMPA)) {
Serial.println(grb.v32, HEX);
cbi(RFLAG, FSTAMPA);
}
}
ISR(TIMER0_COMPB_vect) {
if (adccnt) {
if(--adccnt == 0) {
ADMUX = _BV(REFS0) |_BV(ADLAR) | 2; // ADMUX è nella sezione 24.9.1 di Excel
sbi(ADCSRA,ADSC);
adccnt=ADCRATE;
}
}
}
ISR(ADC_vect) {
uint8_t i=ADMUX & 3;
grb.v[i]=ADCH;
if (i) {
ADMUX = _BV(REFS0) |_BV(ADLAR) | --i;
sbi(ADCSRA,ADSC);
} else if (ogrb != grb.v32) {
sbi(RFLAG, FSTAMPA);
ogrb = grb.v32;
}
}
ISR(TIMER2_COMPB_vect, ISR_NAKED) {
sbi(PORTD, PD2);
asm(
"push r0 \n"
"in r0, 0x3f \n"
"push r0 \n"
"out 0x3f, r0 \n"
"pop r0 \n"
"reti \n"
);
cbi(PORTD, PD2);
/* on OCR2B match */
}
Green ........... Red ............ Blue