Source file: /~heha/basteln/Haus/Füllstand/Füll.zip/Füll1.cpp

/* 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-80