...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