/* Einfacher Füllstandsmesser.
Gemessen wird die Luftschall-Laufzeit zwischen Tankdom und Wasseroberfläche.
Ohne Temperaturkompensation.
Füllstand 0 bei 190 cm Luft fest eingebaut, keine Konfiguration, keine Tasten.
Keine Helligkeitsmodulation.
henni, 180906
Hardware:
1 PA2 RESET frei
2 PD0 RxD frei
3 PD1 TxD frei
4 PA1 XTAL2 frei (Uhrenquarz 32,768 kHz)
5 PA0 XTAL1 frei (Uhrenquarz)
6 PD2 LED-Display Anode Zehner + Hunderter
7 PD3 LED-Display Anode Einer
8 PD4 frei
9 PD5 OC0B Ultraschall-Sendeimpuls, low-aktiv, Vorderflanke
10 GND
11 PD6 ICP1 Ultraschall-Empfangsimpuls, low-aktiv, Vorderflanke
12 PB0 LED-Display Katoden (ohne Widerstände) a..g
.. ... ...
19 PB7 LED-Display Katode Hunderter (nur "1")
20 Ucc
*/
#include <avr/io.h>
#include <avr/fuse.h>
#include <avr/signature.h> // gepatcht: "const" weg!
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <avr/pgmspace.h>
typedef uint8_t byte;
FUSES={
0xE6, // 128 kHz
0xDF,
0xFF,
};
/* Zeitbetrachtung:
Auflösung: 343 m/s / 128 kHz / 2 = 1,34 mm
Zählumfang: 3 m / 1,34 mm = 2240 (16 Bit)
Messzeit: 6 m / 343 m/s < 20 ms (empfohlen: > 20 ms)
MulDiv-Zahlen: Weg in cm = Takte * 17 / 128,
wäre c = 128 kHz / 128 * 17 * 0,02 m = 340 m/s
Temperaturkompensation: c = (331,6 + 0,6 T/°C) m/s
*/
static byte segl,segh,z,t0h;
static const PROGMEM byte seg7[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
// Berechnet segl und segh: Ziffern ohne vorlaufende Nullen
// Ohne itoa() u.ä. sondern "zu Fuß"
static void show() {
byte zm=z/10;
byte zl=z%10;
byte zh=zm>=10?0x80:0;
if (zh) zm-=10;
segl=pgm_read_byte(seg7+zl);
segh=zm|zh?pgm_read_byte(seg7+zm)|zh:0;
}
// 128 kHz / 256 = 500 Hz: Multiplexen der Anzeige
ISR(TIMER0_OVF_vect) {
++t0h; // Überlauf mit rund 2 Hz
PORTD&=~0x08;
PORTD&=~0x04;
byte k=~PORTB<<1;
if (!k) ++k;
PORTB=~k;
if (segl&k) PORTD|=0x08;
if (segh&k) PORTD|=0x04;
}
int main() {
PORTA=0x07; // Pullups zur Vermeidung offener Eingänge
PORTB=0xFF;
DDRB=0xFF;
PORTD=0x73;
DDRD=0x2C;
TCCR0B=0x01;
TIMSK=0x02; // Überlauf mit 500 Hz, Flackerfrequenz 60 Hz
sei();
for(;;) {
sleep_cpu();
if (t0h==0) {
PORTD&=~0x20; // Start Ultraschallimpuls mit 2 Hz
z=0;
TCNT1 = 0;
TIFR = 0x08; // Capture-Flag löschen
TCCR1B= 0x81; // Zeit messen, fallende Flanke
}
if (t0h==4) { // 2 ms lang
PORTD|= 0x20; // Ende Ultraschallimpuls
}
if (t0h==40) { // 20 ms Laufzeit lassen
TCCR1B= 0; // Zeitmessung stoppen
if (z) show();
else segl=segh=0x40; // "--" anzeigen
}
if (!z && TIFR&0x08) { // Erstes Echo
z=190-(ICR1*17>>7); // in Pegel umrechnen
}
}
}
Detected encoding: UTF-8 | 0
|