Aus RN-Wissen.de
Version vom 22. Juni 2009, 21:05 Uhr von NLB (Diskussion | Beiträge)
QuellCode Get Flash FileSector.bas
'CopyRight
'Dipl.-Ing. Norbert L. Brodtmann , Gütersloh Germany
'This program is wrote to become familiar with SD-Card technologies
'in order to integrate it in my 8-acis Robotic-Controller (www.RoBo-mac.de).
'It is based on J.F. Vögel's AVR-DOS and uses parts of its code issued in his product documentation.
'It may be used in accordance of BASCOM's and AVR-DOS's license policy and agreement.
'* This program returns the Start-Sector Number of any file - short filenames (8.3) - stored in a Flash-Card
' in order to use it with direct access of the commands DriveWriteSektor() / DriveReadSektor() etc.
'* It also gives output to measure Transfer-Time; to benefit this, you need an oscilloscope.
'* You can use this program just to become familiar with SD-Cards too
' or include parts in your application. Therefore it is divvied in 5 parts.
'Part 1
'Declaration based on the used Hardware (Mega 128 / LCD 4 x 20 / SD-Card board of Display 3000).
'Part 2
'Additional declaration of including AVR-DOS and the type of Flash-Card used (FC, SD/MCC etc. ).
'Please note: You have to adapt the "config_CARD.bas" (for example Config_MMC.bas) to your system too.
'There is a (Compiler-) Function-switch to select of the following possibilities.
'Function_1 Test DOS-Commands using COM/TERMINAL in dialog
'Function_2 Running Part 3 to 5
'Function_3 Direct Sector Access and measurement of transfer-time by using an oscilloscope (Bort B.7)
' In addition you will find a trick to read a file's
' - (Long)-Name (up to 40 Characters + Extension = 44 in total incl. "dot") and its
' - Date/Time-Stamp.
'Function_1/2 needs a SRAM Size > 3k, Function_3 less than 1k
'Part 3
'A "GOSUB" Routine_fileinfo
'Asking for the files name (8.3) and searching information concerning this file (also including the Sector#)
'Part 4
'A "GOSUB" Routine_sector_select
'using the Sector# with the command DriveReadSektor() as a "how to do" example
'Part 5
'A "GOSUB" Routine_transfer_time_1
'to measure transfer time. Bort B.7 toggles with every DriveReadSektor() command.
'Using an oscilloscope you will get an frequency. Each period consists the time to read two sectors!
'This Routine is based on something similar I found in the Internet several times
'- however I do not know the Copyright owner, I suppose it is shareware.
'Please note:
'There is a tutorial (in German language) concerning these items at ......
'--- Part1 ---------------------------------------------------
$regfile = "m128def.dat" 'ATmega128
$crystal = 16000000
'---
Config Lcdbus = 4 '4-bit Step_Step_Mode
Config Lcd = 20 * 4 '20x4 LCD display
Config Lcdpin = Pin , Db4 = Porte.4 , Db5 = Porte.5 , Db6 = Porte.6 , Db7 = Porte.7 , E = Porte.3 , Rs = Porte.2
Const Lcd_line1 = "Get_Flash_FileSector"
Const Lcd_line2 = "CopyRight:"
Const Lcd_line3 = " www.RoBo-mac.de"
Cls : Cursor Off Noblink
Locate 1 , 1 : Lcd Lcd_line1
Locate 2 , 1 : Lcd Lcd_line2
Locate 3 , 1 : Lcd Lcd_line3
'Special Function (Display 3000)
Config Pinb.4 = Input 'Cardsensor
Config Pinb.5 = Output 'SD-Card active (High) / inaktiv (Low)
Config Pinb.6 = Input 'Writeprotect active (Low) / inaktiv (High)
Config Pinb.7 = Output 'Toggel
Portb = &B01110000
If Pinb.4 = 1 Then
Locate 4 , 1 : Lcd "Card NO"
End
Else
Locate 4 , 1 : Lcd "Card YES "
If Pinb.6 = 1 Then
Locate 4 , 11 : Lcd "read only"
Else
Locate 4 , 11 : Lcd "read/write"
End If
End If
'--- Part2 ---------------------------------------------------
' Adjust HW Stack, Soft-Stack and Frame size to 128 minimum each!!!
$hwstack = 128
$swstack = 128
$framesize = 128
Enable Interrupts
$baud1 = 9600
Open "Com1:" As Binary As #1 ' use #1 for fs_interpreter
'Include here your driver for Compactflash/HardDisk or other
'$include "Config_CompactFlash_M128.bas"
'$Include "Config_HardDisk_M128.bas"
$include "Config_MMC.bas"
'Select a function
'Const Function_switch = 1 'SRAM ca. 3340 / FS_Interpreter.bas active
'Const Function_switch = 2 'SRAM ca. 3030 / will use Part 3 to 5
Const Function_switch = 3 'SRAM ca. 780 / Just direct Sector Access
#if Function_switch = 3
'Direct Sector Access and measurement of transfer-time
'Does not neet: Config_AVR-DOS.bas !!!
Dim Ptr As Word 'Address-Pointer SRAM
Dim Buffer As String * 512
Dim Mmc_error As Byte
Dim Sector_now As Word
Ptr = Varptr(buffer)
For Sector_now = 512 To 10511 '512 is normaly the first Data-Sector
'Sector_now = 512 'endles
'Toggle Portb.7
Set Portb.7
Mmc_error = Drivereadsector(ptr , Sector_now) 'Ca. 1,37 msec HW / 6,05 msec SW per Sector
'Mmc_error = Drivewritesector(ptr , Sector_now) 'Ca. 1,83 msec HW / 7,5 msec SW per Sector
Reset Portb.7
''(
'The following code will only work fine, if these information
'- are specially placed by the PC-Program writing the file
'- to a very fresh formatted SD-Card!!!
Dim Datei_name As String * 45 At Buffer + 00 Overlay 'File Name max: (40.3)
Dim Datei_date_time As String * 19 At Buffer + 45 Overlay
Dim Interim As Byte
Dim Interim_2 As Byte At Mmc_error + 00 Overlay
If Sector_now = 512 Then
Waitms 1500
Locate 4 , 1 : Lcd Spc(20)
Locate 4 , 1 : Lcd Mid(datei_name , 1 , 20)
Wait 1
Interim_2 = Len(datei_name) 'Shiftlcd Left moves whole display, therefore
If 20 < Interim_2 Then
Interim_2 = Interim_2 - 19
For Interim = 2 To Interim_2
Locate 4 , 1 : Lcd Mid(datei_name , Interim , 20)
Waitms 200
Next
Wait 1
End If
Locate 4 , 1 : Lcd Mid(datei_date_time , 1 , 19) + " "
Wait 1
End If
'')
Next
End
'-------------------------------------------------------------
#else
$include "Config_AVR-DOS.bas" 'Include AVR-DOS Configuration and library
Dim Btemp1 As Byte
Print #1 , "Wait for Drive"
If Gbdriveerror = 0 Then
Print #1 , "Init File System ... ";
Btemp1 = Initfilesystem(1) ' Partition 1
' use 0 for drive without Master boot record
If Btemp1 <> 0 Then
Print #1 ,
Print #1 , "Error: " ; Btemp1 ; " at Init file system"
Print #1 ,
End
Else
Print #1 , " OK"
Print #1 , "Filesystem: " ; Gbfilesystem
Print #1 , "FAT Start Sector: " ; Glfatfirstsector
Print #1 , "Root Start Sector: " ; Glrootfirstsector
Print #1 , "Data First Sector: " ; Gldatafirstsector
Print #1 , "Max. Cluster Nummber: " ; Glmaxclusternumber
Print #1 , "Sectors per Cluster: " ; Gbsectorspercluster
Print #1 , "Root Entries: " ; Gwrootentries
Print #1 , "Sectors per FAT: " ; Glsectorsperfat
Print #1 , "Number of FATs: " ; Gbnumberoffats
Print #1 ,
Print #1 ,
End If
Else
Print #1 , "Error during Drive Init: " ; Gbdriveerror
End
End If
#endif
#if Function_switch = 1
Config Clock = Soft
Config Date = Mdy , Separator = .
$include "FS_Interpreter.bas" 'No GOSUBs allowed, (DIM conflicts)
#endif
#if Function_switch = 2
Gosub Routine_fileinfo
Gosub Routine_sector_select
Gosub Routine_transfer_time_1
#endif
End
#if Function_switch = 2
'--- Part3 ---------------------------------------------------
Routine_fileinfo:
Dim File_name As String * 12
Dim Pbfilenr As Byte
Dim Lltemp1 As Long
Dim Lbfilenumber As Byte
Dim Lbfilemode As Byte
Dim Lwfiledirentry As Word
Dim Llfiledirsectornumber As Long
Dim Llfilefirstcluster As Long
Dim Llfilesize As Long
Dim Llfileposition As Long
Dim Llfilesectornumber As Long
Dim Lbfilebufferstatus As Byte
Dim Lwfilebufferaddress As Word
Dim Sector_start As Long
Pbfilenr = 127 'use 127, to avoid conflicts with auto generatet numbers from FreeFile (128 to 255)
File_select:
Input "Select FileName (8.3) / Type END to finish program " , File_name
Locate 2 , 1 : Lcd "File: "
Locate 2 , 7 : Lcd File_name
Locate 3 , 1 : Lcd " "
If Ucase(file_name) = "END" Then
Print #1 , "Program finished"
Locate 3 , 1 : Lcd "Program finished"
End
End If
Open File_name For Input As #pbfilenr
Loadadr Pbfilenr , X
ld r24, X
!Call _GetFileHandle
brcc PrintFileInfo1
rjmp PrintFileInfoError
Printfileinfo1:
Loadadr Lbfilenumber , X
ldi r24, 25
!Call _Mem_Copy
Loadadr Lwfilebufferaddress , X
st X+, zl
st X+, zh
Print #1 ,
Print #1 , "File " ; File_name
Print #1 , "Handle#: " ; Lbfilenumber
Print #1 , "Open mode: " ; Bin(lbfilemode)
Print #1 , "Dir Entry#: " ; Lwfiledirentry
Print #1 , "Dir Sector#: " ; Llfiledirsectornumber
Print #1 , "First Cluster#: " ; Llfilefirstcluster
Print #1 , "Size: " ; Llfilesize
Print #1 , "Position: " ; Llfileposition
Print #1 , "Sector#: " ; Llfilesectornumber
Print #1 , "Buffer Status: " ; Bin(lbfilebufferstatus)
Lltemp1 = 0
Sector_start = Llfilesectornumber
Close #pbfilenr
Locate 3 , 1 : Lcd "Sector#:"
Locate 3 , 10 : Lcd Sector_start
Return
Printfileinfoerror:
'Print #1 , "No Filehandle for " ; Pbfilenr ; " found"
Print #1 , "FileName < " ; File_name ; " > Not Found "
Print #1 ,
Locate 3 , 1 : Lcd " Not Found "
Goto File_select
'--- Part4 ---------------------------------------------------
Routine_sector_select:
Dim Ptr As Word 'Address-Pointer SRAM
Dim Buffer As String * 512
Dim Mmc_error As Byte
Dim Sector_now As Long
Dim Sector_size As Long
Dim Sector_max As Long
Sector_size = Llfilesize
Shift Sector_size , Right , 9 'Division 512 Byte/Sector
'Btemp1 = Llfilesize \ 512 'does not work correct, therefore:
Shift Sector_size , Left , 9
If Sector_size < Llfilesize Then
Shift Sector_size , Right , 9
Sector_size = Sector_size + 1
Else
Shift Sector_size , Right , 9
End If
Ptr = Varptr(buffer) 'SRAM Adr von Buffer
Mmc_error = Drivereadsector(ptr , Sector_start)
Print
Print
Print "SectorSize: " ; Sector_size
Print "Read Start-Sector(" ; Sector_start ; ") ok."
Print
Print Buffer
Print
Return
'--- Part5 ---------------------------------------------------
Routine_transfer_time_1:
Print "For 'Transfer-Time' measurement with an oscilloscope use toggling PortB.7"
Print "- 1 Period represents 2 Sectors"
Print
Print "Test the 'Transfer-Time' "
Print " - for Read and Write (to be choosen by changing block-marker)"
Print " - with and without the Print-Commands"
Print " - with Soft/Hard SPI. To do so, select used SPI in File Config_CARD.bas"
Print
Input "To start the test, strike ENTER/RETURN now ! / Type END to finish program" , File_name
Print
Print
If Ucase(file_name) = "END" Then
Print #1 , "Program finished"
Locate 3 , 1 : Lcd "Program finished"
End
End If
Ptr = Varptr(buffer)
Sector_max = Sector_start + Sector_size
Sector_max = Sector_max - 1
If Gbdriveerror = 0 Then
Mmc_error = Driveinit()
If Mmc_error = 0 Then
Print "Driveinit Ok. "
For Sector_now = Sector_start To Sector_max
Toggle Portb.7
'Read
''(
Mmc_error = Drivereadsector(ptr , Sector_now)
If Mmc_error = 0 Then
Print "ReadSector(" ; Sector_now ; ") ok."
Print Buffer
Else
Print "Error during ReadSector(" ; Sector_now ; ") : " ; Mmc_error
End If
'')
'----------------
'Write
'( ' '
Mmc_error = Drivewritesector(ptr , Sector_now)
If Mmc_error = 0 Then
Print "WriteSector(" ; Sector_now ; ") ok."
Print Buffer
Else
Print "Error during WriteSector(" ; Sector_now ; ") : " ; Mmc_error
End If
')
Next Sector_now
Else
Print "Error during Driveinit(): " ; Mmc_error
End If
Print "End of Test"
End If
Return
#endif
Siehe auch
- [[BASCOM, SD/MMC und andere (SPI)-Flash-Karten