Moin alle,

ich habe ein 'kleines' Problem und bräuchte dabei mal Eure Hilfe:

Vor ein paar Tagen habe ich im Internet einen sehr interessanten Artikel darüber gelesen, wie man eine LED am µ-Controller als Signalindikator (Blinken, Dauerlicht) und 'gleichzeitig' als Lichtsensor benutzen kann (siehe Link 1 und Link 2).

Wie sie zum Leuchten gebracht wird, ist klar - als Sensor wird sie benutzt, in dem man einfach nur ihre lichtabhängige Kapazität mißt. Dazu wird die LED in Sperrrichtung an +Ub gelegt, und danach über den normalen Strombegrenzungswiderstand entladen. Die Zeit, die sich daraus ergibt, ist ein Maß für die lichtabhängige Kapazität.

Zur Verdeutlichung dazu folgendes Bild:

Bild hier  

Aus dem PDF-Dokument bzw. den darin enthaltenen Oszillogrammen habe ich entnommen, daß eine Meßperiode von 100 µs ausreichen sollte, um festzustellen, ob die LED angeleuchtet wird oder nicht.

Ich bin, was die Atmel-Programmierung angeht, noch blutiger Anfänger, habe aber trotzdem mal probiert, in AVR-Basic ein kleines Programm dafür zu schreiben (siehe Anhang). Als µ-Controller habe ich den AT90S2343 genommen, da ich davon noch einen übrig habe.

Das Grundgerüst ist relativ einfach und noch nicht optimiert, das Programm macht folgendes:

- die LED blinkt drei mal kurz, einmal lang als Indikator für den Programmstart und die bevorstehende Messung
- jetzt folgt 1 s Pause (LED dunkel), dann die Messung
- nun blinkt die LED drei mal kurz und signalisiert das Ende der Messung
- jetzt wird das Ergebnis der Messung ausgegeben: Ein mal lang blinken -> LED wurde angeleuchtet oder zwei mal lang blinken -> LED wurde nicht angeleuchtet

Bei der Messung gehe ich wie folgt vor: Ich schalte die LED in Sperrrichtung an +Ub, warte 1 ms (zwecks 'Aufladen' ihrer Kapazität) und starte dann Timer0. Wenn dieser überläuft (nach ca. 255 µs), verzweige ich in eine Unterroutine, in der der eine Ausgang auf Eingang umgeschaltet und dann abgefragt wird. Aus der Unterroutine kommend, wird mir der Zustand des Einganges nun per LED ausgegeben.

So weit, so gut. Das Problem dabei ist, es ändert sich nichts. Der Eingang bleibt laut Messung immer auf '1'.

Was mache ich falsch und wie mache ich es richtig?

Ich freue mich auf Eure Antworten und bin für jeden Hinweis dankbar!

Viele Grüße,

Radio Eriwan

Code:
'
$regfile = "2343DEF.dat"
$crystal = 1000000
'
Dim A As Byte
Dim An_oder_aus As Bit
'
Config Timer0 = Timer , Prescale = 1                        'Timer0 als Timer konfigurieren
Stop Timer0                                                 'Timer0 wieder anhalten, da er bei Konfiguration gleich gestartet wird
Timer0 = 0                                                  'Timer0 auf '0' setzen - Tcnt0 soll auch gehen!?
On Timer0 Tim0_isr                                          'Bei Überlauf (>255) zu Tim0_isr springen
Enable Timer0                                               'Timer-Interrupt einschalten
Enable Interrupts                                           'Interrupt-Handling einschalten
'
Config Portb = &B00000000                                   'Grundzustand einstellen -> alle Pins als Eingänge
Portb = &B11111111                                          'Pullup-Widerstände zuschalten
'
Do
'
Config Portb.3 = Output
Config Portb.4 = Output
Portb.4 = 0
'
For A = 1 To 3
  Portb.3 = 1
  Waitms 50
  Portb.3 = 0
  Waitms 1000
Next A
Portb.3 = 1
Waitms 1000
Portb.3 = 0
Waitms 1000
'
Portb.4 = 1
Waitms 1
Start Timer0                                                'Vor Ablauf der folgenden Wartezeit sollte die Messung fertig sein
Waitms 1
'
For A = 1 To 3
  Portb.3 = 1
  Waitms 50
  Portb.3 = 0
  Waitms 50
Next A
Waitms 1000
'
If An_oder_aus = 0 Then
  Portb.3 = 1
  Waitms 1000
  Portb.3 = 0
  Waitms 1000
End If
If An_oder_aus = 1 Then
  Portb.3 = 1
  Waitms 1000
  Portb.3 = 0
  Waitms 1000
  Portb.3 = 1
  Waitms 1000
  Portb.3 = 0
  Waitms 1000
End If
'
Loop
'
Tim0_isr:
  Stop Timer0
  An_oder_aus = 0
  Config Portb.4 = Input
  An_oder_aus = Pinb.4
  Config Portb.4 = Output
  Portb.4 = 0
  Timer0 = 0
Return
'
End