Hallo ihr Lieben,
wie ihr wisst bin ein ich ein absoluter Frischling, was die embedded-Programierung angeht. Im AVR32_Linux_Forum habe ich kurz mein Solarprojekt beschrieben. Hierfür brauche ich dringend ein Kommunikation zwischen dem NGW100 und dem ATmega32L.
Inzwischen läuft der NGW100 als I2C-Master. Aber mit dem ATmega32 habe ich ein großes Probleme. Nach jedem Empfang startet das ASM-Programm neu und ich weiß nicht warum.
Hier der von mir angepasste Quellcode.
Entwicklungsumgebung: AVR Studio 4
Target: AVR-Dragon
meine Fragen hierzu:
1. Ist m32def.inc das richtige Include?
2. Was wird mit ".cseg" und ".org 0" erreicht?
3. Wieso steht die Interrupt-Vector-Tabelle hinter dem RESET?
4. Wer bestimmt die Reihenfolge der Interrupt-Vectoren?
5. In den Fuses kann ich den internen Oszillator auf 8 MHz einstellen.
Was bedeudet &CK +0, +4 und +8 ms?
6. In der TWI-Beschreibung des atmel steht, dass die internen pullup-Widerstände für SDA und SCL mittels PORTCn eingeschaltet werden könne. Habe ich das mit "out PORTC, 6" getan?
7. Warum landet das Programm nach jedem korrekten Empfang eines einzelnen Bytes wieder beim RESET???
wie ihr wisst bin ein ich ein absoluter Frischling, was die embedded-Programierung angeht. Im AVR32_Linux_Forum habe ich kurz mein Solarprojekt beschrieben. Hierfür brauche ich dringend ein Kommunikation zwischen dem NGW100 und dem ATmega32L.
Inzwischen läuft der NGW100 als I2C-Master. Aber mit dem ATmega32 habe ich ein großes Probleme. Nach jedem Empfang startet das ASM-Programm neu und ich weiß nicht warum.
Hier der von mir angepasste Quellcode.
Code:
; TWI I2C SLAVE
; 10/2005
; Bernhard.Erfurt@gmx.de
; Adaption 2009/03 Michael Hößel
; TAKT=8.0 MHZ
;
.include "m32def.inc"
; TWI Slave Receiver Codes
.equ TW_SR_SLA_ACK = 0x60; x60 01100000 (SLA+W wurde empfangen-ACK wurde zurückgesendet)
.equ TW_SR_ARB_LOST_SLA_ACK = 0x68; x68 01101000 (Arbitration verloren in SLA+R/W als MASTER; SLA+W wurde empfangen; ACK wurde zurückgesendet
.equ TW_SR_GCALL_ACK = 0x70; x70 01110000 (General call address wurde empfangen; ACK wurde zurückgesendet
.equ TW_SR_ARB_LOST_GCALL_ACK=0x78; x78 01111000 (Arbitration verloren in SLA+R/W als MASTER;General call address wurde empfangen; ACK wurde zurückgesendet
.equ TW_SR_DATA_ACK = 0x80; x80 10000000 (die vorher adressierten (SLA+W) Daten wurden empfangen; ACK wurde zurückgesendet
.equ TW_SR_DATA_NACK = 0x88; x88 10001000 (die vorher adressierten (SLA+W) Daten wurden empfangen; ACK wurde nicht zurückgesedet
.equ TW_SR_GCALL_DATA_ACK = 0x90; x90 10010000 (die vorher adressierten (General call) Daten wurden empfangen; ACK wurde zurückgesendet
.equ TW_SR_GCALL_DATA_NACK = 0x98; x98 10011000 (die vorher adressierten (General call) Daten wurden empfangen; ACK wurde nicht zurückgesendet
.equ TW_SR_STOP = 0xA0; xA0 10100000 (STOP wurde empfangen, oder wiederholter Start)
; TWI Slave Transmitter Codes
.equ TW_ST_SLA_ACK = 0xA8; xA8 10101000 (SLA+R wurde empfangen; ACK wurde zurückgesendet)
.equ TW_ST_ARB_LOST_SLA_ACK = 0xB0; xB0 10110000 (Arbitration verlor SLA+R/W als MASTER, ACK wurde zurückgesendet)
.equ TW_ST_DATA_ACK = 0xB8; xB8 10111000 (TWDR ist übertragen worden; ACK ist empfangen worden
.equ TW_ST_DATA_NACK = 0xC0; xC0 11000000 (TWDR ist übertragen worden; ACK ist NICHT empfangen worden
.equ TW_ST_LAST_DATA = 0xC8; xC8 11001000 (Letztes Datenbyte in TWDR ist übertragen worden (TWEA = "0"); Ack ist empfangen worden
.equ TW_NO_INFO = 0xF8; xF8 11111000 (Keine relevanten Zustandinformationen vorhanden; TWINT = "0" keine TWDR-Tätigkeit
.equ TW_BUS_ERROR = 0x00; x00 00000000 (Bus-Error wegen ungültige STARToder STOP BEDIgung; keine TWDR-Tätigkeit
; TWI SLAVE EINSTELLUNGEN
.equ TWI_SLAVE_ADRESSE = 77 ; eigene SLAVE ADRESSE 1...127
.equ TWI_GENERAL_CALL_enable= 0 ; 1=Generral Call enabled / 0=disabled
; REGISTER
.def DATA=R15
.def TEMP = R16
.def TEMP1= R17
.def TEMP2= R18
.def TEMP3= R19
.def TEMP4= R20
.cseg ;Beginn eines Code-Segmentes
.org 0 ;Startadresse=0
rjmp RESET ; Reset Handler
reti ;rjmp EXT_INT0 ; IRQ0 Handler
reti ;rjmp EXT_INT1 ; IRQ1 Handler
reti ;rjmp TIM2_COMP ; Timer2 Compare Handler
reti ;rjmp TIM2_OVF ; Timer2 Overflow Handler
reti ;rjmp TIM1_CAPT ; Timer1 Capture Handler
reti ;rjmp TIM1_COMPA ; Timer1 CompareA Handler
reti ;rjmp TIM1_COMPB ; Timer1 CompareB Handler
reti ;rjmp TIM1_OVF ; Timer1 Overflow Handler
reti ;rjmp TIM0_OVF ; Timer0 Overflow Handler
reti ;rjmp SPI_STC ; SPI Transfer Complete Handler
reti ;rjmp USART_RXC ; USART RX Complete Handler
reti ;rjmp USART_UDRE ; UDR Empty Handler
reti ;rjmp USART_TXC ; USART TX Complete Handler
reti ;rjmp ADC ; ADC Conversion Complete Handler
reti ;rjmp EE_RDY ; EEPROM Ready Handler
reti ;rjmp ANA_COMP ; Analog Comparator Handler
rjmp TWSI ; Two-wire Serial Interface Handler
reti ;rjmp SPM_RDY ; Store Program Memory Ready Handler
RESET:
;STACK initialisieren
ldi temp, LOW(RAMEND)
out SPL, temp
ldi temp, HIGH(RAMEND)
out SPH, temp
; PORT B + D alles AUSGÄNGE
ldi temp, 0b11111111
out DDRB, temp
out PORTB,temp
out DDRD, temp
out PORTD,temp
; PORT C alles EINGÄNGE
clr TEMP
out DDRC,temp
ldi temp, 6
out PORTC,temp
; TWI INITIALISIERUNG
rcall TWI_INI
; STARTWERTE
clr DATA
; alle Interrupts freigeben
sei
LOOP:
rjmp LOOP
; #############################################################################
; #############################################################################
; #############################################################################
; TWI INTERRUPPT-Routine
TWSI:
push temp ; temp auf dem Stack sichern
in TEMP,SREG ; Einlesen des SREG
push TEMP ; Schreiben von SREG im Stack (KOPIE)
;-------
in temp, TWSR ; Status-Register abfragen
andi temp, 0xF8 ; Bit0...2 ausblenden (Prescaler und Reserve-Bit)
cpi temp, TW_SR_SLA_ACK ; x60
breq TWSI_TW_SR_SLA_ACK
cpi temp, TW_SR_DATA_ACK ; x80
breq TWSI_TW_SR_DATA_ACK
cpi temp, TW_SR_ARB_LOST_SLA_ACK ; x68
breq TWSI_TW_SR_ARB_LOST_SLA_ACK
cpi temp, TW_SR_GCALL_ACK ; x70
breq TWSI_TW_SR_GCALL_ACK
cpi temp, TW_SR_ARB_LOST_GCALL_ACK ; x78
breq TWSI_TW_SR_ARB_LOST_GCALL_ACK
cpi temp, TW_SR_DATA_NACK ; x88
breq TWSI_TW_SR_DATA_NACK
cpi temp, TW_SR_GCALL_DATA_ACK ; x90
breq TWSI_TW_SR_GCALL_DATA_ACK
cpi temp, TW_SR_GCALL_DATA_NACK ; x98
breq TWSI_TW_SR_GCALL_DATA_NACK
cpi temp, TW_SR_STOP ; xA0
breq TWSI_TW_SR_STOP
;
cpi temp, TW_ST_SLA_ACK ; 0xA8
breq TWSI_TW_ST_SLA_ACK
cpi temp, TW_ST_ARB_LOST_SLA_ACK ; 0xB0
breq TWSI_TW_ST_ARB_LOST_SLA_ACK
cpi temp, TW_ST_DATA_ACK ; 0xB8
breq TWSI_TW_ST_DATA_ACK
cpi temp, TW_ST_DATA_NACK ; 0xC0
breq TWSI_TW_ST_DATA_NACK
cpi temp, TW_ST_LAST_DATA ; 0xC8
breq TWSI_TW_ST_LAST_DATA
cpi temp, TW_NO_INFO ; 0xF8
breq TWSI_TW_NO_INFO
cpi temp, TW_BUS_ERROR ; 0x00
breq TWSI_TW_BUS_ERROR
rjmp TWSI_TW_BUS_ERROR ; nicht behandelte Status-Zustände
; SLAVE RECEIVER
TWSI_TW_SR_SLA_ACK: ; x60 01100000 (SLA+W wurde empfangen-ACK wurde zurückgesendet)
;ldi temp, 255
;out PORTB,temp ; LED's alle aus
;cbi PORTB,0
rjmp TWSI_w
TWSI_TW_SR_ARB_LOST_SLA_ACK: ; x68 01101000 (Arbitration verloren in SLA+R/W als MASTER; SLA+W wurde empfangen; ACK wurde zurückgesendet
;cbi PORTB,1
rjmp TWSI_w
TWSI_TW_SR_GCALL_ACK: ; x70 01110000 (General call address wurde empfangen; ACK wurde zurückgesendet
;cbi PORTB,2
rjmp TWSI_w
TWSI_TW_SR_ARB_LOST_GCALL_ACK: ; x78 01111000 (Arbitration verloren in SLA+R/W als MASTER;General call address wurde empfangen; ACK wurde zurückgesendet
;cbi PORTB,3
rjmp TWSI_w
TWSI_TW_SR_DATA_ACK: ; x80 10000000 (die vorher adressierten (SLA+W) Daten wurden empfangen; ACK wurde zurückgesendet
;cbi PORTB,4
in DATA, TWDR ; DATA
out PORTB,DATA
rjmp TWSI_w
TWSI_TW_SR_DATA_NACK: ; x88 10001000 (die vorher adressierten (SLA+W) Daten wurden empfangen; ACK wurde nicht zurückgesedet
;cbi PORTB,5
rjmp TWSI_w
TWSI_TW_SR_GCALL_DATA_ACK: ; x90 10010000 (die vorher adressierten (General call) Daten wurden empfangen; ACK wurde zurückgesendet
;cbi PORTB,6
rjmp TWSI_w
TWSI_TW_SR_GCALL_DATA_NACK: ; x98 10011000 (die vorher adressierten (General call) Daten wurden empfangen; ACK wurde nicht zurückgesendet
;cbi PORTB,7
rjmp TWSI_w
TWSI_TW_SR_STOP: ; xA0 10100000 (STOP wurde empfangen, oder wiederholter Start)
;cbi PORTB,7
rjmp TWSI_w
; SLAVE TRANSMITTER
TWSI_TW_ST_SLA_ACK: ; xA8 10101000 (SLA+R wurde empfangen; ACK wurde zurückgesendet)
;ldi temp,255
;out PORTB,temp ; LEDs alle aus
;cbi PORTB,0
OUT TWDR, DATA ; DATA
rjmp TWSI_w
TWSI_TW_ST_ARB_LOST_SLA_ACK: ; xB0 10110000 (Arbitration verlor SLA+R/W als MASTER, ACK wurde zurückgesendet)
;cbi PORTB,1
rjmp TWSI_w
TWSI_TW_ST_DATA_ACK: ; xB8 10111000 (TWDR ist übertragen worden; ACK ist empfangen worden
;cbi PORTB,2
OUT TWDR, DATA ; DATA
rjmp TWSI_w
TWSI_TW_ST_DATA_NACK: ; xC0 11000000 (TWDR ist übertragen worden; ACK ist NICHT empfangen worden
;cbi PORTB,3
OUT TWDR, DATA ; DATA
rjmp TWSI_w
TWSI_TW_ST_LAST_DATA: ; xC8 11001000 (Letztes Datenbyte in TWDR ist übertragen worden (TWEA = "0"); Ack ist empfangen worden
;cbi PORTB,4
rjmp TWSI_w
TWSI_TW_NO_INFO: ; xF8 11111000 (Keine relevanten Zustandinformationen vorhanden; TWINT = "0" keine TWDR-Tätigkeit
;cbi PORTB,5
rjmp TWSI_w
TWSI_TW_BUS_ERROR: ; x00 00000000 (Bus-Error wegen ungültige STARToder STOP BEDIgung; keine TWDR-Tätigkeit
rcall TWI_ERROR
;rjmp TWSI_w
;-------
TWSI_w:
; rcall wait_1s ; diese Warteschleife ist nicht nötig, kann entfernd werden
;das TWINT-Flag löschen ((logisch 1)
ldi temp, 1<<TWINT|1<<TWEA|1<<TWEN|1<<TWIE
; ldi temp, 1<<TWINT|1<<TWEN
out TWCR,temp
;-------
pop TEMP ; LESEN von SREG vom STACK (KOPIE)
out SREG,TEMP ; Wiederherstellen von SREG
pop temp ; temp wiederherstellen
reti
; #############################################################################
; #############################################################################
; #############################################################################
TWI_INI:
; TWI TWAR (nur SLAVE) Adress-Register
ldi temp,(TWI_SLAVE_ADRESSE<<TWA0 | TWI_GENERAL_CALL_ENABLE<<TWGCE)
out TWAR,temp
; TWI TWCR Control-REGISTER
ldi temp, 1<<TWINT|1<<TWEA|0<<TWSTA|0<<TWSTO|0<<TWWC|1<<TWEN|1<<TWIE
out TWCR,temp
; Teiler wird 1
ldi temp,1
out TWBR,temp
ret
; #############################################################################
; #############################################################################
; #############################################################################
TWI_ERROR:
cbi PORTD,0
; TWI STOP
ldi r16, (1<<TWINT)|(1<<TWEN)|(1<<TWSTO)
out TWCR, r16
; TWI aus
ldi r16, (0<<TWEN)
out TWCR, r16
; TWI INITIALISIERUNG
rcall TWI_INI
rcall wait_1s
sbi PORTD,0
ret
; #############################################################################
; #############################################################################
; #############################################################################
; Wait for TWINT Flag set.
TWI_TWINT_wait:
in temp, TWCR
sbrs temp, TWINT
rjmp TWI_TWINT_wait
ret
; #############################################################################
; #############################################################################
; #############################################################################
WAIT_1s:
push temp1 ; temp1 auf dem Stack sichern
push temp2 ; temp2 auf dem Stack sichern
push temp3 ; temp3 auf dem Stack sichern
;------------
ldi temp3,5
clr temp2
clr temp1
wait1s_w:
dec temp1
brne wait1s_w
dec temp2
brne wait1s_w
dec temp3
brne wait1s_w
;------------
pop temp3 ; temp3 wiederherstellen
pop temp2 ; temp2 wiederherstellen
pop temp1 ; temp1 wiederherstellen
ret
Target: AVR-Dragon
meine Fragen hierzu:
1. Ist m32def.inc das richtige Include?
2. Was wird mit ".cseg" und ".org 0" erreicht?
3. Wieso steht die Interrupt-Vector-Tabelle hinter dem RESET?
4. Wer bestimmt die Reihenfolge der Interrupt-Vectoren?
5. In den Fuses kann ich den internen Oszillator auf 8 MHz einstellen.
Was bedeudet &CK +0, +4 und +8 ms?
6. In der TWI-Beschreibung des atmel steht, dass die internen pullup-Widerstände für SDA und SCL mittels PORTCn eingeschaltet werden könne. Habe ich das mit "out PORTC, 6" getan?
7. Warum landet das Programm nach jedem korrekten Empfang eines einzelnen Bytes wieder beim RESET???