Problem z zapisem do eepromu pod Atmega8

To forum jest dla wszystkich pasjonatów mikrokontrolerów AVR Atmela. Wymiana doświadczeń i pomoc dla początkujących w pisaniu programów zarówno w C, Asemblerze jak i BASCOM. Zapraszam znawców tematu, aby pomogli wszystkim początkującym!
ODPOWIEDZ
y0yster
-
Posty: 15
Rejestracja: 04 lut 2007, 14:17
Lokalizacja: Nysa
Kontakt:

Problem z zapisem do eepromu pod Atmega8

Post autor: y0yster » 03 lis 2007, 16:47

Witam,

Od niedawna mam mały problem z zapisem do eepromu typu 24c64. Odczyt działa mi elegancko, ale z zapisem mam już mały kłopot. Próbowałem różnych podejść do sprawy, ale wszystko poszło na marne. Najlepiej zobrazuje to kod programu:

Proszę o pomoc, bo już nie mam co wymyślić.

O co tak na prawdę mi chodzi. Po wysłaniu porcji danych (jednego bajtu) powinienem otrzymać od eepromu potwierdzenie ACK. W dokumentacji Atmega8 zobaczyłem, że powinienem otrzymać kod od interfejsu 0x28, a otrzymuję 0x20. Wygląda na to, że wysyłam jeszcze raz SLA+W, a to nie prawda.


Kod główny programu:

Kod: Zaznacz cały

.INCLUDE "m8def.inc"

;makra

.MACRO twi_check_error
	;przesowamy w prawo o 2 miejsca, aby nie brac pod uwage prescalera
	in TWI_REGISTER, TWSR
	cbr TWI_REGISTER, (1 << TWPS1) | (1 << TWPS0)
	cpi TWI_REGISTER, @0
	brne twi_error
.ENDMACRO

.dseg
	.def TWI_REGISTER = r25

.cseg
.org 0x000
rjmp	reset

reset:

LDI R16, HIGH( RAMEND)
OUT SPH, R16
LDI R16, LOW( RAMEND)
OUT SPL, R16

clr r16
ldi r16, (1 << TWPS0)
out TWSR, r16
ldi r16, 20
out TWBR, R16

sbi PORTC, PC5
sbi PORTC, PC4

rcall twi_start
;error ?
twi_check_error 0x08

;adres urzadzenia + zapis
ldi TWI_REGISTER, 0x50 << 1 ; + 0
rcall twi_send_data
;error ?
twi_check_error 0x18

;msb
ldi TWI_REGISTER, 0x00
rcall twi_send_data
;error ?
twi_check_error 0x28

;lsb
ldi TWI_REGISTER, 0x00
rcall twi_send_data
;error ?
twi_check_error 0x28

ldi r17, 0x00

zapis:

;zapisujemy bajt
ldi TWI_REGISTER, 0x61
rcall twi_send_data
twi_check_error 0x28

inc r17

cpi r17, 20
brne zapis

rcall twi_stop

;zapetlamy
petla:
	rjmp petla

;blad na interfejsie twi
twi_error:
	mov EEPROM_DATA, TWI_REGISTER
	rcall write_to_eeprom
	rjmp petla

.INCLUDE "..\biblioteki\twi.inc"
Kod biblioteki do wbudowanego interfejsu TWI w Atmega8:

Kod: Zaznacz cały

;wysylamy dane
twi_send_data:
	;zapis danych
	out TWDR, TWI_REGISTER

	ldi TWI_REGISTER, (1 << TWINT) | (1 << TWEN) | (1 << TWEA)
	;wysylamy dane na zlacze
	out TWCR, TWI_REGISTER

	rcall twi_busy

	;konczymy wysylanie danych
	ret

;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

;operacja odcytywania bajtu
twi_read_data:
	;dajemy sygnal do odczytu
	ldi TWI_REGISTER, (1 << TWINT) | (1 << TWEN) | (1 << TWEA)
	out TWCR, TWI_REGISTER
	
	rcall twi_busy
		
	;odczytujemy dane
	in TWI_REGISTER, TWDR
			
	ret

;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

;wysylanie STARTU
twi_start:
	ldi TWI_REGISTER, (1 << TWINT) | (1 << TWSTA) | (1 << TWEN) | (1 << TWEA)
	out TWCR, TWI_REGISTER

	rcall twi_busy

	ldi TWI_REGISTER, (0 << TWINT) | (0 << TWSTA) | (1 << TWEN) | (1 << TWEA)
	out TWCR, TWI_REGISTER
	
	;koniec, powracamy
	ret

;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

twi_stop:
	ldi TWI_REGISTER, (1 << TWSTO) | (1 << TWEN) | (1 << TWINT)
	;wysylamy nasze ustawienia
	out TWCR, TWI_REGISTER
	
	;wylaczamy interfejs twi
	ldi TWI_REGISTER, 0 << TWEN
	out TWCR, TWI_REGISTER
	
	;wyslano stop, powracamy do programy		
	ret

;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

;sprawdznaie czy interfejs TWI jest zajety
twi_busy:
	;wczytanie rejestru kontrolnego
	in TWI_REGISTER, TWCR
	;porownanie bitu przerwania TWINT, jesli 1
	sbrs TWI_REGISTER, TWINT
	;to omijamy skok do ponownego sprawdzenia
	rjmp twi_busy

	;powrot
	ret


[ Dodano: 2007-11-14, 20:11 ]
Czy mógłby mi ktoś pomóc z problemem?
Na internecie nie znalazłem przykładu w asemblerze do obsługi sprzętowego eepromu. :(

ODPOWIEDZ