📄 indoor-sdcard.asm
字号:
; ---------------------------------------------------------
;
; SD Card Interfacing Functions
;
; ---------------------------------------------------------
; Author: Manfred Langemann
; Begin of project: 20.01.2006
; Latest version generated: 22.02.2006
; Filename: Indoor-SDCard.asm
; ---------------------------------------------------------
;
; Functions implemented:
; - SD card interface software
;
; ---------------------------------------------------------
; SD Card Definitions
; ---------------------------------------------------------
;
.equ SDCard_Write = PORTB
.equ SDCard_Read = PINB
.equ SDCard_Direction_Register = DDRB
.equ SDCard_DataIn = PINB0
.equ SDCard_DataOut = PORTB1
.equ SDCard_Clock = PORTB2
.equ SDCard_ChipSelect = PORTB3
;
; Here are the constant command bytes for the SD Card
;
Const_SDCard_CMD_00: .DB 0x40,0x00,0x00,0x00,0x00,0x95 ; Reset SD card
Const_SDCard_CMD_01: .DB 0x41,0x00,0x00,0x00,0x00,0xFF ; Initialise SD card
Const_SDCard_CMD_16: .DB 0x51,0x00,0x00,0x00,0x00,0xFF ; Read one block of 512 Byte from SD card
; Address byte will be filled up in program
Const_SDCard_CMD_24: .DB 0x58,0x00,0x00,0x00,0x00,0xFF ; Write Read one block of 512 Byte to SD card
; Address byte will be filled up in program
; *********************************************************
; Function Init_SDCard
;
; Purpose: Initialise the SD Card
; Return value:
; - temp1 = 1: Function successful, otherwise not
;
; *********************************************************
Init_SDCard:
;
; Save registers in use
;
push temp2 ; Save temp2 register
push XL ; Save XL register
push XH ; Save XH register
push ZL ; Save ZL register
push ZH ; Save ZH register
;
; Write the static command bytes to SRAM
;
ldi temp1, 24 ; Number of Bytes to be stored in SRAM
;
; Get constand address (Note: to be divided by 2, to get correct address)
;
ldi ZH, HIGH(Const_SDCard_CMD_00<<1); Get high address of constant
ldi ZL, LOW(Const_SDCard_CMD_00<<1) ; Get low address of constant
;
; Get SRAM address
;
ldi XH, HIGH(SDCard_Command_00) ; Get high address of SRAM
ldi XL, LOW(SDCard_Command_00) ; Get low address of SRAM
;
; Now shuffle the 24 bytes for the SD Card commands
;
Init_SDCard_1:
lpm temp2, Z+ ; Get the byte in const address
st X+, temp2 ; Store the byte in SRAM
dec temp1
brne Init_SDCard_1
;
; Set SD-Card ports (direction and state)
;
; PortB0: Input = Data Output von SD-Card
; PortB1: Output = Data Input von SD-Card
; PortB2: Output = Clock Input von SD-Card
; PortB3: Output = ChipSelect Input von SD-Card
;
ldi temp1, (1<<DDB1) | (1<<DDB2) | (1<<DDB3)
out SDCard_Direction_Register, temp1
;
; Set ChipSelect to high level
; Set Data Output to high level
; Set Clock to high level
;
ldi temp1, (1<<SDCard_ChipSelect) | (1<<SDCard_DataOut) | (1<<SDCard_Clock)
out SDCard_Write, temp1
;
; Wait for Chip Select signal setting
;
ldi temp2, Timeout_200
Init_SDCard_1a:
nop
dec temp2
brne Init_SDCard_1a
;
; Initialisation of the SD Card in the SPI Mode
; Send minimum 74 Clocks to SD Card
; Minimum is: 11 bytes with 8 clocks = 88 clocks
;
ldi temp2, 11
Init_SDCard_2:
ldi temp1, 0xff
call Write_Byte_SDCard
dec temp2
brne Init_SDCard_2
;
; Write Command CMD0 to SD Card to reset it. We try it 200 times
;
ldi temp2, Timeout_200
Init_SDCard_3:
dec temp2
brne Init_SDCard_4 ; Try it 200 times
ldi temp1, 0 ; without success, set return value to 0, exit function
rjmp Init_SDCard_7
;
; Get the command address
;
Init_SDCard_4:
ldi ZH, HIGH(SDCard_Command_00) ; Get high address of CMD0 in SRAM
ldi ZL, LOW(SDCard_Command_00) ; Get low address of CMD0 in SRAM
;
; Write the command
;
call Write_Command_SDCard ; Return value in temp1 register
;
; When command is successful (return value = 1), then it returns in temp1 register a value of 1
;
cpi temp1, 1
brne Init_SDCard_3
;
; Disable SC Dard
;
call Disable_SDCard
;
; Wait a time
;
ldi temp2, Timeout_200
Init_SDCard_4a:
nop
dec temp2
brne Init_SDCard_4a
;
; ---------------------------------------------------------
; Now the card has successfully been reset (to be done after power on)
; Now we have to send the CMD1 command (Initialisation)
; ---------------------------------------------------------
;
ldi temp2, Timeout_100
Init_SDCard_5:
dec temp2
brne Init_SDCard_6 ; Try it 100 times
ldi temp1, 0 ; without success, set return value to 0, exit function
rjmp Init_SDCard_7
;
; Get the command address
;
Init_SDCard_6:
ldi ZH, HIGH(SDCard_Command_01) ; Get high address of CMD1 in SRAM
ldi ZL, LOW(SDCard_Command_01) ; Get low address of CMD1 in SRAM
;
; Write the command
;
call Write_Command_SDCard ; Return value in temp1 register
;
; When command is successful (return value = 0), then it returns in temp1 register a value of 1
;
cpi temp1, 0
brne Init_SDCard_5
;
; Set return value
;
ldi temp1, 1
Init_SDCard_7:
;
; Disable SD Card
;
call Disable_SDCard
;
; Restore used registers
;
pop ZH ; Restore ZH register
pop ZL ; Restore ZL register
pop XH ; Restore XH register
pop XL ; Restore XL register
pop temp2 ; Restore temp2 register
ret
; *********************************************************
; Function Write_Command_SDCard
;
; - Write a 6 Byte command to the SD Card
; - Address of first Command Byte is in Z Register
; - Command answer will be returned in temp1 register
; temp1 = 0xFF -> Function not successful, else not
;
; *********************************************************
Write_Command_SDCard:
;
; Save registers in use
;
push temp2 ; Save temp2 register
push XL ; Save XL register
push XH ; Save XH register
;
; Ensable SD Card
;
call Enable_SDCard
;
; Write 6 Byte command to SD Card
;
ldi temp2, 6
Write_Command_SDCard_1:
ld temp1, Z+
call Write_Byte_SDCard
dec temp2
brne Write_Command_SDCard_1
;
; Receive from SD Card a valid anser byte, which is NOT 0xFF
; We will allow 100 read cycles to get correct answer.
;
ldi temp2, Timeout_100
Write_Command_SDCard_2:
;
; Decrement the counter
;
; Already 100 times called ? If yes, then exit this function
;
dec temp2
brne Write_Command_SDCard_3
ldi temp1, 0
rjmp Write_Command_SDCard_4; OK, exit this function, because no return from SD card
;
Write_Command_SDCard_3:
;
; Read the byte from the SD card
;
call Read_Byte_SDCard
;
; If returned value is still 0xFF, then read once more
;
cpi temp1, 0xFF
breq Write_Command_SDCard_2
;
; Only way to exit this function
;
Write_Command_SDCard_4:
;
; Restore used registers
;
pop XH ; Restore XH register
pop XL ; Restore XL register
pop temp2 ; Restore temp2 register
ret
; *********************************************************
; Function Write_Byte_SDCard
;
; - Writes one byte to the SD Card
; - Byte to be written is in temp1
; - MSB will be sent as first bit
; - Used registers:
; - temp1
;
; *********************************************************
Write_Byte_SDCard:
;
; Save registers in use
;
push temp2 ; Save temp2 register
ldi temp2, 8 ; 8 bits to be transmitted
Write_Byte_SDCard_1:
sbrs temp1, 7 ; Skip if bit 7 (MSB) is set
rjmp Write_Byte_SDCard_2
;
; Write 1 to card
;
sbi SDCard_Write, SDCard_DataOut
rjmp Write_Byte_SDCard_3
;
; Write 0 to card
;
Write_Byte_SDCard_2:
cbi SDCard_Write, SDCard_DataOut
;
; Write a low clock puls to SDCard
;
Write_Byte_SDCard_3:
cbi SDCard_Write, SDCard_Clock ; Set Clock level to LOW
sbi SDCard_Write, SDCard_Clock ; Set Clock level to HIGH
;
; Shift data byte to left for 1 bit
;
lsl temp1
;
; Decrease bit counter
;
dec temp2
brne Write_Byte_SDCard_1
;
; Restore used registers
;
pop temp2 ; Restore temp2 register
ret
; *********************************************************
; Function Read_Byte_SDCard
;
; - Reads one byte from the SD Card
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -