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


Korrektur der Firmware, von Michael Gaus

Müsste das statt Pinb nicht Pinc und statt Portb.0...Portb.3 nicht Pinc.0...Pinc.3 heißen, es sollen ja die Eingänge abgefragt werden?

   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 = Pinc                              'Port
     If Dat = 5 Then A = Portc.0                          'Portbits
     If Dat = 6 Then A = Portc.1
     If Dat = 7 Then A = Portc.2
     If Dat = 8 Then A = Portc.3

Antwort: Das stimmt wohl, die Eingaben müssen auf Port C geändert werden. Diese Version für den Mega8 wurde nicht so sorgfältig geprüft wie die Holtek-Version für die Lenpakete. Es würde mich nicht wundern, wenn noch mehr Fehler auftauchen.  

Weitere Korrekturen, von Michael Gaus

Ich habe entsprechende Änderungen vorgenommen und mit der neuesten Bascom-AVR Version 2.0.7.5 Demo kompiliert. Dabei wurde angemeckert, dass "Adr" ein "reserved Word" sei, ich habe dann alle "Adr" erstzt durch "Addr".

Änderungen:
1) PINB ersetzt durch PINC, PORTB.x ersetzt durch PINC.x , s.o.
2) Skip if S1/S2=0/1 waren alle verdreht abgefragt => korrigiert
3) Beim Label "Programmieren" muss es in der 2. Zeile nach dem "Do" Befehl heißen: PORTD = Adrlo OR &HF0 statt Addr
4) Bei PWM Config: clear_down geändert in clear_up
5. C- und D-Zählschleife am die Holtek-Version angeglichen

Down load:  Tpsm8_korrigiert_2.zip


'--------------------------------------------------------------
' Tasten-programmierbare Steuerung TPS
' ATmega8, intern 8 MHz, 2 ADC, 2 PWM
'--------------------------------------------------------------

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


Dim Addr 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_up , Compare_b_pwm = Clear_up
Start Timer1


Waitms 200

'Test: Zählschleife
'Dat = &H45 : Writeeeprom Dat , 0 'A=5
'Dat = &H52 : Writeeeprom Dat , 1 'C=A
'Dat = &H11 : Writeeeprom Dat , 2 'Por=1
'Dat = &H27 : Writeeeprom Dat , 3 '200 ms
'Dat = &H10 : Writeeeprom Dat , 4 'Port=0
'Dat = &H27 : Writeeeprom Dat , 5 '200 ms
'Dat = &HA2 : Writeeeprom Dat , 6 'C-mal jmp 2
'Dat = &H30 : Writeeeprom Dat , 7 'Ende


'Test: Unterprogramm
'Dat = &H4F : Writeeeprom Dat , 0 'A=15
'Dat = &H52 : Writeeeprom Dat , 1 'C=A
'Dat = &H82 : Writeeeprom Dat , 2 'Adr 32...
'Dat = &HD0 : Writeeeprom Dat , 3 'Call 32+0
'Dat = &H80 : Writeeeprom Dat , 4 'Adr 00...
'Dat = &HA2 : Writeeeprom Dat , 5 'C-mal jmp 2
'Dat = &H30 : Writeeeprom Dat , 6 'Ende
'Unterprogramm ab Adresse 32
'Dat = &H11 : Writeeeprom Dat , 32 'Port=1
'Dat = &H27 : Writeeeprom Dat , 33 '200 ms
'Dat = &H10 : Writeeeprom Dat , 34 'Port=0
'Dat = &H27 : Writeeeprom Dat , 35 '200 ms
'Dat = &H27 : Writeeeprom Dat , 35 '200 ms
'Dat = &HE0 : Writeeeprom Dat , 36 'Return


'Test: Verzweigung, Blinken wenn ADC < 7
'Dat = &H47 : Writeeeprom Dat , 0 'A=7
'Dat = &H51 : Writeeeprom Dat , 1 'B=A
'Dat = &H69 : Writeeeprom Dat , 2 'A=ADC
'Dat = &H82 : Writeeeprom Dat , 3 'Adr 32...
'Dat = &HC2 : Writeeeprom Dat , 4 'if A<B then Adr=Adr+1
'Dat = &HD0 : Writeeeprom Dat , 5 'Call 32+0
'Dat = &H80 : Writeeeprom Dat , 6 'Adr 00...
'Dat = &H90 : Writeeeprom Dat , 7 'Jump 00
'Unterprogramm ab Adresse 32
'Dat = &H11 : Writeeeprom Dat , 32 'Port=1
'Dat = &H27 : Writeeeprom Dat , 33 '200 ms
'Dat = &H10 : Writeeeprom Dat , 34 'Port=0
'Dat = &H27 : Writeeeprom Dat , 35 '200 ms
'Dat = &H27 : Writeeeprom Dat , 35 '200 ms
'Dat = &HE0 : Writeeeprom Dat , 36 'Return

'Test : Tastenabfrage S1
'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


Waitms 200

If S2 = 0 Then
Goto Programmieren
Else
Ausfuehren:
Addr = 0
Do
Readeeprom Eebyte , Addr
Addr = Addr + 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
Addr = Addr - 1
Addr = Addr - 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 = Pinc 'Port
If Dat = 5 Then A = Pinc.0 'Portbits
If Dat = 6 Then A = Pinc.1
If Dat = 7 Then A = Pinc.2
If Dat = 8 Then A = Pinc.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
Addr = Adrhi * 16 'Springe absolut 0...255
Addr = Addr + Dat
End If
If Kom = 10 Then
If C > 0 Then 'C-mal
C = C - 1
C = C And 15
Addr = Adrhi * 16 'Springe absolut 0...255
Addr = Addr + Dat
End If

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

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

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


Programmieren:
Addr = 0
Prog = 0
Do
Adrlo = Addr And 15 'Adresse anzeigen
Portd = Adrlo Or &HF0
Waitms 300
Portd = 0 Or &HF0
Waitms 200
Readeeprom Eebyte , Addr
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 , Addr
Portd = 255 - 0
Waitms 600
Addr = Addr + 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 , Addr
Portd = 0 Or &HF0
Waitms 600
Addr = Addr + 1
Prog = 0
End If
If Prog = 7 Then
Addr = Addr + 1
Prog = 0
End If
Waitms 50
Do
Loop Until S2 = 1
Waitms 50
End If
Loop Until Prog = 0
Loop

End


Korrektur zum Port-Lesen, von Manfred Tischer

Im Programm muss man bei Verarbeitung des Befehls A=Din beachten, dass ja nur das untere Nibble des Bytes genutzt wird. Die beiden AD-Eingänge sind ja auch auf PortC (Teile des oberen Nibble). Von daher müssen beim Verarbeiten dieses Befehls die oberen Bits ausgeblendet werden. Ansonsten funktionieren anschließende Vergleiche ggf. nicht korrekt.

z.B.:
A=Din
B=A
A=1110
A=B? (Ergebnis des Vergleichs hängt vom Eingangssignal an den Analogeingängen ab)

Mit folgender Änderung für das Komando 6 ist das Problem aus meiner Sicht behoben.

    If Kom = 6 Then
      If Dat = 1 Then A = B                      
      If Dat = 2 Then A = C
      If Dat = 3 Then A = D
      If Dat = 4 Then A = &H0F And Pinc          
      If Dat = 5 Then A = Pinc.0                  '
      If Dat = 6 Then A = Pinc.1
      If Dat = 7 Then A = Pinc.2
      If Dat = 8 Then A = Pinc.3
      If Dat = 9 Then
        Dd = Getadc(4)                           
        Dd = Dd / 64
        A = Dd
      End If
      If Dat = 10 Then
        Dd = Getadc(5)                          
        Dd = Dd / 64
        A = Dd
      End If
    End If


Download der korrigierten Version, kompiliert mit Bascom 1.11.9.8: Tpsm8_n3.zip

(Hinweis von B.K: Daraufhin habe ich noch mal in den Quelltext der Holtek-Version geschaut, dort war es schon genauso wie jetzt hier koorigiert:
In Holtek-C:    if (Dat == 4) A = _pa & 15;)


Elektronik-Labor  Projekte   TPS