Forum: Mikrocontroller und Digitale Elektronik doppelte variablenwerte im sector


von bastler (Gast)


Lesenswert?

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

von Ralph (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.