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
Code:
#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_
hell.c
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);
}
Lesezeichen