Mini-TPS mit ATmega8

Elektronik-Labor  Projekte   TPS



Dies ist eine Miniversion mit dem ATmega8. Alle Ein- und Ausgänge liegen am oberen Rand und wurden mit Serienwiderständen gegen Überlastung geschützt, die Eingänge 2,2 k, die Ausgänge mit 1 k. Die Ausgänge liegen wie bisher auf D0 bis D3, die Eingänge wie bisher auf C0 bis C3.

Abweichend vom ersten Entwurf mit dem Mega168  gibt es diesmal zwei PWM-Ausgänge (PWM1, PWM2) und zwei AD-Eingänge (AD1= ADC4 und AD2 = ADC5). Die Taste S1 liegt jetzt an D6 und S2 an D7. Anders als beim STK500 werden die Portausgänge nicht mehr invertiert. Aber man muss darauf achten, dass die beiden Tasten am gleichen Port liegen und die Pullups eingeschaltet bleiben.

Da die Tasten jetzt nicht mehr am Eingangsport liegen, bietet sich eine direkte Tastenabfrage über die bedingten Sprungbefehle an. Deshalb gibt es jetzt vier neue Optionen für den Befehl 12 (CC bis CF).

Die erweiterte Befehlsliste

10 ... 1F: Direkte Portausgabe 0...15
20 ... 2F: Wartezeit 0...15
(1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 30000,  60000 ms)
30 ... 3F: Sprung zurück 0...15
40 ... 4F: A = 0...15
51...5A: Ziel 1...10 = A
51: B = A
52: C = A
53: D = A
54: Dout = A
55: Dout.0 = A.0
56: Dout.1 = A.0
57: Dout.2 = A.0
58: Dout.3 = A.0
59: PWM1 = A
5A: PWM2 = A

61 ..6A: A = Quelle 1...10
61: A= B
62: A = C
63: A = D
64: A = Din
65: A = Din.0
66: A = Din.1
67: A = Din.2
68: A = Din.3
69: A = ADC1
6A: A = ADC2

71 ...7A: A = Ausdruck 1...10
71: A = A + 1
72: A = A – 1
73: A = A + B
74: A = A – B
75: A =  A * B
76: A = A / B
77: A = A And B
78: A = A Or B
79: A =  A Xor B
7A: A = Not A)
80 ... 8F: Adr-high = 0...15
90 ... 0F: Direkter Sprung auf Adr-high, Adr-low (0..15)
A0 ... AF: Zählschleife C-mal Adr-high, Adr-low (0..15)
B0 ... BF: Zählschleife D-mal Adr-high, Adr-low (0..15)
C1 ... CF: Bedingter Sprung: If (Bedingung 1...15) then Adr = Adr + 1
C1: if A > B then Adr = Adr + 1
C2: if A < B then Adr = Adr + 1
C3: if A = B then Adr = Adr + 1
C4: if Din.0 = 1 then Adr = Adr + 1
C5: if Din.1 = 1 then Adr = Adr + 1
C6: if Din.2 = 1 then Adr = Adr + 1
C7: if Din.3 = 1 then Adr = Adr + 1
C8: if Din.0 = 0 then Adr = Adr + 1
C9: if Din.1 = 0 then Adr = Adr + 1
CA: if  Din.2 = 0 then Adr = Adr + 1
CB: if Din.3 = 0 then Adr = Adr + 1
CC: if S1 = 0 then Adr = Adr + 1
CD: if  S2 = 0 then Adr = Adr + 1
CE: if S1 = 1 then Adr = Adr + 1
CF: if S2 = 1 then Adr = Adr + 1

D0 ... DF Unterprogrammaufruf Adr-high, Adr-low (0..15)
E0 ... EF: Return


Ein Beispiel zur Tastenabfrage S1: Solange man die Taste drückt, läuft ein schneller Zähler, die LEDs leuchten scheinbar mit halber Helligkeit. Lässt man die Taste los, friert der Zählerstand ein. Damit hat man praktisch ein Zufallsprogramm bzw. einen Würfel von Null bis 15.


'Dat = &HCC : Writeeeprom Dat , 0                  'if S1 = 1 then Adr = Adr + 1
'Dat = &H71 : Writeeeprom Dat , 1                    'A = A + 1
'Dat = &H54 : Writeeeprom Dat , 2                    'Dout =A
'Dat = &H33 : Writeeeprom Dat , 3                    'Adr = Adr - 3




Die Befehle in einer Programmierkarte

123456789ABCDE
0Dout1 msjmp -A=    AdrHijmpC*D*if ...callret
1 2 ms  B=AA= BA = A + 1    A > B  
2 5 ms  C=A A = CA = A – 1    A < B  
3 10  D=AA = DA = A + B    A = B  
4 20  Dout = AA = DinA = A – B    Din.0 = 1  
5 50  Dout.0 = A.0A = Din.0A =  A * B     Din.1 = 1  
6 100  Dout.1 = A.0 A = Din.1A = A / B       Din.2 = 1  
7 200  Dout.2 = A.0A = Din.2 A = A And B    Din.3 = 1  
8 500  Dout.3 = A.0 A = Din.3A = A Or B    Din.0 = 0   
9 1 s  PWM1 = AA = ADC1A =  A Xor B    Din.1 = 0  
A 2 s  PWM2 = A A = ADC2A = Not A     Din.2 = 0  
B 5 s     
    Din.3 = 0  
C 10          S1 = 0  
D 20         S2 = 0  
E 30         S1 = 1  
F 60         S2 = 1  


Der Controller läuft jetzt mit 8 MHz intern. EESAVE ist aktiviert. Das bedeutet, man kann beim ersten Brennen ein Programm im EEPROM mitgeben, es dann im Quelltext auskommentieren oder löschen und noch einmal brennen.




Insbesondere nützlicheUnterprogramme lassen sich auf diese Weise für die spätere Verwendung bereithalten. Das Bild zeigt ein Programm ab 00 in ein Unterprogramm ab &H20, ausgelesen mit dem STK500.




Download: TPSm8.zip

Und hier das komplette Listing mit allen Anpassungen für den Mega8.
'--------------------------------------------------------------
' Tasten-programmierbare Steuerung TPS
' ATmega8, intern 8 MHz, 2 ADC, 2 PWM
'--------------------------------------------------------------

$regfile = "m8def.dat"
$crystal = 8000000
$hwstack = 32
$swstack = 64
$framesize = 64


Dim Adr As Byte
Dim Eebyte As Byte
Dim Dat As Byte
Dim Kom As Byte
Dim Adrhi As Byte
Dim Adrlo As Byte
Dim Adrret As Byte
Dim Prog As Byte
Dim Dd As Word

Dim A As Byte
Dim B As Byte
Dim C As Byte
Dim D As Byte


Ddrd = &H0F 'D0...D1 Outputs
Portd = &HF0 'Pullup D4...D7
Portc = &H0F 'C0..C3 Inputs mit Pullup

S1 Alias Pind.6 'Dateneingabe
S2 Alias Pind.7 'Programmieren

Config Adc = Single , Prescaler = Auto , Reference = Off
Start Adc
Config Timer1 = Pwm , Prescale = 8 , Pwm = 8 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down
Start Timer1

If S2 = 0 Then
Goto Programmieren
Else
Ausfuehren:
Adr = 0
Do
Readeeprom Eebyte , Adr
Adr = Adr + 1
Dat = Eebyte And 15
Kom = Eebyte / 16
If Kom = 1 Then '1: Direkte Portausgabe
Portd = Dat Or &HF0
End If
If Kom = 2 Then '2: Wartezeit
If Dat = 0 Then Waitms 1
If Dat = 1 Then Waitms 2
If Dat = 2 Then Waitms 5
If Dat = 3 Then Waitms 10
If Dat = 4 Then Waitms 20
If Dat = 5 Then Waitms 50
If Dat = 6 Then Waitms 100
If Dat = 7 Then Waitms 200
If Dat = 8 Then Waitms 500
If Dat = 9 Then Waitms 1000
If Dat = 10 Then Waitms 2000
If Dat = 11 Then Waitms 5000
If Dat = 12 Then Waitms 10000
If Dat = 13 Then Waitms 20000
If Dat = 14 Then Waitms 30000
If Dat = 15 Then Waitms 60000
End If
If Kom = 3 Then '3: Sprung - relativ
Adr = Adr - 1
Adr = Adr - Dat
End If
If Kom = 4 Then
A = Dat
End If
If Kom = 5 Then
If Dat = 1 Then B = A 'Variablen
If Dat = 2 Then C = A
If Dat = 3 Then D = A
If Dat = 4 Then Portd = A Or &HF0 'Port
If Dat = 5 Then
If A.0 = 0 Then Portd.0 = 0 Else Portd.0 = 1 'Portbits
End If
If Dat = 6 Then
If A.0 = 0 Then Portd.1 = 0 Else Portd.1 = 1
End If
If Dat = 7 Then
If A.0 = 0 Then Portd.2 = 0 Else Portd.2 = 1
End If
If Dat = 8 Then
If A.0 = 0 Then Portd.3 = 0 Else Portd.3 = 1
End If
If Dat = 9 Then
Dd = A * 17 'PWM
Pwm1a = Dd 'PWM
End If
End If
If Kom = 6 Then
If Dat = 1 Then A = B 'Variablen
If Dat = 2 Then A = C
If Dat = 3 Then A = D
If Dat = 4 Then A = Pinb 'Port
If Dat = 5 Then A = Portb.0 'Portbits
If Dat = 6 Then A = Portb.1
If Dat = 7 Then A = Portb.2
If Dat = 8 Then A = Portb.3
If Dat = 9 Then
Dd = Getadc(4) 'ADC
Dd = Dd / 64
A = Dd
End If
If Dat = 10 Then
Dd = Getadc(5) 'ADC
Dd = Dd / 64
A = Dd
End If
End If
If Kom = 7 Then
If Dat = 1 Then A = A + 1
If Dat = 2 Then A = A - 1
If Dat = 3 Then A = A + B
If Dat = 4 Then A = A - B
If Dat = 5 Then A = A * B
If Dat = 6 Then A = A / B
If Dat = 7 Then A = A And B
If Dat = 8 Then A = A Or B
If Dat = 9 Then A = A Xor B
If Dat = 10 Then A = Not A
A = A And 15
End If
If Kom = 8 Then
Adrhi = Dat 'Oberes Nibble der Adresse
End If
If Kom = 9 Then
Adr = Adrhi * 16 'Springe absolut 0...255
Adr = Adr + Dat
End If
If Kom = 10 Then
C = C - 1
C = C And 15
If C > 0 Then 'C-mal
Adr = Adrhi * 16 'Springe absolut 0...255
Adr = Adr + Dat
End If

End If
If Kom = 11 Then
D = D - 1
D = D And 15
If D > 0 Then 'D-mal
Adr = Adrhi * 16 'Springe absolut 0...255
Adr = Adr + Dat
End If

End If
If Kom = 12 Then
If Dat = 1 Then
If A > B Then Adr = Adr + 1
End If
If Dat = 2 Then
If A < B Then Adr = Adr + 1
End If
If Dat = 3 Then
If A = B Then Adr = Adr + 1
End If
If Dat = 4 Then
If Pinc.0 = 1 Then Adr = Adr + 1
End If
If Dat = 5 Then
If Pinc.1 = 1 Then Adr = Adr + 1
End If
If Dat = 6 Then
If Pinc.2 = 1 Then Adr = Adr + 1
End If
If Dat = 7 Then
If Pinc.3 = 1 Then Adr = Adr + 1
End If
If Dat = 8 Then
If Pinc.0 = 0 Then Adr = Adr + 1
End If
If Dat = 9 Then
If Pinc.1 = 0 Then Adr = Adr + 1
End If
If Dat = 10 Then
If Pinc.2 = 0 Then Adr = Adr + 1
End If
If Dat = 11 Then
If Pinc.3 = 0 Then Adr = Adr + 1
End If
If Dat = 12 Then
If Pind.6 = 1 Then Adr = Adr + 1
End If
If Dat = 13 Then
If Pind.7 = 1 Then Adr = Adr + 1
End If
If Dat = 14 Then
If Pind.6 = 0 Then Adr = Adr + 1
End If
If Dat = 15 Then
If Pind.7 = 0 Then Adr = Adr + 1
End If

End If
If Kom = 13 Then
Adrret = Adr
Adr = Adrhi * 16 'Call Unterprogramm absolut 0...255
Adr = Adr + Dat
End If
If Kom = 14 Then
Adr = Adrret 'Return
End If
Loop
End If


Programmieren:
Adr = 0
Prog = 0
Do
Adrlo = Adr And 15 'Adresse anzeigen
Portd = Adr Or &HF0
Waitms 300
Portd = 0 Or &HF0
Waitms 200
Readeeprom Eebyte , Adr
Dat = Eebyte And 15
Kom = Eebyte / 16
Portd = Kom Or &HF0 'Befehl anzeigen
Do
Loop Until S2 = 1
Waitms 50

Prog = 1 'Phase 1: Befehl anzeigen
Do
If S1 = 0 Then

If Prog = 1 Then
Prog = 2
Kom = 15
End If
If Prog = 2 Then 'Phase 2: Befehl verändert
Kom = Kom + 1
Kom = Kom And 15
Portd = Kom Or &HF0
End If
If Prog = 3 Then : 'Phase 3: Befehl unverändert, Daten ändern
Prog = 5
Dat = 15
End If
If Prog = 4 Then 'Phase 4: Befehl und Daten geändert
Prog = 5
Dat = 15
End If
If Prog = 5 Then 'Phase 5: Daten verändert
Dat = Dat + 1
Dat = Dat And 15
Portd = Dat Or &HF0
End If
Waitms 50
Do
Loop Until S1 = 1
Waitms 50
End If

If S2 = 0 Then
If Prog = 3 Then Prog = 7 'nur angezeigt, nicht verändert
If Prog = 1 Then
Portd = Dat Or &HF0
Prog = 3
End If
If Prog = 4 Then
Portd = 255 - Dat
Prog = 6
End If
If Prog = 2 Then
Portd = Dat Or &HF0
Prog = 4
End If
If Prog = 6 Then 'nur Kommando wurde verändert
Dat = Dat And 15
Eebyte = Kom * 16
Eebyte = Eebyte + Dat
Writeeeprom Eebyte , Adr
Portd = 255 - 0
Waitms 600
Adr = Adr + 1
Prog = 0
End If
If Prog = 5 Then 'Daten wurden verändert
Dat = Dat And 15
Eebyte = Kom * 16
Eebyte = Eebyte + Dat
Writeeeprom Eebyte , Adr
Portd = 0 Or &HF0
Waitms 600
Adr = Adr + 1
Prog = 0
End If
If Prog = 7 Then
Adr = Adr + 1
Prog = 0
End If
Waitms 50
Do
Loop Until S2 = 1
Waitms 50
End If
Loop Until Prog = 0
Loop

End

zurück


Elektronik-Labor  Projekte   TPS