Hallo, beschäftige mich heute zum ersten Mal mit dem ATMEL und hab mir die AVR-Tools runter geladen. Hab, bis jetzt (Ausbilding/Studium), immer mit Intel/Infineon Sachen zu tun gehabt. Würde gern ein paar alte Programme zum Laufen bekommen. Mußte aber feststellen, dass das AVR-Programm keine C Dateien unterstütz..ist das richtig? Und für was ist das MAKEFILE? Gruß Bernd.
Hi, das AVRStudio kann von Haus aus kein C. Dafür gibts z.B. WinAVR (basiert auf gcc) oder auch andere kommerzielle Compiler. Ich persönlich finde WinAVR aber ziemlich gut. Das Makefile selber gibt an was denn zum bauen des Projekts notwendig ist -- ich würde es als "Bauanleitung" bezeichnen. Ein ziemlich mächtiges und für größere Sachen imo unverzichtbares Tool.
Okay...vielen Dank! Nun zu meiner nächsten "blöden" Frage... Wollte einfach mal den Timer0 Zählen lassen. Hab mir folgende Zeilen ausgedacht: include "m8def.inc" .device ATMEGA8 .def stunden=r1 .def minuten=r2 .def sekunden=r3 .def hunderst=r4 .def temp=r7 out TCCR0, 0b00000101 ; Vorteiler einstellen ...... okay. Soweit so gut. Beim Umwandeln kommt die Fehlermeldung "error: Invalid Register" Obwohl ich die inlcude-Datei richtig eingebunden ist. Geb ich den Zahlenwert falsch an. In allen Beispielen die ich gefunden habe geht das so. Benutze AVRStudio4. Danke für Eure Hilfe. Gruß Bernd.
in bzw. out geht nicht direkt mit Operand, sondern nur über Register. ldi r16, blabla out TCCR0, r16
Out geht nur über Register. ldi r16,irgendeinbyte out tccr0,r16 Es gibt einen Unterschied zwischen unteren (r0...r15) und oberen (r16...r31) Registern, die unteren können nicht mit Konstanten arbeiten. Vielleicht hilft dir das Datenblatt des AVRs und die Hilfe zum Assembler (Instruction-set) weiter. Oder Beispiele hier im Forum und auch das Tutorial. ...
Hallo... ..vielen Dank! Irgendwie ist das eine totale Umstellung vom Infineon auf den Atmel. Danke schonmal. Bernd.
Hallo, habe endlich meinen ersten Timer + Interrupt auf einem ATMEL zum laufen gebracht. Danke. Nur eine kleine Frage. Meine Programm sieht so aus: ---------------------- .include "m8def.inc" ;Inlcude Datei für ATMEGA8 .device ATMEGA8 ;Angabe des Chips .def temp=r17 .org 0x000 rjmp start .org 0x123 start: ; ldi temp, 1<<TOIE1 ;Timer Interrupte freigeben out TIMSK, temp ldi temp, 0b11111111 ;Timer1H mit Startwert laden out TCNT1H, temp ldi temp, 0b11111110 ;Timer1L mit Startwert laden out TCNT1L, temp ldi temp, 0b0000000 ;Timer1 Vorteiler out TCCR1B, temp ldi temp, 0b0000001 ;Timer1 Vorteiler out TCCR1B, temp sei warte: rjmp warte ;Warte auf Interrupt .org 0X008 inc sekunden ldi temp, 1<<OCF1A ;Timer1 Overflow Flag zurücksetzen out TIFR, temp reti ------------------------------- Nun ist mir aufgefallen, daß beim Interrupt nicht das Overflow Interrupt-Flag TOV1 sondern das Compare Register OCF1A gesetzt wird. Damit der Rücksprung funktioniert setzte ich dieses auch am Ende der IR-Routine zurück. Was bring ich da durcheinander? Danke. Gruß Bernd.
Hi...
Du hast den Stackpointer nicht initialisiert.
Die Int-Vektoren nimmt man meist als Sprungtabelle, da braucht man sich
nicht um die verwendeten Adressen zu kümmern (org) und kann auch mit
mehreren INTs arbeiten.
Beispiel:
.cseg
.org 0 ;Reset- und Interrupt-Vektoren AT-Mega 8
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
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
reti; rjmp TWSI ;Two-wire Serial Interface Handler
reti; rjmp SPM_RDY ;Store Program Memory Ready Handler
.include"LCDprint.inc" ;LCD-Ausgabefunktionen
.include"_LCD_4x27.inc" ;LCD-Treiber-Routinen für LCDs mit 2
HD44780
.include"locate_4x27.inc";Ausgabepositionierung für LCD 4x27 Zeichen
reset:
ldi wl,low(ramend) ;Stackpointer initialisieren
out SPL,wl
ldi wl,high(ramend)
out SPH,wl
;... weitere Initialisierungen...
In der Interrupt-Service-Routine sollte das SREG gesichert werden:
TIM1_COMPA: ;ISR Timer1-Interrupt (alle 10ms)
in srsk,sreg ;SREG sichern (Exklusivregister)
push xh ;benutzte Register
push xl ;sichern
in xl,ocr1al ;Weckzeit
in xh,ocr1ah ;holen,
subi xl,low(-tim1zu) ;Intervall
sbci xh,high(-tim1zu) ;dazu,
out ocr1ah,xh ;und wieder
out ocr1al,xl ;in den Timer
;xl und xh können jetzt innerhalb der ISR frei benutzt werden
Tastenabfrage: ;Entprellroutine, geklaut bei Peter Dannegger...
in zl,tap ;Tastenport einlesen (gedrückt=L)
com zl ;invertieren (gedrückt=H)
eor zl,tas ;nur Änderungen werden H
and tz0,zl ;Prellzähler unveränderter Tasten löschen (Bit0)
and tz1,zl ;Prellzähler unveränderter Tasten löschen (Bit1)
com tz0 ;L-Bit zählen 0,2,->1, 1,3,->0
eor tz1,tz0 ;H-Bit zählen 0,2,->tz1 toggeln
and zl,tz0 ;Änderungen nur dann erhalten, wenn im Prellzähler
and zl,tz1 ;beide Bits gesetzt sind (Zählerstand 3)
eor tas,zl ;erhaltene Änderungen toggeln alten (gültigen)
;Tastenstatus
and zl,tas ;nur (neu) gedrückte Tastenbits bleiben erhalten
or tfl,zl ;und zugehörige Bits setzen
;(gelöscht wird nach Abarbeitung)
;in "tas" steht jetzt der gültige Tastenzustand,
;in "tfl" die Flags der neu gedrückten,
;aber noch nicht abgearbeiteten Tasten...
;zl ist jetzt wieder frei für weitere temporäre Zwecke in der ISR
dec teiler ;Sekundenvorteiler runter
brne nixvollsek ;abgelaufen? nein...
sbr flags,1<<neusek ;ja, Flag setzen,
ldi teiler,teilfaktor ;und Teiler auf Startwert setzen
nixvollsek:
cpi teiler,teilfaktor/2 ;Halbe Sekunde?
brne nixhalbsek ;nein...
sbr flags,1<<neuhalb ;ja, Flag setzen
nixhalbsek:
pop xl ;benutzte Register
pop xh ;wiederherstellen
out sreg,srsk ;SREG wiederherstellen
reti ;fertig...
Die Flags in TIFR werden durch den Aufruf der ISR automatisch zurück
gesetzt. Damit hat der Programmierer nix zu tun. Es werden natürlich
auch die Flags (in TIFR) gesetzt, deren INTs man nicht aktiviert hat
(TIMSK), diese sind aber wirkungslos und brauchen nicht beachtet
werden.
Ich hoffe, ein paar "Stolpersteine" beseitigt zu haben.
...
Und schon ist mir ein Flüchtigkeitsfehler in der ISR aufgefallen: Die Tastenentprellung muss natürlich das Register xl nutzen und nicht zl. Es wundert mich nur, dass das Programm trotzdem funktioniert hat. ...
Hallo... danke schonmal. Das heißt ich brauch das hier: ----------------------- .cseg .org 0 ;Reset- und Interrupt-Vektoren AT-Mega 8 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 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 reti; rjmp TWSI ;Two-wire Serial Interface Handler reti; rjmp SPM_RDY ;Store Program Memory Ready Handler -------------------------------- und in der IR-Routine das hier: -------------------------------- in srsk,sreg ;SREG sichern (Exklusivregister) --------------------------------- Verstehe irgendwie nicht was das soll..aber ich machs mal.. Gruß Bernd.
Das mit der Tabelle hab ich schon verstanden und mit dem Stack auch. Aber wenn ich das Flag nicht lösche springt er mir 2 mal in die IR-Routine.
Wenn du nur einen Int nutzt, geht das auch auf deine Weise. Ich finde die Sprungtabelle aber übersichtlicher. Das IN SRSK,SREG sichert das Statusregister (die Bedingungsflags) im Register SRSK. Am Ende der ISR muss dieses dann wiederhergestellt werden: OUT SREG,SRSK Damit wird erreicht, dass die ISR dem Hauptprogramm nicht die Flags unterm Hintern verstellt. Was aber bedeutend wichtiger ist: Du musst den Stackpointer initialisieren, sonst klappt kein Rücksprung aus ISR oder UP (RETI, RET). ...
Die Flags in TIFR brauchen definitiv nicht per Programm gelöscht werden. Das geschieht automatisch. ...
Hallo! Jetzt weiß ich wo mein Fehler lag!! Da ich den Stackpointer nicht initialisiert hatte ist mein Programm aus der IR-Routine wieder auf 0x000 gesprungen! Okay. Vielen Dank!!! Gruß Bernd.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.