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.