📄 spitwi.asm
字号:
;==============================================================================
; Procedury SPI
; Projekt: Miernik energii i mocy na ADE7759
;==============================================================================
.cseg
;------------------------------------------------------------------------------
USTAW_SPI: ; inicjalizacja interfejsu SPI w ATmega
sbi PORTB-1, 4 ; SS jako wyjscie
sbi ADE_CS_PORT, ADE_CS ; wylacz SPI w ADE7759 (ADE_CS stan wysoki)
sbi PORTB-1, 7 ; SCK jako wyjscie
sbi PORTB-1, 5 ; MOSI jako wyjscie
ldi temp, (1<<SPE) | (1<<MSTR) | (1<<CPHA) ; wlacz SPI
out SPCR, temp
ret
;------------------------------------------------------------------------------
SPI_TRX: ; transfer bajtu (z temp do SPI) i (z SPI do temp)
out SPDR, temp
STR_1: sbis SPSR, SPIF
rjmp STR_1 ; czekaj na ustawienie flagi zakonczenia transmisji
in temp, SPSR ; kasuj powyzsza flage
in temp, SPDR ; odczyt bajtu z rejestru danych SPI do temp
rcall DELAY_3_5us
ret
;------------------------------------------------------------------------------
SPI_ADE_WRITE_1B: ; przesylanie komendy + jeden bajt
; temp - komenda (adres), r0 - dane
SPI_ADE_ON
ori temp, 0b10000000 ; bit zapisu
rcall SPI_TRX ; wyslij komende (z temp)
mov temp, r0 ; teraz dane...
rcall SPI_TRX ; wyslij
SPI_ADE_OFF
ret
SPI_ADE_WRITE_2B: ; przesylanie komendy + dwa bajty
; temp - komenda, r1:r0 - dane
SPI_ADE_ON
ori temp, 0b10000000 ; bit zapisu =1
rcall SPI_TRX ; wyslij komende (z temp)
mov temp, r1 ; teraz starszy bajt...
rcall SPI_TRX ; wyslij
mov temp, r0 ; teraz mlodszy bajt...
rcall SPI_TRX ; wyslij
SPI_ADE_OFF
ret
;------------------
SPI_ADE_READ_1B: ; przesylanie komendy + jeden bajt do odbioru
; temp - komenda, r0 - dane
SPI_ADE_ON
andi temp, 0b00011111 ; bit zapisu =0
rcall SPI_TRX ; wyslij komende (z temp)
rcall SPI_TRX ; odbierz
mov r0, temp ; dane do r0
SPI_ADE_OFF
ret
SPI_ADE_READ_2B: ; przesylanie komendy + dwa bajty do odbioru
; temp - komenda, r1:r0 - dane
SPI_ADE_ON
andi temp, 0b00011111 ; bit zapisu =0
rcall SPI_TRX ; wyslij komende (z temp)
rcall SPI_TRX ; odbierz
mov r1, temp ; dane MSB do r1
rcall SPI_TRX ; odbierz
mov r0, temp ; dane LSB do r0
SPI_ADE_OFF
ret
;==============================================================================
; Procedury komunikacji I2C (TWI)
; Projekt: Miernik energii i mocy oraz rejestrator na ADE7759
;==============================================================================
.cseg
;==============================================================================
; Master Transmiter
; rejestr Y zawiera adres bufora danych do wyslania
; rejestr r0 zawiera ilosc bajtow do wyslania (NIE liczac adresu scalaka)
; pierwszy bajt danych to adres ukladu scalonego (i kierunek: write)
; W przypadku bledu jest przekazywany przez "temp"
;==============================================================================
TWI_MASTER_WRITE:
ldi temp, TWI_BR
out TWBR, temp ; Bit Rate
ldi temp, TWI_SR
out TWSR, temp ; preskaler
inc r0 ; zwiekszenie licznika, poniewaz na poczatku
inc r0 ; wysylania danych jest on zmniejszany
ldi temp, (1<<TWINT) | (1<<TWSTA) | (1<<TWEN)
out TWCR, temp ; START
TMW_W: in temp, TWCR
sbrs temp, TWINT
rjmp TMW_W ; czekaj na koniec transmisji (flaga TWINT)
in temp, TWSR ; sprawdzenie poprawnosci transmisji
andi temp, 0xF8
cpi temp, TWIS_MT_DATA_ACK
brne TMW_E1
rjmp TMW_N
TMW_E1: cpi temp, TWIS_MT_SLA_ACK
brne TMW_E2
rjmp TMW_N
TMW_E2: cpi temp, TWIS_START
brne TWI_ERROR ; BLAD
TMW_N: dec r0 ; zmniejsz licznik
breq TMW_STO
ld temp, Y+
out TWDR, temp ; dane do wyslania
ldi temp, (1<<TWINT) | (1<<TWEN)
out TWCR, temp ; start transmisji
rjmp TMW_W
TMW_STO: ldi temp, (1<<TWINT) | (1<<TWSTO) | (1<<TWEN)
out TWCR, temp ; STOP
clr temp ; brak bledu
ret
;------------------------------------------------------------------------------
TWI_ERROR:
mov r1, temp ; kopia bledu
ldi temp, (1<<TWINT) | (1<<TWSTO) | (1<<TWEN)
out TWCR, temp ; STOP
mov temp, r1 ; w temp zwraca kod bledu transmisji
ret
;==============================================================================
; Master Recaiver
; rejestr Y zawiera adres bufora danych do odebrania
; rejestr r0 zawiera ilosc bajtow do odebrania (NIE liczac adresu scalaka)
; pierwszy bajt danych to adres ukladu scalonego (i kierunek: read)
; W przypadku bledu jest przekazywany przez "temp"
;==============================================================================
TWI_MASTER_READ:
ldi temp, TWI_BR
out TWBR, temp ; Bit Rate
ldi temp, TWI_SR
out TWSR, temp ; preskaler
ldi temp, (1<<TWINT) | (1<<TWSTA) | (1<<TWEN)
out TWCR, temp ; START
TMR_W1: in temp, TWCR
sbrs temp, TWINT
rjmp TMR_W1 ; czekaj na koniec transmisji (flaga TWINT)
in temp, TWSR ; sprawdzenie poprawnosci transmisji
andi temp, 0xF8
cpi temp, TWIS_START
brne TWI_ERROR
ld temp, Y
out TWDR, temp ; adres do wyslania
ldi temp, (1<<TWINT) | (1<<TWEN)
out TWCR, temp ; start transmisji
TMR_W2: in temp, TWCR
sbrs temp, TWINT
rjmp TMR_W2 ; czekaj na koniec transmisji (flaga TWINT)
in temp, TWDR ; dane odczytane (gdy petla po raz pierwszy, to odczyta adres)
st Y+, temp
in temp, TWSR ; sprawdzenie poprawnosci transmisji
andi temp, 0xF8
cpi temp, TWIS_MR_DATA_ACK
brne TMR_E1
rjmp TMR_N
TMR_E1: cpi temp, TWIS_MR_DATA_NOACK
brne TMR_E2
rjmp TMR_STO ; ostatnia dana -> stop
TMR_E2: cpi temp, TWIS_MR_SLA_ACK
brne TWI_ERROR ; BLAD
TMR_N: dec r0 ; zmniejsz licznik
breq TMR_LS ; tak, czyli ostatnia dana do odczytu
ldi temp, (1<<TWINT) | (1<<TWEN) | (1<<TWEA)
out TWCR, temp ; start transmisji
rjmp TMR_W2
TMR_LS: ldi temp, (1<<TWINT) | (1<<TWEN) ; bez potwierdzenia ACK
out TWCR, temp ; start transmisji
rjmp TMR_W2
TMR_STO: ldi temp, (1<<TWINT) | (1<<TWSTO) | (1<<TWEN)
out TWCR, temp ; STOP
clr temp ; brak bledu
ret
.exit
;------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -