PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : geschafft : mmc-karte zu fuss mit bascom proggen...hurra



roboterheld
10.11.2007, 20:01
es ist geschafft. die mmc-karte kann ich jetzt zu fuss proggen mit bascom, nur über "shiftout-befehl" und "shiftin-befehl" sectoren beschreiben.
das auslesen geht genauso einfach. kann jeder selbst ergänzen.

bei mir laufen damit 4 verschiedene mmc/sd-karten.

hier der code :


$regfile = "m32def.dat"
$framesize = 32
$swstack = 32
$hwstack = 64
$crystal = 8000000
$baud = 19200


Declare Sub Mc_init()
Declare Sub Mc_write()

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

Mcs Alias Portb.0
Mosi Alias Portb.1
Miso Alias Pinb.2
Sck Alias Portb.3

Config Pinb.0 = Output
Config Pinb.1 = Output
Config Pinb.2 = Input
Config Pinb.3 = Output


Waitms 255
Sector = 0

Buffer(1) = &HFE
Buffer(514) = &HFF
Buffer(515) = &HFF

For A = 2 To 513
Buffer(a) = 71
Next

Call Mc_init()
Call Mc_write()

End


Sub Mc_init()

Set Mcs

Dout = &HFF
For A = 0 To 10
Shiftout Mosi , Sck , Dout , 1 , 8 , 16
Next

Anfang:
Reset Mcs

Cmd(1) = &H40
Cmd(2) = 0
Cmd(3) = 0
Cmd(4) = 0
Cmd(5) = 0
Cmd(6) = &H95
For A = 1 To 6
Shiftout Mosi , Sck , Cmd(a) , 1 , 8 , 16
Next

For A = 1 To 8
Reset Sck
Waitus 10
Set Sck
Waitus 10
Next
:
Shiftin Miso , Sck , Din , 1 , 8 , 16
If Din <> 1 Then
Goto Anfang
End If
Print Din

Anfang1:
Reset Mcs

Cmd(1) = &H41
Cmd(2) = 0
Cmd(3) = 0
Cmd(4) = 0
Cmd(5) = 0
Cmd(6) = &HFF
For A = 1 To 6
Shiftout Mosi , Sck , Cmd(a) , 1 , 8 , 16
Next

For A = 1 To 8
Reset Sck
Waitus 10
Set Sck
Waitus 10
Next

Shiftin Miso , Sck , Din , 1 , 8 , 16
If Din <> 0 Then
Goto Anfang1
End If
Print Din

Set Mcs

End Sub

Sub Mc_write()

Set Mcs

Cmd(1) = &H58
Cmd(2) = 0
Cmd(3) = 0
Cmd(4) = 0
Cmd(5) = 0
Cmd(6) = &HFF

Shift Sector , Left , 9

Tmp = Sector And &HFF000000
Shift Tmp , Right , 24
Cmd(2) = Tmp

Tmp = Sector And &H00FF0000
Shift Tmp , Right , 16
Cmd(3) = Tmp

Tmp = Sector And &H0000FF00
Shift Tmp , Right , 8
Cmd(4) = Tmp

Anfang2:
Reset Mcs

For A = 1 To 6
Shiftout Mosi , Sck , Cmd(a) , 1 , 8 , 16
Next

For A = 1 To 8
Reset Sck
Waitus 10
Set Sck
Waitus 10
Next

Shiftin Miso , Sck , Din , 1 , 8 , 16
If Din <> 0 Then
Goto Anfang2
End If
Print Din

For A = 1 To 8
Reset Sck
Waitus 10
Set Sck
Waitus 10
Next

For A = 1 To 515
Dout = Buffer(a)
Shiftout Mosi , Sck , Dout , 1 , 8 , 16
Waitus 10
Next

Waitus 10
Shiftin Miso , Sck , Din , 1 , 8 , 16
Print Din

For A = 1 To 8
Reset Sck
Waitus 10
Set Sck
Waitus 10
Next

Set Mcs

End Sub

Rofo88
10.11.2007, 20:37
Schön , ein paar Kommentare im Quellcode würden dem Anfänger sicher hilfreich sein.

=D>

Stromi
10.11.2007, 21:44
Ja, ein bisschen Erklärung, brauche ich auch. Übrigens, selbst wenn ich was programmiere, schreibe ich mir REM's, denn in 3 Tagen weiß ich nicht mehr warum ich Das oder Dieses gemacht habe....
Soll heißen: ist keine Kritik !!!
Warum macht man das immer einmal so zwischendurch #-o :
For A = 1 To 8
Reset Sck
Waitus 10
Set Sck
Waitus 10
Next
Als "Füller" ?

roboterheld
10.11.2007, 21:54
man muss das diagramm kennen. einige im forum haben es ohne diagramm gemacht und es haut nicht hin. hier ist die superbeschreibung für eine mmc-karte , viel spass, ist einfach zu lesen. danach habe ich mein programm geschrieben :

http://elm-chan.org/docs/mmc/mmc_e.html




a, ein bisschen Erklärung, brauche ich auch. Übrigens, selbst wenn ich was programmiere, schreibe ich mir REM's, denn in 3 Tagen weiß ich nicht mehr warum ich Das oder Dieses gemacht habe....


ich habe ein hundertjähriges gedächtnis für programme.

Stromi
10.11.2007, 22:01
aha O:) ,
deswegen der Name, ich bin froh mich Morgens im Spiegel zu erkennen....

Pyro-Mike
10.11.2007, 22:05
ich habe ein hundertjähriges gedächtnis für programme.

Wir haben aber leider keine Glaskugel ^^ (soll keine Kritik sein) http://www.greensmilies.com/smile/smiley_emoticons_glaskugel3.gif

roboterheld
10.11.2007, 22:13
danach kann man mein programm auch gut verfolgen. warum...wo...wie lange...was...hin gehört. auch die codebefehle stehen dabei.


http://www.ulrichradig.de/site/atmel/avr_mmcsd/pdf/MMCSDTimming.pdf

Stromi
10.11.2007, 22:17
Vielen Dank "Hero", auch der erste Link, für Deutschleser wie mich, mit Google übersetzt, ist schon gut lesbar.

roboterheld
11.11.2007, 09:03
hier für die tüftler die mc_read-routine(512byte):



Sub Mc_read()
Set Mcs

Cmd(1) = &H51
Cmd(2) = 0
Cmd(3) = 0
Cmd(4) = 0
Cmd(5) = 0
Cmd(6) = &HFF

Shift Sector , Left , 9

Tmp = Sector And &HFF000000
Shift Tmp , Right , 24
Cmd(2) = Tmp

Tmp = Sector And &H00FF0000
Shift Tmp , Right , 16
Cmd(3) = Tmp

Tmp = Sector And &H0000FF00
Shift Tmp , Right , 8
Cmd(4) = Tmp

Anfang3:
Reset Mcs

For A = 1 To 6
Shiftout Mosi , Sck , Cmd(a) , 1 , 8 , 16
Next

For A = 1 To 8
Reset Sck
Waitus 10
Set Sck
Waitus 10
Next

Shiftin Miso , Sck , Din , 1 , 8 , 16
If Din <> 0 Then
Goto Anfang3
End If
Print Din

For A = 1 To 16
Reset Sck
Waitus 10
Set Sck
Waitus 10
Next

Shiftin Miso , Sck , Din , 1 , 8 , 16
If Din <> &HFE Then
Goto Ende
End If

For A = 2 To 515
Shiftin Miso , Sck , Din , 1 , 8 , 16
Buffer(a) = Din
Next

Ende:
Waitms 5

Set Mcs

End Sub

robobaer
11.11.2007, 11:22
Hallo, was spricht denn gegen die Verwendung von SPI anstatt von shiftout. Das vereinfacht das ganz doch ganz erheblich. Und wenn man dann noch die fertigen Routinen von BASCOM nutzt wirds noch einfacher.
Ich hänge mal meine Version der MMC-Routinen an die ich vor zwei Jahren geschrieben habe. Im zweiten Block mal die neue Version mit BASCOM-Bordmitteln.
Vielleicht hilfts dem ein oder anderem.

mfg.
Joachim



' ################################################## ############################
' Connect Avr To MMC/SD with BASCOM
'
' Copyright(c) 2005 Joachim Reiter
' based on code from Ulrich Radig
'
'
' Dieses Programm Ist Freie Software. Sie K�nnen Es Unter Den Bedingungen Der
' Gnu General Public License , Wie Von Der Free Software Foundation Ver�ffentlicht,
' Weitergeben Und / Oder Modifizieren , Entweder Gem�� Version 2 Der Lizenz Oder
' (nach Ihrer Option) Jeder Sp�teren Version.

' Die Ver�ffentlichung Dieses Programms Erfolgt In Der Hoffnung,
' Da� Es Ihnen Von Nutzen Sein Wird , Aber Ohne Irgendeine Garantie,
' Sogar Ohne Die Implizite Garantie Der Marktreife Oder Der Verwendbarkeit
' F�r Einen Bestimmten Zweck. Details Finden Sie In Der Gnu General Public License.
'
' Sie Sollten Eine Kopie Der Gnu General Public License Zusammen Mit Diesem
' Programm Erhalten Haben.
' Falls Nicht , Schreiben Sie An Die Free Software Foundation,
' Inc. , 59 Temple Place , Suite 330 , Boston , Ma 02111 -1307 , Usa.
' ################################################## ############################
$regfile = "m32def.dat"
$crystal = 8000000
$baud = 19200

Const Attr_long_name = &H0F
Const Attr_read_only = &H01
Const Attr_hidden = &H02
Const Attr_system = &H04
Const Attr_volume_id = &H08
Const Attr_directory = &H10
Const Attr_archive = &H20

Config Portb = &B10110000
Mmc_miso Alias Portb.6
Mmc_mosi Alias Portb.5
Mmc_cs Alias Portb.4
Mmc_sck Alias Portb.7
Set Mmc_cs
Spsr = 0

Dim Direntry(32) As Byte
Dim Dir_name(8) As Byte At Direntry Overlay ' 8 chars filename
Dim Dir_ext(3) As Byte At Direntry+&H08 Overlay ' 8 chars filename
Dim Dir_attr As Byte At Direntry+$0b Overlay ' file attributes RSHA, Longname, Drive Label, Directory
Dim Dir_dummy(10) As Byte At Direntry+$0c Overlay
Dim Dir_time As Word At Direntry+$16 Overlay ' creation time part in milliseconds
Dim Dir_date As Word At Direntry+$18 Overlay ' creation time
Dim Dir_cluster As Word At Direntry+$1a Overlay ' first cluster high word
Dim Dir_filesize As Long At Direntry+$1c Overlay
Dim Fat_adresse As Long
Dim Dir_adresse As Long
Dim Data_adresse As Long

Dim Buffer(512) As Byte
Dim Vbr_start As Long At Buffer+&H1C6 Overlay
Dim Bytespersektor As Word At Buffer+&H0B Overlay
Dim Sektorpercluster As Byte At Buffer+&H0D Overlay
Dim Reservedsektor As Byte At Buffer+&H0E Overlay
Dim Maxrootentry As Word At Buffer+&H11 Overlay
Dim Sektorprofat As Word At Buffer+&H16 Overlay


Dim Cmd(6) As Byte
Dim Count As Integer
Dim Count1 As Integer
Dim Timeout As Byte
Dim Timeout1 As Byte
Dim Tmp As Byte
Dim Anz_bytes As Word
Dim Fn_ergo As Byte
Dim Addr As Long
'Dim Tmpaddr As Long
Dim Databyte As Byte
Dim File_cluster As Word

Declare Sub Mmc_write_byte(databyte As Byte)
Declare Function Mmc_read_byte() As Byte
Declare Function Mmc_init() As Byte
Declare Function Mmc_write_command(cmd() As Byte) As Byte
Declare Function Mmc_write_sector(addr As Long) As Byte
Declare Sub Mmc_read_block(cmd() As Byte , Anz_bytes As Word)
Declare Sub Mmc_read_sector(byval Addr As Long)
Declare Sub Mmc_read_csd()
Declare Sub Mmc_read_cid()

Declare Sub Scandisk()
Declare Function Readfile(byval Cluster As Word) As Word
Declare Sub Readdir(byval Nr As Word)
Declare Sub Outbuffer()


Main:
Print "Press any Key"
Do
Loop Until Inkey() <> 0

Fn_ergo = Mmc_init()
If Fn_ergo <> 0 Then
Print "Keine Karte gefunden " ; Fn_ergo
Goto Main
End If

Print "Karte gefunden"

Call Scandisk
Print "DIR :" ; Dir_adresse
Print "FAT :" ; Fat_adresse

Print "DATA:" ; Data_adresse


Call Mmc_read_sector(dir_adresse )
Call Outbuffer()

For Count = 1 To 32
Direntry(count) = Buffer(32 + Count)
Next X
For Count = 1 To 8
Print Chr(dir_name(count));
Next Count

Print ".";
For Count = 1 To 3
Print Chr(dir_ext(count));
Next Count
Print " " ; Dir_filesize ; " " ; Dir_cluster
File_cluster = Readfile(dir_cluster)
Print "xxxxx:" ; File_cluster
Call Outbuffer()

Goto Main

Sub Outbuffer()
Local Otmp As Word
Local Otmp1 As Byte
Local Ocount As Byte
Local Ocount1 As Byte

For Ocount = 0 To 31
Otmp = Ocount * 16
Print Hex(otmp) ; " ";
For Ocount1 = 1 To 16
Incr Otmp
Print Hex(buffer(otmp)) ; " ";
Next Ocount1
Otmp = Ocount * 16
For Ocount1 = 1 To 16
Incr Otmp
Otmp1 = Buffer(otmp)
If Otmp1 < 32 Then Otmp1 = 46
Print Chr(otmp1);
Next Ocount1
Print
Next Ocount
Print
End Sub

Goto Main

Call Mmc_read_csd()
For Count = 1 To 16
Print Hex(buffer(count)) ; " ";
Next X
Print

Input "Blocknummer " , Addr

Goto Main
End

' Lese Directoryeintrag
Sub Readdir(byval Nr As Word)
Local X As Byte
Local Y As Byte
Local Rcount As Byte
Local Rtmp As Word

Call Mmc_read_sector(dir_adresse)
For X = 1 To 15
Rtmp = X * 32
' Leereintrag, das wars dann
If Buffer(rtmp + 1) = 0 Then Exit For
' Gel�schter Eintrag
If Buffer(rtmp + 1) <> &HE5 Then
For Count = 1 To 32
Incr Rtmp
Direntry(count) = Buffer(rtmp)
Next Count
For Count = 1 To 8
Print Chr(dir_name(count));
Next Count

Print ".";
For Count = 1 To 3
Print Chr(dir_ext(count));
Next Count
Print " " ; Dir_filesize
End If

Next X

End Sub



' liest Cluster von File aus und gibt n�chsten Cluster zur�ck
' FFFF als R�ckgabe = Ende des Files
Function Readfile(byval Cluster As Word) As Word

Local Nextcluster As Word
Local Fatblock As Long
Local Fatadresse As Long
Local Tcl As Long

Print "bbbbbb"
Fatblock=Cluster*2
Fatadresse = Fatblock Mod Bytespersektor
Fatblock = Fatblock / Bytespersektor
Fatblock = Fatblock + Fatadresse
Call Mmc_read_sector(fatblock)

Print "ccccc" ; Fatblock ; " " ; Fatadresse
NextCluster=Buffer(Fatadresse)*256
NextCluster=Nextcluster+Buffer(Fatadresse+1)

Call Mmc_read_sector(tcl)
' Offset wegen Dateianfang
Cluster = Cluster - 2
Cluster = Cluster * Sektorpercluster
' und zu Anfang dazumachen
Cluster = Cluster + Data_adresse
' und auslesen
Tcl = Cluster
Print "aaa:" ; Tcl ; " " ; Nextcluster
Call Mmc_read_sector(tcl)
Print "vvvvv"
' Naechsten Cluster zurueckgeben
ReadFile=NextCluster
End Function


Sub Scandisk()
Local Ltmp As Long

Ltmp = 0
' Aus Sektor 0 an H1C6 Long auslesen = Volume-Boot Record
Call Mmc_read_sector(ltmp )
' VBR lesen
Ltmp = Vbr_start
Call Mmc_read_sector(ltmp )

Dir_adresse = 2 * Sektorprofat
Dir_adresse = Dir_adresse + Ltmp
Dir_adresse = Dir_adresse + Reservedsektor
Fat_adresse = Ltmp + 1
Data_adresse = Maxrootentry * 32
Data_adresse = Data_adresse / Bytespersektor
Data_adresse = Data_adresse + Dir_adresse

End Sub



Sub Mmc_write_byte(databyte As Byte)
Spdr = Databyte
Bitwait Spsr.spif , Set
End Sub


Function Mmc_read_byte() As Byte
Spdr = &HFF
Bitwait Spsr.spif , Set
Mmc_read_byte = Spdr
End Function


' ################################################## ##########################
' ###### Routine zur Initialisierung der MMC /SD - Karte (spi -mode)
' ################################################## ##########################
Function Mmc_init() As Byte

Config Portb = &B10110000
Set Mmc_cs
Spsr = 0
Set Spcr.spe
Set Spcr.mstr
Set Spcr.spr0 ' CLK/128
Set Spcr.spr1

Set Mmc_cs ' disable card

' Initialisiere MMC / SD - Karte in den SPI-Mode
Databyte = &HFF
For Count = 1 To 16 ' Sendet Min 74+ Clocks an die MMC/SD-Karte
Call Mmc_write_byte(databyte)
Next Count

' Sendet Kommando Cmd0 an MMC/SD-Kkarte
Cmd(1) = &H40
Cmd(2) = &H00
Cmd(3) = &H00
Cmd(4) = &H00
Cmd(5) = &H00
Cmd(6) = &H95
Timeout = 0
Do
Fn_ergo = Mmc_write_command(cmd(1))
Incr Timeout
If Timeout > 200 Then
Mmc_init = 1 ' Abbruch Bei Commando1
Exit Function
End If
Loop Until Fn_ergo = 1

Cmd(1) = &H41
Cmd(2) = &HFF
Timeout = 0
Do
Fn_ergo = Mmc_write_command(cmd(1))
Incr Timeout
If Timeout > 200 Then
Mmc_init = 2 ' Abbruch Bei Commando 2
Exit Function
End If
Loop Until Fn_ergo = 0

' SPI Bus auf maximale Ggeschwindigkeit
Reset Spcr.spr0
Reset Spcr.spr1
Set Spsr.spi2x

Set Mmc_cs ' Set Mmc_chip_select To High(mmc / Sd -karte Inaktiv)
Mmc_init = 0
End Function


' ################################################## ##########################
' ###### Sendet ein Commando an die MMC/SD-Karte
' ################################################## ##########################
Function Mmc_write_command(cmd() As Byte) As Byte

Local Ldatabyte As Byte
Ldatabyte = &HFF
Local Ltimeout As Byte
Ltimeout = 0


' Set Mmc_chip_select to high(MMC/SD-Karte Inaktiv)
Set Mmc_cs

' Sendet 8 Clock Impulse
Call Mmc_write_byte(ldatabyte)

' Set Mmc_chip_select to low(MMC/SD-Karte Aktiv)
Reset Mmc_cs

' Sendet 6 Byte Commando
For Count = 1 To 6
Call Mmc_write_byte(cmd(count))
Next Count

Ldatabyte = &HFF
' Wartet Auf Ein G�ltige Antwort Von Der Mmc / Sd -karte
While Ldatabyte = &HFF
Ldatabyte = Mmc_read_byte()
Incr Ltimeout
If Ltimeout > 100 Then Exit While
Wend

Mmc_write_command = Ldatabyte
End Function


' ################################################## ##########################
' ###### Routine Zum Schreiben Eines Blocks(512byte) Auf Die Mmc / Sd -karte
' ################################################## ##########################
Function Mmc_write_sector(addr As Long) As Byte

Local Tmpaddr As Long
' Sende Kommando Cmd24 zum Schreiben an MMC/SD-Kkarte
Cmd(1) = &H58
Cmd(2) = &H00
Cmd(3) = &H00
Cmd(4) = &H00
Cmd(5) = &H00
Cmd(6) = &HFF

' Die Adressierung Der Mmc / Sd -karte Wird In Bytes Angegeben,
' Addr Wird Von Blocks Zu Bytes Umgerechnet Danach Werden
' Diese In Das Commando Eingef�gt * /
Shift Addr , Left , 9 ' Addr = Addr * 512

Tmpaddr = Addr And &HFF000000
Shift Tmpaddr , Right , 24
Cmd(2) = Tmpaddr
Tmpaddr = Addr And &H00FF0000
Shift Tmpaddr , Right , 16
Cmd(3) = Tmpaddr
Tmpaddr = Addr And &H0000FF00
Shift Tmpaddr , Right , 8
Cmd(4) = Tmpaddr

' Sendet Commando Cmd24 An Mmc / Sd -karte(write 1 Block / 512 Bytes)
Fn_ergo = Mmc_write_command(cmd(1))
If Fn_ergo <> 0 Then Return

' Wartet Einen Moment Und Sendet Einen Clock An Die Mmc / Sd -karte
For Count = 1 To 100
Databyte = Mmc_read_byte()
Next

' Sendet Start Byte An Mmc / Sd -karte
Databyte = &HFE
Call Mmc_write_byte(databyte)

' Schreiben Des Bolcks(512bytes) Auf Mmc / Sd -karte
For Count = 1 To 512
Call Mmc_write_byte(buffer(count))
Next Count

' Crc -byte Schreiben
Databyte = &HFF
Call Mmc_write_byte(databyte)
Call Mmc_write_byte(databyte)

' Wartet Auf Mmc / Sd -karte Busy
Do
Databyte = Mmc_read_byte()
Loop Until Databyte = &HFF

' Set Mmc_chip_select To High(mmc / Sd -karte Inaktiv)
Set Mmc_cs
Mmc_write_sector = 0
End Function


' ################################################## ##########################
' ###### Routine Zum Lesen Des Cid Registers Von Der Mmc / Sd -karte(16bytes)
' ################################################## ##########################
Sub Mmc_read_block(cmd() As Byte , Anz_bytes As Word)

' Sendet Commando Cmd An Mmc / Sd -karte
Fn_ergo = Mmc_write_command(cmd(1))
If Fn_ergo <> 0 Then Return

' Wartet Auf Start Byte Von Der Mmc / Sd -karte(feh / Start Byte)
Do
Databyte = Mmc_read_byte()
Loop Until Databyte = &HFE

' Lesen Des Bolcks(normal 512bytes) Von Mmc / Sd -karte
For Count = 1 To Anz_bytes
Buffer(count) = Mmc_read_byte()
Next Count

' Crc -byte Auslesen
Databyte = Mmc_read_byte()
Databyte = Mmc_read_byte()

' Set Mmc_chip_select To High(mmc / Sd -karte Inaktiv)
Set Mmc_cs
End Sub


' ################################################## ##########################
' ###### Routine Zum Lesen Eines Blocks(512byte) Von Der Mmc / Sd -karte
' ################################################## ##########################
Sub Mmc_read_sector(byval Addr As Long )

Local Tmpaddr As Long
' Kommando 17 Zum Lesen Eines Blocks Von Der Mmc / Sd - Karte
Cmd(1) = &H51
Cmd(2) = &H00
Cmd(3) = &H00
Cmd(4) = &H00
Cmd(5) = &H00
Cmd(6) = &HFF

' Die Adressierung Der Mmc / Sd -karte Wird In Bytes Angegeben,
' Addr Wird Von Blocks Zu Bytes Umgerechnet Danach Werden
' Diese In Das Commando Eingef�gt * /
Shift Addr , Left , 9 ' Addr = Addr * 512

Tmpaddr = Addr And &HFF000000
Shift Tmpaddr , Right , 24
Cmd(2) = Tmpaddr
Tmpaddr = Addr And &H00FF0000
Shift Tmpaddr , Right , 16
Cmd(3) = Tmpaddr
Tmpaddr = Addr And &H0000FF00
Shift Tmpaddr , Right , 8
Cmd(4) = Tmpaddr
Print "READSEC ";
Anz_bytes = 512
Call Mmc_read_block(cmd(1) , Anz_bytes)
Print "retuor"
End Sub


' ################################################## ##########################
' ###### Routine Zum Lesen Des Cid Registers Von Der Mmc / Sd -karte(16bytes)
' ################################################## ##########################
Sub Mmc_read_cid()
' Kommando 10 zum Lesen des CID
Cmd(1) = &H4A
Cmd(2) = &H00
Cmd(3) = &H00
Cmd(4) = &H00
Cmd(5) = &H00
Cmd(6) = &HFF

Anz_bytes = 16
Call Mmc_read_block(cmd(1) , Anz_bytes)
End Sub


' ################################################## ##########################
' ###### Routine Zum Lesen Des Csd Registers Von Der Mmc / Sd -karte(16bytes)
' ################################################## ##########################
Sub Mmc_read_csd()
' Kommando 9 zum Lesen des CSD
Cmd(1) = &H49
Cmd(2) = &H00
Cmd(3) = &H00
Cmd(4) = &H00
Cmd(5) = &H00
Cmd(6) = &HFF

Anz_bytes = 16
Call Mmc_read_block(cmd(1) , Anz_bytes)
End Sub


Und nun die neue Version mit der mmc-lib.


$regfile = "m32def.dat"
$crystal = 16000000
$baud = 9600
Baud = 9600

Dim Abuffer(512) As Byte
Dim Wsrampointer As Word

'-------------------------------------------------------------------------------
' Config_MMC.BAS
' Config File for MMC Flash Cards Driver
' (c) 2003-2005 , MCS Electronics / V�gel Franz Josef
'-------------------------------------------------------------------------------
' Place MMC.LIB in the LIB-Path of BASCOM-AVR installation
'
'Connection as following
'MMC M128/M103
'1 MMC_CS PORTB.0
'2 MOSI PORTB.2
'3 GND
'4 +3.3V
'5 CLOCK PORTB.1
'6 GND
'7 MISO, PORTB.3

' you can vary MMC_CS on HW-SPI and all pins on SOFT-SPI, check settings
' ========== Start of user definable range =====================================

' you can use HW-SPI of the AVR (recommended) or a driver build in Soft-SPI, if
' the HW-SPI of the AVR is occupied by an other SPI-Device with different settings

' Declare here you SPI-Mode
' using HW-SPI: cMMC_Soft = 0
' not using HW_SPI: cMMC_Soft = 1
Const Cmmc_soft = 0


' define Chip-Select Pin
Config Pinb.0 = Output ' define here Pin for CS of MMC/SD Card
Max_cs Alias Portb.0
Set Max_cs

Config Pinb.1 = Output ' define here Pin for CS of MMC/SD Card
Mmc_cs Alias Portb.1
Set Mmc_cs

' Define here SS Pin of HW-SPI of the CPU (f.e. Pinb.0 on M128)
Config Pinb.4 = Output ' define here Pin of SPI SS
Spi_ss Alias Portb.4
Set Spi_ss ' Set SPI-SS to Output and High por Proper work of
' SPI as Master

' HW-SPI is configured to highest Speed
Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = high , Phase = 1 , Clockrate = 64 , Noss = 1
'Spsr = 1 ' Double speed on ATMega128
Spiinit ' Init SPI

' ========== End of user definable range =======================================


' Error
Const Cperrdrivereset = 225 ' Error response Byte at Reset command
Const Cperrdriveinit = 226 ' Error response Byte at Init Command
Const Cperrdrivereadcommand = 227 ' Error response Byte at Read Command
Const Cperrdrivewritecommand = 228 ' Error response Byte at Write Command
Const Cperrdrivereadresponse = 229 ' No Data response Byte from MMC at Read
Const Cperrdrivewriteresponse = 230 ' No Data response Byte from MMC at Write
Const Cperrdrive = 231
Const Cperrdrivenotsupported = 232 ' return code for DriveGetIdentity, not supported yet

Waitms 1 ' Wait some time before initialising MMC/SD
Dim Gbdriveerror As Byte ' General Driver Error register
Dim Gbdriveerrorreg As Byte ' Driver load Error-Register of HD in case of error
Dim Gbdrivestatusreg As Byte ' Driver load Status-Register of HD on case of error
Dim Gbdrivedebug As Byte
$lib "MMC.LIB" ' link driver library
$external _mmc

Dim I As Word
Dim Sectornr As Long
Wsrampointer = Varptr(abuffer(1))

Print
Input "Start?" , I
Gbdriveerror = Driveinit() ' Init MMC/SD Card

Print "Init ";
Print Gbdriveerror

Do
Print
Input "Sector:" , Sectornr
Gbdriveerror = Drivereadsector(wsrampointer , Sectornr)
Print "Read" ; Gbdriveerror
For I = 1 To 512
Print Abuffer(i) ;
Print " ";
Next I
Waitms 1000
Loop

End 'end program

roboterheld
11.11.2007, 12:34
ich möchte creativ bleiben und nicht immer das vorgekaute nutzen.
es ist für mich was feines, wenn ich sehe, das mit den einfachen schiebebefehl (shiftout/in) solche dinge gemacht werden können.

das mit den vorgefertigten ist für mich keine herausforderung. das sollen die benutzen die beruflich in zeitnot sind und schnell was auf die beine stellen wollen. ich bin ein hobbist und bin nicht in zeitnot.
mit fertigen routinen macht das hobby kein spass.

ich kenne alle fertigen routinen von winavr-c und von bascom die im hintergrung arbeiten.

ist gut gemeint. ich halte mich so fit !

mfg

roboterheld
11.11.2007, 12:55
ich habe dein erste programm in softspi gestestet. läuft nicht.
ist für die fehlersuche auch zu undurchsichtig geschrieben.
die config der pins wird zb 2x durchgeführt, einmal zu anfang und dann in der ini, warum?
das zweite hat zuviel geheimnisse, die ich nicht verfolgen kann.

mfg

robobaer
11.11.2007, 13:00
ich möchte creativ bleiben und nicht immer das vorgekaute nutzen.
es ist für mich was feines, wenn ich sehe, das mit den einfachen schiebebefehl (shiftout/in) solche dinge gemacht werden können.

das mit den vorgefertigten ist für mich keine herausforderung. das sollen die benutzen die beruflich in zeitnot sind und schnell was auf die beine stellen wollen. ich bin ein hobbist und bin nicht in zeitnot.
mit fertigen routinen macht das hobby kein spass.


Upps, wusste nicht dass du "back to the roots" willst. Dann hättest du auch Shiftin/out selbst schreiben müssen :-).
Na ja, nix für ungut und viel Spass beim Proggen.

mfg.
Joachim

roboterheld
11.11.2007, 13:01
jetzt habe ich mit dem ersten programm die hard-spi genommen, habe meine mmc umgesteckt zur spi, wird auch nicht erkannt.
von 4 verschiedenen karten wird nur bei mir 1 erkannt. programm ist zu unsicher.

bei meinem einfachen gestrickten programm werden alle 4 erkannt.


mfg

roboterheld
11.11.2007, 13:04
....Upps, wusste nicht dass du "back to the roots" willst. Dann hättest du auch Shiftin/out selbst schreiben müssen.....

hab ich gestern probiert, ist eine einfache tolle sache mit dem clocks.
shiftout/in kann man gut selber herstellen, ist sehr einfach.

den code kann man gut in asm-bascom einbauen:




;////// ShiftOut //////////////////////////
_Sout: sbi DDRB, 1
ldi r24,0x08
_So2: rol zl
brcc _So1
sbi PORTB,1
rjmp _So3
_So1: cbi PORTB,1
_So3: sbi PORTB,3
dec r24
cbi PORTB,3
brne _So2
cbi PORTB,1
ret

;////// ShiftIn //////////////////////////
_Sin: cbi DDRB,2
ldi r24,0x08
_Si4: clc
sbi PORTB,3
sbic PINB,2
sec
rol zl
cbi PORTB,3
dec r24
brne _Si4
ret