...bler programmierung.Unten hängt mein erstes unfertiges
Assemblerprogramm, was mal die Software für ein geplantes Testgerätchen
geben soll. Es ist bisher nur ein Fragment ohne Sinnvolle Funktion...
Kritik an meinem Programmierstil und Hinweise auf Fehler sind von mir
ausdrücklich gewünscht!
Mein wichtigstes Problem ist allerdings, dass der Atmel zwar in PWR-Down
geht, ich ihn aber nicht mit high-low wechsel (Int 0,1) wachbekomme.
Was mache ich falsch??
Ich hänge mit dem Problem schon Tage fest.
Ich wäre Dankbar, wenn sich jemand die Mühe machen würde, das mal kurz
zu analysieren.
Gruß Philipp
Die Progzeilen:
.org 0x000
rjmp RESET ; Reset Handler
rjmp EXINT_0 ; IRQ0 Handler
rjmp EXINT_1 ; IRQ1 Handler
reti ;TIM1_CAPT ; Timer1 Capture Handler
rjmp TIM1_COMP ; Timer1 compare Handler
reti ;TIM1_OVF ; Timer1 Overflow Handler
rjmp TIM0_OVF ; Timer0 Overflow Handler
reti ;SPI_STC ; SPI Transfer Complete Handler
reti ;UART_RXC ; UART RX Complete Handler
reti ;UART_DRE ; UDR Empty Handler
reti ;UART_TXC ; UART TX Complete Handler
reti ;ADC ; ADC Conversion Complete Interrupt
Handler
reti ;EE_RDY ; EEPROM Ready Handler
reti ;ANA_COMP ; Analog Comparator Handler
.org 0x011
RESET:
;-------------PORTCONFIG------------
ldi temp, RAMEND ; Stackpointer nie vergessen!
out SP, temp
ldi temp, 0xFF ;portD als Ausgang konfigurieren
out DDRD, temp
ldi temp, 0xFF ;portB als Ausgang konfigurieren
out DDRB, temp
;--------------Timer 1 config------------
ldi temp, 0b01000010 ;Compare match T1,overflow T0
out TIMSK, temp
ldi temp, 0b00000000
out TCCR1A, temp ;kein Asgang, PWM off
ldi temp, 0b00001100 ;b3 comare match, b2-0 CLK/256 *****
out TCCR1B, temp
;--------------Timer 0 config------------
ldi temp, 0b00000101 ;Timer0 CK/1024 *****
out TCCR0,temp
;------------Werte füt T1----------------
ldi temp, 0b00000011 ; *****
out OCR1H, temp ;höherwertiges Vrgleichsbyte
ldi temp, 156; *****
out OCR1L, temp ;niederwertiges Vergleichsbyte
;-------------- Sleepconfig ------------
ldi temp, 0b00111111 ;Sleep enable, Sleep Mode PWRDN, int 0, 1 1-0
Flanke
out MCUCR, temp
ldi temp, 0x8f ;Wert für 20 sec. *****
mov offreg, temp
ldi temp, 0b11000000 ;INT 0,1 aktivieren
out GIMSK, temp
ldi temp, 0b10000000 ;Interupt enable
out SREG, temp
sei
hloop:
ldi temp, 0xFF ;portD als Ausgang konfigurieren
out DDRD, temp
;_____________Hauptschleife________________
lloop: rjmp lloop ;Endlosschleife
___________Sprungziele__________________
offdir:
ldi temp, 0b11111111 ;LED's abschalten
out PORTD, temp
out PORTB, temp
sei
sleep
ldi temp, 0x00
out PORTB, temp
ldi temp, 0b10000000 ;Interupt enable
out SREG, temp
rjmp RESET
;______________Exint handler___________________
EXINT_0:
ldi temp, 0b11111111 ;LED's abschalten
out PORTB, temp
reti
EXINT_1:
;ldi temp, 0b10000000 ;Interupt enable
;out SREG, temp
;rjmp RESET
ldi temp, 0b11111111 ;LED's abschalten
out PORTB, temp
reti
;_____________Timerhandler___________________
TIM0_OVF:
subi offreg, 0x01 ;offreg -1
cpi offreg, 0x00
breq offdir ;springe, wenn >/= 1 zu offdir
reti
TIM1_COMP:
sbic portd,7 ;springe ü n. bef. wenn pind7=0
rjmp aus
sbi portd,7 ;pind7=1
reti
aus: cbi portd,7 ;pind7=0
reti
Philip, Auszug aus dem 4433-Datenblatt, Seite 31, Power Down Mode: Only an External Reset, a Watchdog Reset (if enabled) or an external level interrupt can wake up the MCU. Die Betonung liegt auf "level", heißt, deine H-L transition sollte eine sicherlich mit Hilfe des Datenblattes näher zu definierende Minimaldauer auf L verweilen. hth -uwe
danke für den Tipp, habe mittlerweile herausgefunden wie es geht. Die Minimaldauer kann ich mit handbetätigten Tasern nicht unterschreiten..;-) Problem scheint es zu sein, dass ich ein und ausgaben auf PortD habe, obwohl ich die Datenrichtungsregister nach aller Kunst maltretiert habe. Wenn ich meine Ausgabe auf PortC oder B lege, geht alles. Aller Anfang scheint gerade beim Assemblerprogrammieren schwer zu sein. Ich denke, man muss sich einfach durchbeissen und herumprobieren. Das kostet halt Zeit ohne Ende.....*gähn* Genauer lesen sollte ich vielleicht auch noch lernen, ist aber auch ein sehr verschachtelte Logik im Datenblatt. Viele Grüsse Philipp (der nicht geschlafen hat*G*)
PhilipP, du hast latürnich Recht, so schnell, die Minimaldauer zu unterschreiten, ist kein Finger, aber vielleicht 'n prellender Taster? Wie auch immer: mit deiner PORTD Klamotte triffst Du wahrscheinlich in's Schwarze. Ich bin mir zwar nicht ganz sicher, aber ich denke, die Interruptpins gleichzeitig als Ausgang zu verwenden, gehört nicht zu den leicht zu durchschauenden Sachen. Du treibst, bevor du in den Schlaf fällst, 'ne 1 an den INT-Pins raus, das heißt, deine Tastermimik muß niederohmig genug sein, diese aktive "1" niederzubügeln, damit der Prozessor den Interrupt erkennt. Brauchst Du den verwendeten Interrupt-Pin wirklich als Ausgang??? groetjes und ... schlaf mal wieder :) -uwe
Jep, du solltest nicht nur immer deinen AVR sondern auch mal dich selbst schlafen schicken. ;o) Ist als freundlicher Rat gemeint und bestimmt nicht böse gemeint!
Hi!
Betrifft Schreibstiel:
ldi temp, 0xFF ;portD als Ausgang konfigurieren
out DDRD, temp
ldi temp, 0xFF ;portB als Ausgang konfigurieren
out DDRB, temp
Wenn temp einmal einen Wert hat geht er nicht verloren.
ldi temp, 0xFF ;portD als Ausgang konfigurieren
out DDRD, temp
out DDRB, temp ;portB als Ausgang konfigurieren
macht dasselbe,aber 1 Wort gespart
ldi temp, 0b10000000 ;Interupt enable
out SREG, temp
sei
warum 2 x sei ist doch I-Bit auf 1, die oberen 2 Zeilen sind also
unsinnig.(Schaden macht es aber auch keinen)
TIM0_OVF:
subi offreg, 0x01 ;offreg -1
cpi offreg, 0x00
breq offdir ;springe, wenn >/= 1 zu offdir
reti
wenn offreg null erreicht, wird Z-Flag automatisch gesetzt
cpi offreg, 0x00
kann also entfallen
breq offdir ;springe, wenn >/= 1 zu offdir
reti
offdir ist eine andere SUB in der du Int.global freigibst.
Das ist sehr gefährlich im Bezug auf den Stack, kann sein dein Proz.tut
auf einmal nicht mehr wie er soll!
EXINT_0:
ldi temp, 0b11111111 ;LED's abschalten
out PORTB, temp
reti
EXINT_1:
;ldi temp, 0b10000000 ;Interupt enable
;out SREG, temp
;rjmp RESET
ldi temp, 0b11111111 ;LED's abschalten
out PORTB, temp
reti
wenn die beiden Int. dasselbe ausführen sollen(glaube ich aber
eigentlich nicht) kannst du in der Interrupttabelle
(org 0x00)auch die selbe Sprungmarke angeben (zb.EXINT_0)
wenn offreg >R15 , kannst du offreg direkt laden(ohne mov)
Ansonsten gut zu lesen. Weiter so!
Gruss Uwe
Hallo Uwe, vielen Dank für Deine Vorschläge und Hinweise. Sie sind mir sehr hilfreich. Insbesondere die Sache mit einem Sprungziel nach einem Int, welches vom Stack aus nicht mehr nachzuvollziehen ist, hätte ich nicht als Problematisch angesehen, da das Prog bisher läuft. Wenn's dann irgendwann im weiteren Code "knallt", weiss man nicht mehr wo der Bug sitzt... Wenn Du willst, kann ich im fortgeschrittenen Stadium nochmal vorzeigen. Im Moment bin ich noch ein wenig am tüfteln, wo und wie meine drei Ein und 14 Ausgänge liegen sollen... Wo gibt's die Atmel's eigentlich am günstigsten? Die SMD-Versionen sind ein wenig "anspruchsvoll" beim Anschluss auf einem Steckbrett G Ich sollte mir mal welche in DIP besorgen. Ich könnte auch mal ein Bild von meinem Werk hier posten, falls es interessiert... Gruß Philipp
Klar doch, Bilder sind immer von Interesse! Ich hab mir schon mit Freude eure Bilder mit den Lochrasterplatinen in einem anderen Beitrag angesehen. Für mich geht es jetzt nämlich erst richtig los mit MC, habe gestern meine Mail von Reichelt bekommen das sie die Bestellung rausgeschickt haben. Wenn es dann heute ankommt wird gebastelt. Fremde Erfahrungen finde ich immerr sehr hilfreich, ich lese schon seit Monaten hier im Forum mit und finde alles total spannend. Ich hoffe ich stell mich am Anfang nicht all zu dämlich an und ihr seid nicht genervt wenn ich die ein oder andere dumme Frage stelle die ich nicht in ältere Beiträge finde. Großes Lob an dieses Forum, es hat maßgeblich dazu beigetragen mich für AVR zu interessieren. Zuerst hatte ich geplant mir PICs rum zu machen, hatte mir sogar schon eine minimale Ausrüstung dafür geholt. Aber die AVR "Community" ist einfach viel besser, da bin ich gleich umgestiegen bevor ich richtig angefangen hab. ;o) Weiter so ... und immer schön ausschlafen, dann sieht man einfach gesünder aus. Richy
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.