@Lebi, die Realisierung der Erkennung basiert auf "redet er mit mir oder tut ers nicht". Der AVR unten drin probiert eben reihum durch wie er eine Kommunikation aufbauen kann, hat er einen Kommuniaktionsweg gefunden, wird dieser gemerkt und die grüne LED leuchtet (AVR erkannt und gesprächig). Wird programmiert, wird der Kommikationsweg, ein Patchen der IO's vorgenommen. Das signalisiert bei aktivem Programiervorgang. Das Programm werde ich aber nochmals überarbeiten. Habe noch beim EEPROM-Flashen Fehllesungen, weil es zu früh den AVR trennt.
Code:
' AVR-Weiche für AVR-Programmiergerät
' (C) 2007 Wolfgang Schmid / www.wiesolator.de
$RegFile = "m8def.dat"
$Crystal = 8000000 ' interne 8 MHz
' Fuse-Bits
'$Prog &hFF, &h24, &hD9, &h00
LedRot Alias PortC.4
LedGruen Alias PortC.3
LedGelb Alias PortC.2
RES_T1 Alias PortB.7
SCK_T1 Alias PortB.5
MOSI_T1 Alias PortB.3
MISO_T1 Alias PinB.4
RES_T2 Alias PortD.2
SCK_T2 Alias PortB.2
MOSI_T2 Alias PortD.5
MISO_T2 Alias PinB.1
RES_T3 Alias PortB.7
SCK_T3 Alias PortB.6
MOSI_T3 Alias PortD.3
MISO_T3 Alias PinD.4
RES_PC Alias PinD.7
SCK_PC Alias PinB.0
MOSI_PC Alias PinD.6
MISO_PC Alias PortC.5
SupplyT1A Alias PortD.1
SupplyT1B Alias PortC.0
SupplyT23 Alias PortD.0
Const PrgEnB1 = &hAC
Const PrgEnB2 = &h53
Const PrgEnB3 = &h00
Const PRgEnB4 = &h00
Const TimeOut = 65000
Dim AvrTyp As Byte
Dim Retry As Byte
Dim Dummy As Byte
Dim Result As Byte
Dim AvrSend As Byte
Dim AvrEcho As Byte
Dim BitNr As Byte
Dim DeatTime As Word
Init:
' Allgemeine Signale von/zum PC
DDRD.7 = 0 : PortD.7 = 0 ' RESET von PC (Pull-Up aktiv)
DDRB.0 = 0 : PortB.0 = 0 ' SCK von PC (Pull-Up aktiv)
DDRD.6 = 0 : PortD.6 = 0 ' MOSI von PC (Pull-Up aktiv)
DDRC.5 = 1 : PortC.5 = 0 ' MISO an PC
' LED-Anzeige
DDRC.4 = 1
DDRC.3 = 1
DDRC.2 = 1
' AVR-Auswahl
Main:
GoSub DisConnectAvr
' LED's ausschalten
LedRot = 0
LedGruen = 0
LedGelb = 0
Do
Select Case AvrTyp
Case 0: ' AVR-Typ detektieren
LedRot = 1
LedGruen = 0
GoSub Find_T1
GoSub Find_T2
GoSub Find_T3
Case 1: ' ATTINY 2313
LedGruen = 1
LedRot = 0
GoSub Switch_T1
Case 2: ' ATMEGA 8 / ATMEGA 48 / ATMEGA 88 / ATMEGA 168
LedGruen = 1
LedRot = 0
GoSub Switch_T2
Case 3: ' ATMEGA 16 / ATMEGA 32 / ATMEGA 644
LedGruen = 1
LedRot = 0
GoSub Switch_T3
End Select
Loop
' Typ 1 schalten
Switch_T1:
GoSub DisConnectAvr
DDRB.7 = 1 : RES_T1 = 1 ' RESET = Output (High)
DDRB.5 = 1 : SCK_T1 = 0 ' SCK = Output (Low)
DDRB.3 = 1 : MOSI_T1 = 0 ' MOSI = Output (Low)
' Versorgungsspannung anlegen
GoSub PowerUpAvr
' Auf Programmierung warten
Do
If RES_PC = 0 Then Exit Do
If DeatTime >= TimeOut Then
DeatTime = 0
AvrTyp = 0
GoSub Find_T1
If AvrTyp <> 1 Then Return
Else
Incr DeatTime
End If
Loop
LedGelb = 1
Do
RES_T1 = RES_PC ' RESET PC => Ziel-AVR
SCK_T1 = SCK_PC ' SCK PC => Ziel-AVR
MOSI_T1 = MOSI_PC ' MOSI PC => Ziel-AVR
MISO_PC = MISO_T1 ' MISO PC <= Ziel-AVR
' Programmierende detektieren
If RES_PC = 0 Then DeatTime = TimeOut
Decr DeatTime
If DeatTime = 0 Then Exit Do
Loop
LedGelb = 0
' AVR aus Sockel entnehmen
Do
AvrTyp = 0
GoSub Find_T1
If AvrTyp <> 1 Then Exit Do
WaitMs 800
Loop
LedGruen = 0
Return
' Typ 2 schalten
Switch_T2:
GoSub DisConnectAvr
DDRD.2 = 1 : RES_T2 = 1 ' RESET = Output (High)
DDRB.2 = 1 : SCK_T2 = 0 ' SCK = Output (Low)
DDRD.5 = 1 : MOSI_T2 = 0 ' MOSI = Output (Low)
' Versorgungsspannung anlegen
GoSub PowerUpAvr
' Auf Programmierung warten
Do
If RES_PC = 0 Then Exit Do
If DeatTime >= TimeOut Then
DeatTime = 0
AvrTyp = 0
GoSub Find_T2
If AvrTyp <> 2 Then Return
Else
Incr DeatTime
End If
Loop
LedGelb = 1
Do
RES_T2 = RES_PC ' RESET PC => Ziel-AVR
SCK_T2 = SCK_PC ' SCK PC => Ziel-AVR
MOSI_T2 = MOSI_PC ' MOSI PC => Ziel-AVR
MISO_PC = MISO_T2 ' MISO PC <= Ziel-AVR
' Programmierende detektieren
If RES_PC = 0 Then DeatTime = TimeOut
Decr DeatTime
If DeatTime = 0 Then Exit Do
Loop
LedGelb = 0
' AVR aus Sockel entnehmen
Do
AvrTyp = 0
GoSub Find_T2
If AvrTyp <> 2 Then Exit Do
WaitMs 800
Loop
LedGruen = 0
Return
' Typ 3 schalten
Switch_T3:
GoSub DisConnectAvr
DDRB.7 = 1 : RES_T3 = 1 ' RESET = Output (High)
DDRB.6 = 1 : SCK_T3 = 0 ' SCK = Output (Low)
DDRD.3 = 1 : MOSI_T3 = 0 ' MOSI = Output (Low)
' Versorgungsspannung anlegen
GoSub PowerUpAvr
' Auf Programmierung warten
Do
If RES_PC = 0 Then Exit Do
If DeatTime >= TimeOut Then
DeatTime = 0
AvrTyp = 0
GoSub Find_T3
If AvrTyp <> 3 Then Return
Else
Incr DeatTime
End If
Loop
LedGelb = 1
Do
RES_T3 = RES_PC ' RESET PC => Ziel-AVR
SCK_T3 = SCK_PC ' SCK PC => Ziel-AVR
MOSI_T3 = MOSI_PC ' MOSI PC => Ziel-AVR
MISO_PC = MISO_T3 ' MISO PC <= Ziel-AVR
' Programmierende detektieren
If RES_PC = 0 Then DeatTime = TimeOut
Decr DeatTime
If DeatTime = 0 Then Exit Do
Loop
LedGelb = 0
' AVR aus Sockel entnehmen
Do
AvrTyp = 0
GoSub Find_T3
If AvrTyp <> 3 Then Exit Do
WaitMs 800
Loop
LedGruen = 0
Return
' Typ 1 - ATTINY 2313 ...
Find_T1:
If AvrTyp > 0 Then Return
AvrTyp = 1
GoSub DisConnectAvr
DDRB.7 = 1 : RES_T1 = 1 ' RESET = Output (High)
DDRB.5 = 1 : SCK_T1 = 0 ' SCK = Output (Low)
DDRB.3 = 1 : MOSI_T1 = 0 ' MOSI = Output (Low)
' Versorgungsspannung anlegen
GoSub PowerUpAvr
' >20 ms warten
WaitMs 25
RES_T1 = 0 ' RESET = Low
' >20 ms warten
WaitMs 25
' Prog. Enable anstoßen
For Retry = 1 To 5
AvrSend = PrgEnB1 : GoSub TalkAvr
AvrSend = PrgEnB2 : GoSub TalkAvr
AvrSend = PrgEnB3 : GoSub TalkAvr
Result = AvrEcho
AvrSend = PrgEnB4 : GoSub TalkAvr
If Result = PrgEnB2 Then Exit For
Next Retry
RES_T1 = 1 ' RESET = High
If Result = PrgEnB2 Then Return
AVRTyp = 0
GoSub DisconnectAvr
Return
' Typ 2 - ATMEGA8 ...
Find_T2:
If AvrTyp > 0 Then Return
AvrTyp = 2
GoSub DisConnectAvr
DDRD.2 = 1 : RES_T2 = 1 ' RESET = Output (High)
DDRB.2 = 1 : SCK_T2 = 0 ' SCK = Output (Low)
DDRD.5 = 1 : MOSI_T2 = 0 ' MOSI = Output (Low)
' Versorgungsspannung anlegen
GoSub PowerUpAvr
' >20 ms warten
WaitMs 25
RES_T2 = 0 ' RESET = Low
' >20 ms warten
WaitMs 25
' Prog. Enable anstoßen
For Retry = 1 To 5
AvrSend = PrgEnB1 : GoSub TalkAvr
AvrSend = PrgEnB2 : GoSub TalkAvr
AvrSend = PrgEnB3 : GoSub TalkAvr
Result = AvrEcho
AvrSend = PrgEnB4 : GoSub TalkAvr
If Result = PrgEnB2 Then Exit For
Next Retry
RES_T2 = 1 ' RESET = High
If Result = PrgEnB2 Then Return
AVRTyp = 0
GoSub DisconnectAvr
Return
' Typ 3 - ATMEGA16 ...
Find_T3:
If AvrTyp > 0 Then Return
AvrTyp = 3
GoSub DisConnectAvr
DDRB.7 = 1 : RES_T3 = 1 ' RESET = Output (High)
DDRB.6 = 1 : SCK_T3 = 0 ' SCK = Output (Low)
DDRD.3 = 1 : MOSI_T3 = 0 ' MOSI = Output (Low)
' Versorgungsspannung anlegen
GoSub PowerUpAvr
' >20 ms warten
WaitMs 25
RES_T3 = 0 ' RESET = Low
' >20 ms warten
WaitMs 25
' Prog. Enable anstoßen
For Retry = 1 To 5
AvrSend = PrgEnB1 : GoSub TalkAvr
AvrSend = PrgEnB2 : GoSub TalkAvr
AvrSend = PrgEnB3 : GoSub TalkAvr
Result = AvrEcho
AvrSend = PrgEnB4 : GoSub TalkAvr
If Result = PrgEnB2 Then Exit For
Next Retry
RES_T3 = 1 ' RESET = High
If Result = PrgEnB2 Then Return
AVRTyp = 0
GoSub DisconnectAvr
Return
' SPI-Kommunikation mit AVR
TalkAvr:
For BitNr = 7 To 0 Step -1
Select Case AvrTyp
Case 1:
MOSI_T1 = AvrSend.BitNr
SCK_T1 = 1
WaitUs 11
AvrEcho.BitNr = MISO_T1
SCK_T1 = 0
Case 2:
MOSI_T2 = AvrSend.BitNr
SCK_T2 = 1
WaitUs 11
AvrEcho.BitNr = MISO_T2
SCK_T2 = 0
Case 3:
MOSI_T3 = AvrSend.BitNr
SCK_T3 = 1
WaitUs 11
AvrEcho.BitNr = MISO_T3
SCK_T3 = 0
End Select
WaitUs 11
Next BitNr
Return
' AVR mit Spannung versorgen
PowerUpAvr:
Select Case AvrTyp
Case 1:
SupplyT1A = 1 ' Supply T1 GND aktiv
SupplyT1B = 0 ' Supply T1 VCC aktiv
Case 2:
SupplyT23 = 1 ' Supply M8/M16 GND/VCC aktiv
Case 3:
SupplyT23 = 1 ' Supply M8/M16 GND/VCC aktiv
End Select
Return
' AVR trennen
DisConnectAvr:
' Supply deaktivieren
DDRD.0 = 1 : PortD.0 = 0 ' Supply M8/M16 inaktiv
DDRC.0 = 1 : PortC.0 = 1 ' Supply 2313 VCC inaktiv
DDRD.1 = 1 : PortD.1 = 0 ' Supply 2313 GND inaktiv
' Signale zum Ziel-AVR deaktivieren (Input)
DDRB.7 = 0 : PortB.7 = 0 ' RESET Typ 1 - 3
DDRD.2 = 0 : PortD.2 = 0 ' RESET Typ - 2 -
DDRB.5 = 0 : PortB.5 = 0 ' SCK Typ 1 - -
DDRB.2 = 0 : PortB.2 = 0 ' SCK Typ - 2 -
DDRB.6 = 0 : PortB.6 = 0 ' SCK Typ - - 3
DDRB.3 = 0 : PortB.3 = 0 ' MOSI Typ 1 - -
DDRD.5 = 0 : PortD.5 = 0 ' MOSI Typ - 2 -
DDRD.3 = 0 : PortD.3 = 0 ' MOSI Typ - - 3
DDRB.4 = 0 : PortB.4 = 0 ' MISO Typ 1 - -
DDRB.1 = 0 : PortB.1 = 0 ' MISO Typ - 2 -
DDRD.4 = 0 : PortD.4 = 0 ' MISO Typ - - 3
Return
@windi, die Unterstützung für 8-Füßler habe ich nicht realisiert. Denke wenn man sowas wirklich brauchen sollte, dann kann man das wohl recht flott auf eine Lochraster aufbauen. Das Layout solte ja selbst ätzbar und einseitig ausfallen. Aber wenn du es schaffen solltest das in das Layout zu implementieren, gerne her damit
Sollte man aber mit einem 20-poligen Adaptersockel basteln können wenn es da dringend drauf soll. Muß eben VCC/GND/MIOS/MOSI/SCK und RESET verbinden auf einen ATINY2313.
Grüße Wolfgang
Lesezeichen