با سلام من از این کد برای ارتبتط با MMC استفاده کردم ولی یک سکتور رو میتونم بنویسم و بخونم. مثلا اگر بنویسم Mwrite &h00000000 و خط بعدش هم بنویسم Mwtite &h00000001 دیتایی که تو دومی بهش دادم رو تو سکتور اول جای دیتای قبلی می نویسه خودم فکر میکنم آدرس دهی اشتباهه نظر شما چیه؟
کد:
' Program: MMC.BAS written using Bascom-AVR ver 1.11.6.2
' Basic program to interface with a Sandisk
' MMC module using the SPI protocol.
'
' ALPHA CODE
' **** NOT FOR COMMERCIAL USE *****
' Ver. 0.0.9 Aug, 2001
'
' Project Reference: MMC-AT103L
' MCU: Atmel AT103L
' Software: Bascom-AVR ver 1.11.6.2
' Atmel Programmer: STK300 development board set at 3.3v.
' ISP and terminal output
'
' Initial Date: July 23, 2001
' Projected Completion Date: Unknown
'
' Author: Ranjit Diol
' rsdiol@compsys1.com
' http://www.compsys1.com/workbench
'
'***************************************************************
' (c) COMPSys, 2001
' All Rights Reserved
'***************************************************************
'
' DISCLAIMER: This file is being released as non-commericial
' software. It is being provided "AS IS", neither the author,
' nor COMPSys shall be held liable for any damages caused
' by its use either directly or indirectly in any form or manner.
'
'===============================================================
'
'Brief: The MMC is a 3volt part therefore all data lines
' must be conditioned if interfacing with a 5v mcu.
' Or, a 3.3v MCU can be used such as the AT103L or the AT90LS8535
'
'IMPORTANT NOTE:
' In SPI mode the MMC's minimum block size is 512 bytes
' therefore data has to be accumulated first either in an eeprom
' or in memory before sending it out as a chunk of 512 bytes.
'
' MMC pins in SPI mode:
' Pin1:ChipSelect(SS),Pin2:MMC input(MOSI),Pin3:GND,Pin4:3V+,
' Pin5:Clock(SCK), Pin6:GND, Pin7:MMC output(MISO)
' AT103L pins:
' Portb.0 SS,Portb.1 SCK,Portb.2 MOSI, Portb.3 MISO
'
'
'==============================================================
$regfile = "M103def.dat" 'AT103L mcu
'Constants
Const Msbl = 0
Const Msbh = 1
Const Dly = 2
Const Bits8 = 8
Const Bits16 = 16
Const Bits32 = 32
'Variables
Dim Res(16) As Byte
Dim Indat(512) As Byte 'Memory buffer for temp storage.
Dim Dat As Byte
Dim Resp As Byte
Dim Resp2 As Word
Dim I As Word
Dim J As Word
Dim X As Byte
Dim Y As Byte
Dim K As Byte
Dim Bout As Byte
Dim Addr1 As Byte
Dim Addr2 As Byte
Dim Addr3 As Byte
Dim Addr4 As Byte
Dim Addr As Long
Dim Saddr As Long
Dim Eaddr As Long
'Aliases
Cs Alias Portb.0
Clk Alias Portb.1
Miso Alias Pinb.3 'inp
Mosi Alias Portb.2 'out
'Declarations
Declare Sub Mprint
Declare Sub Minit
Declare Sub Mstatus
Declare Sub Mwrite(byval Bout As Byte , Byval Addr As Long )
Declare Sub Mread(byval Addr As Long )
Declare Sub Merase(byval Saddr As Long , Byval Eaddr As Long)
'AT103 HW SPI Portb0=SS to MMC 1, Portb1=clock to MMC 5, MISO=Portb3 to MMC 7, MOSI=Portb2 to MMC 2
Config Pinb.0 = Output
Config Pinb.1 = Output
Config Pinb.2 = Output
Config Pinb.3 = Input
Waitms 300
Config Spi = Soft , Din = Pinb.3 , Dout = Portb.2 , Ss = Portb.0 , Clock = Portb.1
Spiinit
'******** MAIN PROGRAM *************
Main:
'Initialize the MMCC
Minit
'If you want to use the ERASE routine
'Uncomment and enter the start/end 32bit address values
'Call erase subroutine enter StartAddr , EndAddr
'Merase &H00000000 , &H00001000
'call write subroutine as: BYTE-TO-WRITE, 32BIT_ADDRESS
Mwrite &HBE , &H00000000
'Call read sub from 512 from address are put in array INDAT
Mread &H00000000
'Call print sub print 512 bytes stored in INDAT array
Mprint
Xloop:
Set Cs
Shiftout Mosi , Clk , Dat , Msbl
Endloop:
Goto Endloop
End 'end program
'************ END OF PROGRAM **************
'======= SUB ROUTINES AND FUNCTIONS =======
'*** INITIALIZATION OF MMC ***
Sub Minit
Set Cs
Dat = &HFF
For I = 1 To 10
Shiftout Mosi , Clk , Dat , Msbl
Next I
Resp = 255
Reset Cs
Cmd0:
Dat = &H40
Shiftout Mosi , Clk , Dat , Msbl
Addr = &H00000000
Shiftout Mosi , Clk , Addr , Msbl
Dat = &H95
Shiftout Mosi , Clk , Dat , Msbl
While Resp <> &H01
Shiftin Miso , Clk , Resp , Msbl
Wend
Lcd "C0:" ; Hex(resp)
'Initialized
Set Cs
Waitms 50
Reset Cs
Dat = &HFF
Cmd1:
While Resp <> &H00
Set Cs
Shiftout Mosi , Clk , Dat , Msbl
Shiftin Miso , Clk , Resp , Msbl
Reset Cs
Dat = &H41
Shiftout Mosi , Clk , Dat , Msbl
Addr = 0
Shiftout Mosi , Clk , Addr , Msbl
Dat = &HFF
Shiftout Mosi , Clk , Dat , Msbl
Shiftout Mosi , Clk , Dat , Msbl
Shiftin Miso , Clk , Resp , Msbl
Wend
Dat = &HFF
Set Cs
Lcd "C1:" ; Hex(resp)
End Sub
'**** READ routine assumes ADDR uses Status subroutine *****
Sub Mread(byval Addr As Long)
Set Cs
Dat = &HFF
Shiftout Mosi , Clk , Dat , Msbl
Shiftin Miso , Clk , Resp , Msbl
Reset Cs
Dat = &H51
Shiftout Mosi , Clk , Dat , Msbl
Shiftout Mosi , Clk , Addr , Msbl
Dat = &HFF
Shiftout Mosi , Clk , Dat , Msbl
Shiftin Miso , Clk , Resp , Msbl
While Resp <> 0
Shiftin Miso , Clk , Resp , Msbl
Wend
While Resp <> &HFE
Shiftin Miso , Clk , Resp , Msbl
Wend
'Lcd Hex(resp)
For I = 1 To 512
Shiftin Miso , Clk , Resp , Msbl
Indat(i) = Resp
'Print Hex(resp);
Next I
Shiftin Miso , Clk , Resp , Msbl
Shiftin Miso , Clk , Resp , Msbl
Set Cs
Mstatus
'Return
End Sub
'****Block Start Tag / End Tag and ERASE ****
Sub Merase(byval Saddr As Long , Byval Eaddr As Long)
'erase first 1024 bytes
'Block START TAG
Cmd32:
Set Cs
Shiftout Mosi , Clk , Dat , Msbl
Shiftin Miso , Clk , Resp , Msbl
Reset Cs
Dat = &H60
Shiftout Mosi , Clk , Dat , Msbl
Shiftout Mosi , Clk , Saddr , Msbl
Dat = &HFF
Shiftout Mosi , Clk , Dat , Msbl
Shiftout Mosi , Clk , Dat , Msbl
Shiftin Miso , Clk , Resp , Msbl
While Resp <> &H00
Shiftin Miso , Clk , Resp , Msbl
Wend
'Block END TAG
Cmd33:
Set Cs
Shiftout Mosi , Clk , Dat , Msbl
Shiftin Miso , Clk , Resp , Msbl
Reset Cs
Dat = &H61
Shiftout Mosi , Clk , Dat , Msbl
Shiftout Mosi , Clk , Eaddr , Msbl
Dat = &HFF
Shiftout Mosi , Clk , Dat , Msbl
Shiftout Mosi , Clk , Dat , Msbl
Shiftin Miso , Clk , Resp , Msbl
While Resp <> &H00
Shiftin Miso , Clk , Resp , Msbl
Wend
'ERASE SELECTED BLOCK
Cmd38:
Set Cs
Shiftout Mosi , Clk , Dat , Msbl
Shiftin Miso , Clk , Resp , Msbl
Reset Cs
Dat = &H66
Shiftout Mosi , Clk , Dat , Msbl
Addr = 0
Shiftout Mosi , Clk , Addr , Msbl
Dat = &HFF
Shiftout Mosi , Clk , Dat , Msbl
Shiftout Mosi , Clk , Dat , Msbl
Shiftin Miso , Clk , Resp , Msbl
While Resp = 0
Shiftin Miso , Clk , Resp , Msbl
Wend
Mstatus
End Sub
'** WRITE Routine assumes ADDR, BOUT uses Status subroutine **
Sub Mwrite(byval Bout As Byte , Byval Addr As Long)
Cmd24:
Set Cs
Dat = &HFF
Shiftout Mosi , Clk , Dat , Msbl
Shiftin Miso , Clk , Resp , Msbl
Reset Cs
Dat = &H58
Shiftout Mosi , Clk , Dat , Msbl
Shiftout Mosi , Clk , Addr , Msbl
Dat = &HFF
Shiftout Mosi , Clk , Dat , Msbl
Shiftout Mosi , Clk , Dat , Msbl
Shiftin Miso , Clk , Resp , Msbl
While Resp <> 0
Shiftin Miso , Clk , Resp , Msbl
Wend
Lcd "C24:" ; Hex(resp)
Dat = &HFE
Shiftout Mosi , Clk , Dat , Msbl
For I = 1 To 512
Shiftout Mosi , Clk , Bout , Msbl
Next I
Dat = &HFF
Shiftout Mosi , Clk , Dat , Msbl
Shiftout Mosi , Clk , Dat , Msbl
Shiftin Miso , Clk , Resp , Msbl
'If Y = &H05 write is a success
Y = Resp And &H0F
'If Resp = 0 the MMC is busy
Shiftin Miso , Clk , Resp , Msbl
While Resp = 0
Shiftin Miso , Clk , Resp , Msbl
Wend
Lowerline
Lcd "Wr:" ; Hex(y)
Set Cs
Mstatus
End Sub
'Get MMC Status
Sub Mstatus
Cmd13:
Set Cs
Shiftout Mosi , Clk , Dat , Msbl
Shiftin Miso , Clk , Resp , Msbl
Reset Cs
Dat = &H4D
Shiftout Mosi , Clk , Dat , Msbl
Addr = 0
Shiftout Mosi , Clk , Addr , Msbl
Dat = &HFF
Shiftout Mosi , Clk , Dat , Msbl
Shiftout Mosi , Clk , Dat , Msbl
Shiftin Miso , Clk , Resp2 , Msbl
Print "Status:" ; Hex(resp2)
Set Cs
'Return
End Sub
Sub Mprint
For I = 1 To 512
Print Hex(indat(i));
Next
Mstatus
End Sub