PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : ATMEGA16 IIC Fehler beim Compilen



Eric79
14.06.2005, 09:57
Hi,
und zwar will ich etwas mit dem IIC Bus des ATmega16 machen.
z.B. serielles EEprom oder eine RTC ansteuern.
Dazu habe ich mit eine routine aus dem Datenblatt geholt:




.include "m16def.inc"

.ORG 0x00
JMP RESET ; Reset Handler
.ORG 0x02
JMP UNUSED ; IRQ0 Handler
.ORG 0x04
JMP UNUSED ; IRQ1 Handler
.ORG 0x06
JMP UNUSED ; Timer2 Compare Handler
.ORG 0x08
JMP UNUSED ; Timer2 Overflow Handler
.ORG 0x0A
JMP UNUSED ; Timer1 Capture Handler
.ORG 0x0C
JMP UNUSED ; Timer1 CompareA Handler
.ORG 0x0E
JMP UNUSED ; Timer1 CompareB Handler
.ORG 0x10
JMP UNUSED ; Timer1 Overflow Handler
.ORG 0x12
JMP UNUSED ; Timer0 Overflow Handler
.ORG 0x14
JMP UNUSED ; Serial Transfer Complete Handler
.ORG 0x16
JMP UNUSED ; USART0 RX Complete Handler
.ORG 0x18
JMP UNUSED ; USART0,UDR Empty Handler
.ORG 0x1A
JMP UNUSED ; USART0 TX Complete Handler
.ORG 0x1C
JMP UNUSED ; ADC Conversion Complete Handler
.ORG 0x1E
JMP UNUSED ; EEPROM Ready Handler
.ORG 0x20
JMP UNUSED ; Analog Comparator Handler
.ORG 0x22
JMP UNUSED ; TWI Handler
.ORG 0x24
JMP UNUSED ; IRQ2 Handler
.ORG 0x26
JMP UNUSED ; Timer0 Compare Handler
.ORG 0x28
JMP UNUSED ; SPM Ready Handler

UNUSED:
ret

RESET:

ldi r16,high (Ramend)
out sph,r16
ldi r16,low (Ramend)
out spl,r16
sei

.def SLA_W = r20
.def MT_SLA_ACK = r17
.def MT_DATA_ACK = r18
.def DATA = r19
.def START = r21

Main:

ldi r16, (1<<TWINT)|(1<<TWSTA)|(1<<TWEN) ; Send START condition
out TWCR, r16

wait1: ; Wait for TWINT Flag set.
in r16,TWCR ; This indicates that the
sbrs r16,TWINT ; START condition has been
rjmp wait1 ; transmitted

in r16,TWSR ; Check value of TWI Status Register.
andi r16, 0xF8 ; Mask prescaler bits.
cpi r16, START ; If status different from
brne ERROR ; START go to ERROR

ldi r16, SLA_W ; Load SLA_W into TWDR
out TWDR, r16 ; Register. Clear TWINT bit in
ldi r16, (1<<TWINT) | (1<<TWEN) ; TWCR to start
out TWCR, r16 ; transmission of address

wait2: ; Wait for TWINT Flag set.
in r16,TWCR ; This indicates that the
sbrs r16,TWINT ; SLA+W has been transmitted,
rjmp wait2 ; and ACK/NACK has been received.

in r16,TWSR ; Check value of TWI Status
andi r16, 0xF8 ; Register. Mask prescaler bits.
cpi r16, MT_SLA_ACK ; If status different from
brne ERROR ; MT_SLA_ACK go to ERROR

ldi r16, DATA ; Load DATA into TWDR Register.
out TWDR, r16 ; Clear TWINT bit in TWCR
ldi r16, (1<<TWINT) | (1<<TWEN) ; to start transmission
out TWCR, r16 ; of data

wait3: ; Wait for TWINT Flag set.
in r16,TWCR ; This indicates that the DATA
sbrs r16,TWINT ; has been transmitted, and
rjmp wait3 ; ACK/NACK has been received.

in r16,TWSR ; Check value of TWI Status
andi r16, 0xF8 ; Register. Mask prescaler bits.
cpi r16, MT_DATA_ACK ; If status different from
brne ERROR ; MT_DATA_ACK go to ERROR

ldi r16, (1<<TWINT)|(1<<TWEN)|(1<<TWSTO) ; Transmit STOPcondition
out TWCR, r16

rjmp Main


ERROR:
rjmp Error




Gut mir ist klar,daß noch so sachen wie eine fehlerroutine,usw fehlen.
Trotzdem sollte ich den Code schon compilen können.
Nur leider bringt mein AVR Studio Fehlermeldungen.
Siehe anhang.

Hat jemand eine Idee woher der Fehler kommen könnte?

Hier habe ich auch noch ein Problem für das ich bis jetzt auch keine Lösung gefunden habe:
https://www.roboternetz.de/phpBB2/viewtopic.php?t=9972 !

Hat vielleicht schon jemand in ASM einen fertigen Quellcode für eine IIC routine, oder weiss vielleicht eine Seite wo man die her bekommt?

Gruß und danke schonmal

Eric79
14.06.2005, 10:55
Ok hab den Fehler schon gefunden.
muß man so machen:



.equ Start = ?
.equ SLA_W = ? ( Wahrscheinlich das Adressbyte )
.equ MT_SLA_ACK = ?
.equ DATA = ? ( Datenbyte )
.equ MT_DATA_ACK = ?


jetzt muß ich nur noch herausfinden was die Konstanten für einen
Wert haben.
aber vielleicht hat hier ja jemand eine idee.

Gruß

Eric79
14.06.2005, 13:32
So, noch eine Frage:

Wie errechnet sich laut der Formel die Fscl?

Fscl = CPU Clock frequency/ 16 +2 (TWBR) * 4 hoch TWPS

4 hoch TWPS * TWBR * 2 = x

dann CPU Clock frequency / x

liege ich da richtig?

Eric79
14.06.2005, 20:03
So,
in der oben genannten I2C routine vom Datenblatt fehlt doch was oder?

ich habe vor das AT24C02 EEPROM von Atmel zu verwenden.
http://www.atmel.com/dyn/resources/prod_documents/doc0180.pdf

um daten ins EEPROM zu schreiben muß ich doch ihm mitteilen das er gemeint ist.

(The device address word consists of a mandatory one, zero sequence for the first four most significant bits as shown. This is common to all the EEPROM devices. The next 3 bits are the A2, A1 and A0 device address bits for the 1K/2K EEPROM.These 3 bits must compare to their corresponding hard-wired input pins.)

das mach ich mit den A2,A1,A0 bits.
nehmen wir an ich leg alle auf masse, dann schaut das adress Byte doch so aus: 0b1010000&1->für write.

dann brauch ich ja aber noch eine adresse für das datenbyte!
und das fehlt doch in der Routine oder?

wie und wo füge ich das in meine routine ein?
gruß