Hier sind mal die Quelldateien des Moduls zur Helligkeitsmessung.
Erklären tu ich mal nix... Falls was unklar ist, kannst ja fragen (bevor ich hier ins Blaue rein was erkläre und mir den Wolf tippsle)
Es ist als Anregung gedacht. "Out of the Box" wird es wohl eh nicht laufen...
hell.h
hell.cCode:#ifndef _HELL_H_ #define _HELL_H_ extern void hell_init(); extern void hell_intro(); extern uint8_t hell_loop(); extern void hell_mess_start(); #define HELL_MAX 0x1ff enum { HS_IDLE, // inaktiv HS_AWAIT_INTRO, // warten auf Schedule von timer1-job HS_AWAIT_PATTERN_GAP, // warten auf Loch im Anzeigen-MUX HS_MESS, HS_MESS_OK, HS_MESS_TIMEOUT, HS_MESS_DONE }; #define HELL_NWERT 16 typedef struct { uint8_t debug; uint8_t state; uint16_t icr1; uint16_t max; uint16_t wert; uint8_t count; } hell_t; extern hell_t hell; #endif // _HELL_H_
Code:#include <AVR.h> #include <avr/delay.h> #include "ports.h" #include "pattern.h" #include "timer1-job.h" #include "hell.h" #include "main.h" hell_t hell; void hell_init() { hell.state = HS_IDLE; // AIN+ als Eingang MAKE_IN (PORT_AIN0); CLR (PORT_AIN0); // disable AC (ACD = 1) // AC Input Capture on -> disconnect from Input Capture of Timer/Counter1 // AIN0(+) = kein Bandgap ACSR = (0 << ACD) | (0 << ACIC) | (0 << ACBG); // AC MUX enable (AC-Input = ADC-MUX-Output, falls ADC disabled) SFIOR |= (1 << ACME); ADMUX = 0x7 & PORTC_AIN1; } void hell_intro() { hell.state = HS_AWAIT_PATTERN_GAP; hell.max = HELL_MAX; } void hell_mess_start() { SET_ANODES; hell.state = HS_MESS; hell.debug = 0; // Kathoden wurden in pattern::pattern_out() gesetzt. // enable AC (ACD = 0) // AC Input Capture on -> connect to Input Capture of Timer/Counter1 // AIN0(+) = kein Bandgap ACSR = (0 << ACD) | (1 << ACIC) | (0 << ACBG); // stop timer1 // disconnect timer1 from output pin OC, no PWM TCCR1A = 0; TCCR1B = (1 << ICNC1) | (1 << ICES1); // Load capacity via AIN- push-pull cli(); OCR1A = hell.max; // Reset Timer1 TCNT1 = 0; // PortC.x Pegel _delay_loop_1 (30); // enable Input Capture Interrupt TIMSK |= (1 << TICIE1) | (1 << OCIE1A); // start timer 1 at 1/64 (011) // no clear on compare match // noise cancel // input capture edge = raising (mess = AIN(-)) // don't change ICNC1 and ICES1 i.o. not to trigger an IRQ // clear Timer1 Flags TIFR = TIFR_T1; TCCR1B = (1 << ICNC1) | (1 << ICES1) | (1 << CS11) | (1 << CS10); // here we go! // start discharging via external resistor // AIN- to high Z MAKE_IN (PORTC_AIN1); CLR (PORTC_AIN1); sei(); } uint8_t hell_loop() { if (hell.state <= HS_MESS) return T1_CLAIM; if (hell.state == HS_MESS_TIMEOUT) hell.icr1 = hell.max; hell.state = HS_MESS_DONE; // disconnect InCapt1 from AC ACSR = (0 << ACD) | (0 << ACIC); return T1_DONE; } SIGNAL (_handle_icp1_oc1a) { hell.icr1 = ICR1; uint8_t state = HS_MESS_TIMEOUT; if (ACSR & (1 << ACIC)) state = HS_MESS_OK; hell.state = state; SET (PORTC_AIN1); MAKE_OUT (PORTC_AIN1); TIMSK &= ~TIMSK_T1; } // Bit ACIS in ACSR merkt, ob ein Overflow (OC1A) auftrat, // denn beim Betreten der ISR wird das OCF1A gelöscht. void __attribute__((naked)) SIG_OUTPUT_COMPARE1A() { cbi (ACSR, ACIC); rjmp (_handle_icp1_oc1a); } void __attribute__((naked)) SIG_INPUT_CAPTURE1() { rjmp (_handle_icp1_oc1a); }






Zitieren
Nö, oder???


Lesezeichen