@Hubert.G, gieng mir eben darum, wenn ichs hier verstauben lass und versteck bringts keinem was, so kanns halt jeder nutzen der es brauchen kann. Hab erst noch ein "Bugfix" gemacht. Hatte ja Probleme mit EEPROM-Lesen. Die jetzt lauffähige Version ist hier als Code. Den alten nicht nehmen, der ist fehlerbehaftet. Habs mit MEGA8, 16, 32 und Tiny2313 getestet reihum kreuz und quer und geht nun sauber alles (Fusen, EEPROM, Programm).
Code:
' AVR-Weiche für AVR-Programmiergerät
$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 = &H0
Const PrgEnB4 = &H0
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 Boolean
Init:
' Allgemeine Signale von/zum PC
DDRD 0.7 = 0: PortD 0.7 = 0 ' RESET von PC (Pull-Up aktiv)
DDRB 0# = 0: PortB 0# = 0 ' SCK von PC (Pull-Up aktiv)
DDRD 0.6 = 0: PortD 0.6 = 0 ' MOSI von PC (Pull-Up aktiv)
DDRC 0.5 = 1: PortC 0.5 = 0 ' MISO an PC
' LED-Anzeige
DDRC 0.4 = 1
DDRC 0.3 = 1
DDRC 0.2 = 1
' Deat-Time Überwachung parametrieren
On Timer1 IntTimer1
Config Timer1 = Timer, Prescale = 256
Start Timer1
Enable Interrupts
Enable Timer1
' 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
' Timer 1 Overflow-Interrupt ausgelöst
IntTimer1:
DeatTime = 1
Return
' Typ 1 schalten
Switch_T1:
GoSub DisConnectAvr
DDRB 0.7 = 1: RES_T1 = 1 ' RESET = Output (High)
DDRB 0.5 = 1: SCK_T1 = 0 ' SCK = Output (Low)
DDRB 0.3 = 1: MOSI_T1 = 0 ' MOSI = Output (Low)
' Versorgungsspannung anlegen
GoSub PowerUpAvr
Timer1 = 0
DeatTime = 0
Do
' Idle-State
Do
If DeatTime = 1 Then
Timer1 = 0
DeatTime = 0
AvrTyp = 0
GoSub Find_T1
If AvrTyp <> 1 Then Return
End If
' Daten patchen
RES_T1 = 1
If RES_PC = 0 Then Exit Do
If SCK_PC = 1 Then Exit Do
Loop
' Busy-State
LedGelb = 1
DeatTime = 0
Timer1 = 0
Do
' Daten patchen
RES_T1 = RES_PC
SCK_T1 = SCK_PC
MOSI_T1 = MOSI_PC
MISO_PC = MISO_T1
If SCK_PC = 1 Then Timer1 = 0
Loop Until DeatTime = 1
LedGelb = 0
Loop
Return
' Typ 2 schalten
Switch_T2:
GoSub DisConnectAvr
DDRD 0.2 = 1: RES_T2 = 1 ' RESET = Output (High)
DDRB 0.2 = 1: SCK_T2 = 0 ' SCK = Output (Low)
DDRD 0.5 = 1: MOSI_T2 = 0 ' MOSI = Output (Low)
' Versorgungsspannung anlegen
GoSub PowerUpAvr
Timer1 = 0
DeatTime = 0
Do
' Idle-State
Do
If DeatTime = 1 Then
Timer1 = 0
DeatTime = 0
AvrTyp = 0
GoSub Find_T2
If AvrTyp <> 2 Then Return
End If
' Daten patchen
RES_T2 = 1
If RES_PC = 0 Then Exit Do
If SCK_PC = 1 Then Exit Do
Loop
' Busy-State
LedGelb = 1
DeatTime = 0
Timer1 = 0
Do
' Daten patchen
RES_T2 = RES_PC
SCK_T2 = SCK_PC
MOSI_T2 = MOSI_PC
MISO_PC = MISO_T2
If SCK_PC = 1 Then Timer1 = 0
Loop Until DeatTime = 1
LedGelb = 0
Loop
Return
' Typ 3 schalten
Switch_T3:
GoSub DisConnectAvr
DDRB 0.7 = 1: RES_T3 = 1 ' RESET = Output (High)
DDRB 0.6 = 1: SCK_T3 = 0 ' SCK = Output (Low)
DDRD 0.3 = 1: MOSI_T3 = 0 ' MOSI = Output (Low)
' Versorgungsspannung anlegen
GoSub PowerUpAvr
Timer1 = 0
DeatTime = 0
Do
' Idle-State
Do
If DeatTime = 1 Then
Timer1 = 0
DeatTime = 0
AvrTyp = 0
GoSub Find_T3
If AvrTyp <> 1 Then Return
End If
' Daten patchen
RES_T3 = 1
If RES_PC = 0 Then Exit Do
If SCK_PC = 1 Then Exit Do
Loop
' Busy-State
LedGelb = 1
DeatTime = 0
Timer1 = 0
Do
' Daten patchen
RES_T3 = RES_PC
SCK_T3 = SCK_PC
MOSI_T3 = MOSI_PC
MISO_PC = MISO_T3
If SCK_PC = 1 Then Timer1 = 0
Loop Until DeatTime = 1
LedGelb = 0
Loop
Return
' Typ 1 - ATTINY 2313 ...
Find_T1:
If AvrTyp > 0 Then Return
AvrTyp = 1
GoSub DisConnectAvr
DDRB 0.7 = 1: RES_T1 = 1 ' RESET = Output (High)
DDRB 0.5 = 1: SCK_T1 = 0 ' SCK = Output (Low)
DDRB 0.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 0.2 = 1: RES_T2 = 1 ' RESET = Output (High)
DDRB 0.2 = 1: SCK_T2 = 0 ' SCK = Output (Low)
DDRD 0.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 0.7 = 1: RES_T3 = 1 ' RESET = Output (High)
DDRB 0.6 = 1: SCK_T3 = 0 ' SCK = Output (Low)
DDRD 0.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 0.1 = 1: PortD 0.1 = 0 ' Supply 2313 GND inaktiv
' Signale zum Ziel-AVR deaktivieren (Input)
DDRB 0.7 = 0: PortB 0.7 = 0 ' RESET Typ 1 - 3
DDRD 0.2 = 0: PortD 0.2 = 0 ' RESET Typ - 2 -
DDRB 0.5 = 0: PortB 0.5 = 0 ' SCK Typ 1 - -
DDRB 0.2 = 0: PortB 0.2 = 0 ' SCK Typ - 2 -
DDRB 0.6 = 0: PortB 0.6 = 0 ' SCK Typ - - 3
DDRB 0.3 = 0: PortB 0.3 = 0 ' MOSI Typ 1 - -
DDRD 0.5 = 0: PortD 0.5 = 0 ' MOSI Typ - 2 -
DDRD 0.3 = 0: PortD 0.3 = 0 ' MOSI Typ - - 3
DDRB 0.4 = 0: PortB 0.4 = 0 ' MISO Typ 1 - -
DDRB 0.1 = 0: PortB 0.1 = 0 ' MISO Typ - 2 -
DDRD 0.4 = 0: PortD 0.4 = 0 ' MISO Typ - - 3
Return
Ansonsten ist hier alles weitere als HTML-Version: http://wiesolator.de/data/topics/%b5...ger/inhalt.htm
Grüße Wolfgang
Lesezeichen