Ereignissteuerung mit Bascom        

 
                      Elektronik-Labor  Bastelecke  Projekte  Mikrocontoller                        



Das ES-M32: http://www.elexs.de/ESM32.htm

Eine  typische Anwendung für einen Mikrocontroller ist ein Zeitschalter. Ein Eingangssignal z.B. von einem Schalter wird erkannt, und darauf ein Ausgang für eine gewisse Zeit eingeschaltet. Ist ja ganz einfach. Aber was ist, wenn man zwei oder mehr Eingänge hat und mehrere Vorgänge unabhängig voneinander auslösen will? Der Mikrocontroller müsste dann quasi gleichzeitig auf alle Eingänge achten, und sich quasi gleichzeitig um mehrere Ausgänge kümmern. Gebraucht wird also eine Art Multitasking. Hier wird ein ATmega32 verwendet.


Die Aufgabe ist mit einer Timer-Prozedur lösbar. Die Eingänge werden dann zwar auch nicht wirklich gleichzeitig ausgewertet, sondern sehr schnell hintereinander. Aber die Prozedur wird in schneller Folge immer wieder aufgerufen. Wenn dies 100-mal in der Sekunde passiert, ist die Reaktionszeit auf ein Ereignis maximal 10 ms. Für viele Aufgaben geht das als Echtzeit durch.


'Bascom ATmega32, Eingänge, Zeitsteuerung, Ausagänge

$regfile = "m32def.dat"
$crystal = 11059200
$hwstack = 16
$swstack = 32
$framesize = 32
Baud = 9600

Dim i1, i2, i3, i4 as Integer


Config Portd = &B00110000
Config Timer0 = Timer , Prescale = 1024
Enable Interrupts
Enable Timer0
On Timer0 Tim0isr

Do
  waitms 1000
  print i1
Loop

'11,0592 MHz / 1024 / 108 = 100 Hz
Tim0isr:
  timer0=256-108
  toggle  portd.4
  i1 = i1+1
Return

End


Im ersten Versuch soll nur der Timer 0 eingerichtet werden und eine Interruptprozedur mit 100 Hz laufen. Damit man etwas sieht, wird eine LED getoggelt. Sie flackert dann mit 50 Hz. Zur Überprüfung wird ein Zähler i1 erhöht. Im Hauptprogramm wird alle 1000 ms der Zählerstand an das Terminal gesendet. Der Zählerstand erhöht sich jedes Mal um 100. Man weiß also, dass die 10 ms stimmen.





Im nächsten Schritt werden in der Timerprozedur zwei Eingänge abgefragt und zwei Ausgänge beschaltet. Zu jedem Vorgang soll ein Zähler i1, i2 usw. als Zeitgeber gehören. Damit wird eine Art Uhr für jeden Vorgang gebildet. Am Anfang muss ein Eingang für mindestens 30 ms low sein, damit ein gültiges Signal erkannt wird. So wird eine Entprellung erreicht. Dann läuft die Uhr weiter und bestimmt, wie lange ein Ausgang eingeschaltet werden soll. Erst wenn der Vorgang beendet wird, wird der Zähler wieder auf 0 gesetzt und ist dann erst bereit für ein neues Ereignis.



'Bascom ATmega32, Eingänge, Zeitsteuerung, Ausagänge

$regfile = "m32def.dat"
$crystal = 11059200
$hwstack = 16
$swstack = 32
$framesize = 32
Baud = 9600

Dim i1, i2, i3, i4 as Integer

Config Portd = &B00110000
Portd.2 = 1
Portd.3 = 1
Portd.6 = 1
Portd.7 = 1


Config Timer0 = Timer , Prescale = 1024
Enable Interrupts
Enable Timer0
On Timer0 Tim0isr

Do
Loop

'11,0592 MHz / 1024 / 108 = 100 Hz
Tim0isr:
timer0=256-108
'Eingang D2, Timer i1, Ausgang D4
if pind.2=0 AND i1<3 then i1=i1+1 ' Taste gedrückt?
if i1<3 AND pind.2=1 then i1=0 ' Entprellung
if i1 > 2 then i1 = i1 + 1 ' Timer läuft
if i1 = 4 then portd.4=1 ' Impuls Start
if i1 = 104 then portd.4=0 ' 1 s, Impuls Ende
if i1 = 104 then i1=0 ' Timer Stop

'Eingang D3, Timer i2, Ausgang D5
if pind.3=0 AND i2<3 then i2=i2+1 ' Taste gedrückt?
if i2<3 AND pind.3=1 then i2=0 ' Entprellung
if i2 > 2 then i2 = i2 + 1 ' Timer läuft
if i2 = 4 then portd.5=1 ' Impuls Start
if i2 = 204 then portd.5=0 ' 2 s, Impuls Ende
if i2 = 204 then i2=0 ' Timer Sto

Return

End

Hier werden die Eingänge angefragt D2 und D3 und die Ausgänge D4 und D5 gesteuert. Das passt zu den Tasten S1 und S2 auf dem ES-M32 und  zu den beiden LEDs. Mit einem Druck auf S1 wird LED1 für eine Sekunde eingeschaltet. Mit einem Druck wird S2 für zwei Sekunden eingeschaltet. Beide Vorgänge funktionieren völlig unabhängig voneinander. Man kann also die Taster gleichzeitig oder nacheinander drücken. Die jeweilige Zeit startet mit dem Druck auf den jeweiligen Taster.


Tim0isr:
timer0=256-108
'Eingang D2, Timer i1, Ausgang D4
if pind.2=0 AND i1<3 then i1=i1+1 ' Taste 1 gedrückt?
if i1<3 AND pind.2=1 then i1=0 ' Entprellung
if i1 > 2 then i1 = i1 + 1 ' Timer läuft
if i1 = 4 then portd.4=1 ' Impuls Start
if i1 = 104 then portd.4=0 ' 1 s, Impuls Ende
if i1 = 104 then i1=0 ' Timer Stop

'Eingang D3, Timer i2, Ausgang D5
if pind.3=0 AND i2<3 then i2=i2+1 ' Taste 2 gedrückt?
if i2<3 AND pind.3=1 then i2=0 ' Entprellung
if i2 > 2 then i2 = i2 + 1 ' Timer läuft
if i2 = 4 then portd.5=1 ' Impuls Start
if i2 = 204 then portd.5=0 ' 2 s, Impuls Ende
if i2 = 204 then i2=0 ' Timer Stop

'Eingang D3, Timer i3, Ausgang D5
if pind.6=0 AND i3<3 then i3=i3+1 ' Taste 3 gedrückt?
if i3<3 AND pind.6=1 then i3=0 ' Entprellung
if i3 > 2 then
i3 = i3 + 1 ' Timer läuft
if i3 = 4 then portd.5=1 ' Impuls Start
if i3 = 34 then portd.5=0 ' 300 ms, Impuls Ende
if i3 = 64 then portd.5=1 ' Impuls Start
if i3 = 94 then portd.5=0 ' 300 ms, Impuls Ende
if i3 = 124 then portd.5=1 ' Impuls Start
if i3 = 154 then portd.5=0 ' 300 ms, Impuls Ende
if i3 = 154 then i3=0 ' Timer Stop
end if


Ein drittes Ereignis wurde noch hinzugefügt, wobei diesmal gleich drei Impulse erzeugt werden. Der zugehörige Code ist etwas länger. Damit nicht jede if-Abfrage behandelt werden muss, auch wenn sie gerade nicht aktuelle ist, werden die Ausgaben in eine if-Schleife gesetzt, die davon abhängt ob das Ereignis gestartet wurde. Wenn nämlich sehr viele Zeilen in der Interruptprozedur stehen, sollte die Abarbeitung niemals länger als 10 ms dauern.





Elektronik-Labor  Bastelecke  Projekte  Mikrocontoller