hallo, ich habe hier ein leichtverständliches programm um eine mmc-karte
zu betreiben in fastavr. die übertragungsroutinen (shiftin und shiftout
habe ich als asmcode von fastavr nach dem compilieren genommen zur
besseren übersicht).
die zahlen in den sectoren haben immer den doppelten wert , als den
vorgegebenen. wennn ich 65 reinschreibe steht dort 130 bei 40 steht 80
usw.
vielleicht kann ein progger mal weiterhelfen, vielleicht stimmen die
asm-routinen nicht.
ansonsten funktioniert der code mit der mmc-karte.
ich fülle ein buffer wie vorgegeben.
speichere die daten.
leere den buffer.
hole die daten wieder zur kontrolle.
gebe sie zur kontrolle aus.
das timing für die mmc habe ich hier aus dem forum (timing-bild mit
daten).
das programm:
$Device = M32
$Stack = 32
$Clock = 8
$Baud = 19200
Declare Sub Mmc_init()
Declare Sub Mmc_write()
Declare Sub Mmc_read()
Declare Sub shift_o()
Declare Sub shift_i()
Dim Dout As Byte
Dim Din As Byte
Dim A As Word
Dim Cmd(6) As Byte
Dim Buffer(515) As Byte
Dim Tmp As Long
Dim Sector As Long
Dim test As Byte
$Def Mcs =PORTB.0
$Def Mclk =PORTB.3
$Def Mosi =PORTB.1
DDRB.0=1
DDRB.1=1
DDRB.2=0
DDRB.3=1
Enable Interrupts
WaitMs 255
test=0
Buffer(0) = 254
Buffer(513) =255
Buffer(514) =255
For A = 1 To 512
Buffer(a) = 65
Next
Mmc_init()
Sector = 0
WaitMs 100
Mmc_write()
For A = 0 To 514
Buffer(a) = 0
Next
Mmc_init()
Sector = 0
WaitMs 100
Mmc_read()
Print "speicherzelle 0-10"
For A = 0 To 10
Print "wert: " ; Buffer(a)
WaitMs 50
Next
End
Sub shift_i()
$Asm
ldi r24,0x08
_Si2: clc
sbi PORTB,3
sbic PINB,2
sec
rol zl
cbi PORTB,3
dec r24
brne _Si2
sts din,zl
$EndAsm
End Sub
Sub shift_o()
$Asm
lds zl,dout
ldi r24,0x08
_So22: rol zl
brcc _So11
sbi PORTB,1
rjmp _So33
_So11: cbi PORTB,1
_So33: sbi PORTB,3
dec r24
cbi PORTB,3
brne _So22
cbi PORTB,1
$EndAsm
End Sub
Sub Mmc_init()
For A = 0 To 80
Set mclk
WaitUs 1
Reset mclk
Next
Reset Mcs
Anfang:
Cmd(0) = &H40
Cmd(1) = 0
Cmd(2) = 0
Cmd(3) = 0
Cmd(4) = 0
Cmd(5) = &H95
For A = 0 To 5
dout=cmd(a)
Shift_o()
Next
Dout = &HFF
Shift_o()
Shift_i()
If Din <> 1 Then
GoTo Anfang
End If
Set mcs
Print "idle-modus ";din
Dout = &HFF
Shift_o()
Reset mcs
Anfang1:
Cmd(0) = &H41
Cmd(1) = 0
Cmd(2) = 0
Cmd(3) = 0
Cmd(4) = 0
Cmd(5) = 0
For A = 0 To 5
dout=Cmd(a)
shift_o()
Next
Dout = &HFF
Shift_o()
Shift_i()
If Din <> 0 Then
GoTo Anfang1
End If
Set Mcs
Print "betriebs-modus ";din
End Sub
Sub Mmc_write()
Reset Mcs
cmd(0)=&h58
cmd(1)=0
cmd(2)=0
cmd(3)=0
cmd(4)=0
cmd(5)=0
Sector= Shift(Left,9,Sector)
tmp=Sector & &hff000000
tmp=Shift(Right,24,tmp)
cmd(1)=tmp
tmp=Sector & &h00ff0000
tmp=Shift(Right,16,tmp)
cmd(2)=tmp
tmp=Sector & &h0000ff00
tmp=Shift(Right,8,tmp)
cmd(3)=tmp
Anfang2:
For A = 0 To 5
dout=Cmd(a)
shift_o()
Next
Dout = &HFF
Shift_o()
Shift_i()
If Din <> 0 Then
GoTo Anfang2
End If
Print "write-modus ";din
Dout = &HFF
Shift_o()
For A = 0 To 514
Dout = Buffer(a)
Shift_o()
Next
Dout = &HFF
Shift_o()
Reset mosi
Dout = &HFF
Shift_o()
Set mosi
Set Mcs
End Sub
Sub mmc_read()
Reset Mcs
cmd(0)=&h51
cmd(1)=0
cmd(2)=0
cmd(3)=0
cmd(4)=0
cmd(5)=0
Sector= Shift(Left,9,Sector)
tmp=Sector & &hff000000
tmp=Shift(Right,24,tmp)
cmd(1)=tmp
tmp=Sector & &h00ff0000
tmp=Shift(Right,16,tmp)
cmd(2)=tmp
tmp=Sector & &h0000ff00
tmp=Shift(Right,8,tmp)
cmd(3)=tmp
Anfang3:
For A = 0 To 5
dout=Cmd(a)
shift_o()
Next
Dout = &HFF
Shift_o()
Shift_i()
If Din <> 0 Then
GoTo Anfang3
End If
Print "read-modus ";din
Dout = &HFF
Shift_o()
wiederhole:
test=test+1
Shift_i()
If Din <> &hfe Then
If test < 15 Then
GoTo wiederhole
Else
GoTo ende
End If
End If
Buffer(0)=din
For A = 1 To 514
Shift_i()
Buffer(a)=din
Next
ende:
test=0
Set Mcs
End Sub
Das sieht sehr danach aus, als ob du das Byte um eine stelle nach links schiebst. Das ist eine multiplikation mit 2. Du solltest also alle shiftoperatioenen mal genau überprüfen.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.