#include "wiring_private.h" // utili funzioni sbi e cbi
// DEFINIZIONI PER SCHEDULER COMPONENTI
#define ADCRATE 20
volatile uint8_t adccnt=ADCRATE;
// Lettore ADC
volatile union {
uint32_t v32;
uint8_t v[4];
} grb;
volatile uint32_t ogrb=0;
volatile uint8_t fstampa=0; // temporaneo per test
//
// 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
// inzializza ADC
ADCSRB=0;
ADCSRA = _BV(ADEN) | _BV(ADIE) | 7;
// Inizializza scheduler su COMPA
OCR0A=0;
cbi(TCCR0A, WGM00); // Normal Mode
cbi(TCCR0A, WGM01); // Normal Mode
cbi(TCCR0B, WGM02); // Normal Mode
sbi(TIMSK0, OCIE0A);
//inizializzo PWM su TIME1
}
//////////////////////////////
void loop() {
if(fstampa){
pix_show(3, grb.v);
// Serial.println(grb.v32, HEX);
fstampa=0;
}
}
ISR(TIMER0_COMPA_vect){
if(adccnt){
if(--adccnt == 0){
ADMUX = _BV(REFS0)|_BV(ADLAR) | 2;
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){
// fstampa=1;
ogrb=grb.v32;
pix_show(3, grb.v);
// vpix[0]=grb.v[0];
// vpix[1]=grb.v[1];
// vpix[2]=grb.v[2];
}
}
volatile void pix_show(uint8_t nb, uint8_t *vp) {
sbi(DDR,NBIT); // output
cbi(PORT,NBIT); //
cli();
asm volatile (
"lwhile0:\n\t"
"ld r24, %a[vp]+ \n\t" // (c17-18) Z=vp, byte=*Z++
"ldi r25, 8 \n\t" // (c19) e contatore bit
"lwhile:\n\t"
"nop \n\t" // (C+1=20) Fine ciclo: tau = 62,5*20 = 1,25 us
"sbi %[port],%[nbit] \n\t"// (c1) inizia il segnale H
"rjmp .+0 \n\t" // (c3-4) delay 2
"rjmp .+0 \n\t" // (c5-6) delay 2
"sbrs r24, 7 \n\t" // (c7)Test bit 7, skip se 1
"cbi %[port],%[nbit] \n\t"// (c8) se bit 0 impulso corto
"add r24, r24 \n\t" // (c9) r24 <<=1;
"subi r25, 1 \n\t" // (c10) Decremento contatore bit
"breq vnextb \n\t" // (c11) ciclo lungo, son finiti i bit
"rjmp .+0 \n\t" // (c12,13) delay 2
"cbi %[port],%[nbit] \n\t"// (c14) se bit 1, impulso lungo da 13
"rjmp .+0 \n\t" // (c15,16) delay 2
"nop \n\t" // (C17)
"rjmp lwhile \n\t" // (c18,19) entra nel ciclo;
"vnextb:\n\t" // (c12)
"subi %[nb], 1 \n\t" // (c13) Decremento contatore byte
"cbi %[port],%[nbit] \n\t"// (c14) se bit 1, impulso lungo da 13
"brne lwhile0 \n\t" // (c15,16) ... ciclo lungo x cambio byte
//
: [vp] "+e" (vp) // output list
: [nb] "d" (nb),
[port] "i" (_SFR_IO_ADDR(PORT)),
[nbit] "i" (NBIT)
: "r24", "r25"
);
sei(); // Riabilito interrupt
cbi(DDR,NBIT); // input
}
Green ........... Red ............ Blue