Чтение и запись DataFlash AT45DB321D

Схема
SHEMA_flash

Текст программы микроконтроллера

.include "c:\Program Files\Atmel\AVR Tools\AvrAssembler2\Appnotes\m8535def.inc"

.def byteRX         =r17          ;байт RXС
.def byteA          =r19

;=========================================================         
.MACRO outi
        ldi r16,@1
        out @0,r16
.ENDMACRO

.org 0x00
        rjmp RESET

.org URXCaddr
        rjmp UART_RXC

;=========================================================
UART_RXC:
        in byteRX,UDR            ;чтение байта команды
        cpi byteRX,1
        breq c1
        cpi byteRX,2
        breq c2
        cpi byteRX,3
        breq c3
        cpi byteRX,4
        breq c4
        cpi byteRX,5
        breq c5
        rjmp ex

c1:     rcall ReadStatus
        rjmp ex
c2:     rcall DeviceID
        rjmp ex
c3:     rcall Read
        rjmp ex
c4:     rcall Record
        rjmp ex
ex:
reti

;=========================================================
RESET:                           
        outi WDTCR,0x0A           ;Watchdog enable
        outi SPH,HIGH(RAMEND)     ;определение начала стека в ОЗУ
        outi SPL,LOW(RAMEND)   
        outi PORTA,0x00           ;переключение PA на ввод
        outi DDRA,0x00
        outi DDRD,0xFF            ;все линии порта D выходы
   
        outi PORTB,0b10111111     ;WP=1, CS=1, Reset=1, MOSI, SCK выход; MISO вход
        outi DDRB,0b10111111

        ;SPI в режиме мастера, установка скорости связи fck/2
       
        outi SPCR,1<<SPE|1<<MSTR|1<<CPOL|1<<CPHA    
        outi SPSR, 1<<SPI2X

        ldi YL,low(528)            ;528 байт на одной странице памяти
        ldi YH,high(528)
        rcall uart_init                                
        sei                        ;разрешение прерываний   

;=========================================================
Loop:    wdr                       ;сброс сторожевого таймера
rjmp Loop

;=========================================================
UART_TX:
         cbi UCSRA,7               ;сброс флага TX
TX:      wdr
         sbis UCSRA,UDRE           ;ожидание освобождения буфера передатчика
         rjmp TX                           
         out UDR,r16               ;Помещение данных (r16) в буфер, отправка данных
ret

;=========================================================
Record:
        sbi    PORTB,1              ;CS inactive
        nop
        nop
        cbi    PORTB,1              ;DF CS Active!
                                    ;to reset dataflash command decoder
        ldi    R16,0x82             ;код операции Record
        rcall SPI_RW                ;send status register read op-code
        clr    R16
        rcall SPI_RW                ;dummy write to get result
        clr    R16   
        rcall SPI_RW                ;dummy write to get result
        clr    R16
        rcall SPI_RW                ;dummy write to get result
ret
;=========================================================
Read:
        sbi    PORTB,1              ;CS inactive
        nop
        nop
        cbi    PORTB,1              ;DF CS Active!
                                    ;to reset dataflash command decoder
        ldi    R16,0x03             ;код операции Read
        rcall SPI_RW                ;send status register read op-code
        clr    R16
        rcall SPI_RW                ;dummy write to get result
        clr    R16
         rcall SPI_RW               ;dummy write to get result
        clr    R16
         rcall SPI_RW               ;dummy write to get result

        ldi XL,low(600)             ;чтение 600 байт
        ldi XH,high(600)
d1:     wdr
        clr    R16
        rcall SPI_RW                ;dummy write to get result
        rcall UART_TX
        sbiw XL,1
        brne d1
ret

;=========================================================
DeviceID:
        sbi    PORTB,1              ;CS inactive
        nop
        nop
        cbi    PORTB,1              ;DF CS Active!
                                    ;to reset dataflash command decoder
        ldi    R16,0x9F             ;код операции DeviceID
        rcall SPI_RW                ;send status register read op-code
        clr    R16
        rcall SPI_RW                ;dummy write to get result
        rcall UART_TX
        clr    R16
         rcall SPI_RW               ;dummy write to get result
        rcall UART_TX
        clr    R16
         rcall SPI_RW               ;dummy write to get result
        rcall UART_TX
        clr    R16
         rcall SPI_RW               ;dummy write to get result
        rcall UART_TX
        clr    R16
         rcall SPI_RW               ;dummy write to get result
        rcall UART_TX
ret

;=========================================================
ReadStatus:
        sbi    PORTB,1              ;CS inactive
        nop
        nop
        cbi    PORTB,1              ;DF CS Active!
                                    ;to reset dataflash command decoder
        ldi    R16,0xD7             ;код операции ReadStatus
        rcall SPI_RW                ;send status register read op-code
        clr    R16
        rcall SPI_RW                ;dummy write to get result
        rcall UART_TX
ret

;=========================================================
SPI_RW:
        out    SPDR,R16
SPI_RW0:
        sbis SPSR,spif
        rjmp SPI_RW0                 ;wait for transfer complete, poll SPIF-flag
        in R16,SPDR
ret

;=========================================================
uart_init:

.equ XTAL = 16000000
.equ baudrate = 9600
.equ bauddivider = XTAL/(16*baudrate)-1

outi UBRRL,low(bauddivider)           ;set baud rate
outi UBRRH,high(bauddivider)
outi UCSRA,0                          ;без U2X
outi UCSRC,1<<URSEL|3<<UCSZ0          ;8 bit
outi UCSRB,1<<RXEN|1<<TXEN|1<<RXCIE   ;включить RX, TX
ret