Hallo Ich möchte wie oben beschrieben ein delay von 0.5 s einbauen in mein Programm! Programm: #include <stdio.h> #include <mc912d128.h> void main(void) { DDRH ^= 0x80; DDRH |=0x80; while(1){ } } Ihr seht ich möchte einfach die LED im 0,5 s Zyklus ab und anschalten! Gibt es dafür einen direkten Befehl beim MC912DG128A??? So etwas wie delay... ??? Ich programmiere in ICC12 mit C! THX!
Jochen R. schrieb: > Ihr seht ich möchte einfach die LED im 0,5 s Zyklus ab und anschalten! Dann sollte der Code + Delay aber in die Endlosschleife. Ansonsten blinkt's nur einmal. Schau mal im Handbuch nach. Heißt meistens delay.h oder delays.h
Lehrmann Michael schrieb: > Jochen R. schrieb: >> Ihr seht ich möchte einfach die LED im 0,5 s Zyklus ab und anschalten! > > Dann sollte der Code + Delay aber in die Endlosschleife. Ansonsten > blinkt's nur einmal. > > Schau mal im Handbuch nach. Heißt meistens delay.h oder delays.h Ja des delay fehlt ja oben eben noch! :) Darum frage ich ja ;)
Hallo! Ich muss jetzt doch mal blöd fragen... das ist doch das Handbuch was ihr immer meint oder? Weil da steht nix von delay.h bzw delays.h drinnen :) THX!!!
Jochen R. schrieb: > Ich muss jetzt doch mal blöd fragen... das ist doch das Handbuch was ihr > immer meint oder? nein, dass zu deinem Compiler...
Ich glaube der ICC hat kein Delay oder so eingebaut. Du könntest dich mal mit dem Timer beschäftigen, sodass er z.B. jede Millisekunde einen Interrupt generiert und darin eine Variable hochzählt welche du dann überprüfst ob diese schon größer-gleich 500 ist. Du kannst dir natürlich auch erstmal eine wait-Funktion über eine While-Schleife machen. Ich glaube das funktionierte ganz gut bei mir:
1 | void delay1ms(void) { |
2 | asm("ldy #2400"); |
3 | asm("dbne y,."); // 3cyc x 135ns x 2400 = 0,994ms |
4 | }
|
5 | |
6 | |
7 | void wait(int duration) |
8 | {
|
9 | while(duration--) |
10 | delay1ms(); |
11 | }
|
Wenigstens kann ich dir bei jeder deiner Frage helfen. Besonders viele arbeiten hier nämlich nicht mit HC12 (ich auch nicht mehr, hatte aber mal ein größeres Projekt)
Timmo H. schrieb: > Ich glaube der ICC hat kein Delay oder so eingebaut. Du könntest dich > mal mit dem Timer beschäftigen, sodass er z.B. jede Millisekunde einen > Interrupt generiert und darin eine Variable hochzählt welche du dann > überprüfst ob diese schon größer-gleich 500 ist. > > Du kannst dir natürlich auch erstmal eine wait-Funktion über eine > While-Schleife machen. > Ich glaube das funktionierte ganz gut bei mir: >
1 | > void delay1ms(void) { |
2 | > asm("ldy #2400"); |
3 | > asm("dbne y,."); // 3cyc x 135ns x 2400 = 0,994ms |
4 | > } |
5 | >
|
6 | >
|
7 | > void wait(int duration) |
8 | > { |
9 | > while(duration--) |
10 | > delay1ms(); |
11 | > } |
12 | >
|
> > Wenigstens kann ich dir bei jeder deiner Frage helfen. Besonders viele > arbeiten hier nämlich nicht mit HC12 (ich auch nicht mehr, hatte aber > mal ein größeres Projekt) Jo leider :( Aber naja mal schauen... wenigstens kannst du mir ja ab und an ein paar Tipps geben! Ich werde mir jetzt mal das Buch Embedded Microcomputer Systems (Real Time Interfacing) - by Jonathan W. Valvano * (This book uses the ImageCraft ICC12 compiler extensively in its examples! :-) ) besorgen! Weiß nicht ob du das kennst? Hoffe mal damit kann ich dann etwas mehr meine Wissenslücken stopfen! ;) Und danke natürlich nochmal für deine Tipps!!! ;)
Kannst du mir bitte die einzelnen Zeilen des Programms noch etwas erklären? void delay1ms(void) { asm("ldy #2400"); asm("dbne y,."); // 3cyc x 135ns x 2400 = 0,994ms } void wait(int duration) { while(duration--) delay1ms(); } Wäre gut!! ;) THX!!!
Alles innerhalb von asm(...) sind assembler Befehle, also Maschinencode. Im Datenblatt steht wie lange der µC für das Ausführen der Befehle braucht (siehe Kommentar) und diese beiden Befehle mit dem entsprechenden Zahlenwert (2400) brauchen eben 0,994ms (bei 8 MHz). Eigentlich wird halt nur der Zahlenwert "2400" in ein Register (ldy #2400) geschrieben und solange dekrementiert bis dieser 0 ist (dbne = Decrement Branch Not Equal to Zero ) Diese Schleife kannst du dann über wait(100) aufrufen um also 100 mal diese Schleife zu durchlaufen = 994 ms
Timmo H. schrieb: > Alles innerhalb von asm(...) sind assembler Befehle, also Maschinencode. > Im Datenblatt steht wie lange der µC für das Ausführen der Befehle > braucht (siehe Kommentar) und diese beiden Befehle mit dem > entsprechenden Zahlenwert (2400) brauchen eben 0,994ms (bei 8 MHz). > Eigentlich wird halt nur der Zahlenwert "2400" in ein Register (ldy > #2400) geschrieben und solange dekrementiert bis dieser 0 ist (dbne = > Decrement Branch Not Equal ) > Diese Schleife kannst du dann über wait(100) aufrufen um also 100 mal > diese Schleife zu durchlaufen = 994 ms Ist dieser Zahlenwert dann eine Hex-Zahl? Und bedeutet "dbne y,." also der . um 1 erniedrigen??? Und wait(100) schreibe ich dann ganz ans Ende oder? THX!!! ;) das hilft mir wirklich ungemein!!!
Jochen R. schrieb: > Ist dieser Zahlenwert dann eine Hex-Zahl? Und bedeutet "dbne y,." also > der . um 1 erniedrigen??? Nein, schau auch mal ins Reference manual: CPU12RM.pdf #2400 ist eine dezimalzahl die mit ldy in das Y-Register geladen wird. Mit dbne y,. wird das Y-Register dekrementiert und solange es ungleich 0 ist wird auf "." (also die gleiche Adresse wie der Befehl selbst gesprungen (ähnlich wie while(i--);) Das wait verwendest du dann in der Main, also z.B.
1 | void delay1ms(void) { |
2 | asm("ldy #2400"); |
3 | asm("dbne y,."); // 3cyc x 135ns x 2400 = 0,994ms |
4 | }
|
5 | |
6 | |
7 | void wait(int duration) |
8 | {
|
9 | while(duration--) |
10 | delay1ms(); |
11 | }
|
12 | |
13 | int main(){ |
14 | |
15 | |
16 | DDRH |=0x80; // als Ausgang setzen |
17 | |
18 | while(1){ |
19 | PTH ^= 0x80; // 1=>0 bzw. 0=>1 |
20 | wait(100); //100ms warten |
21 | }
|
22 | }
|
Timmo H. schrieb: > Jochen R. schrieb: >> Ist dieser Zahlenwert dann eine Hex-Zahl? Und bedeutet "dbne y,." also >> der . um 1 erniedrigen??? > Nein, schau auch mal ins Reference manual: CPU12RM.pdf > > #2400 ist eine dezimalzahl die mit ldy in das Y-Register geladen wird. > Mit dbne y,. wird das Y-Register dekrementiert und solange es ungleich 0 > ist wird auf "." (also die gleiche Adresse wie der Befehl selbst > gesprungen (ähnlich wie while(i--);) > > Das wait verwendest du dann in der Main, also z.B. > > [c] > void delay1ms(void) { > asm("ldy #2400"); > asm("dbne y,."); // 3cyc x 135ns x 2400 = 0,994ms > } > > > void wait(int duration) > { > while(duration--) > delay1ms(); > } > > int main(){ > > > DDRH |=0x80; // als Ausgang setzen > > while(1){ > PTH ^= 0x80; // 1=>0 bzw. 0=>1 > wait(100); //100ms warten > } > } Okay! Und warum blinkt es bei mir mit folgendem Code nur 1mal? #include <stdio.h> #include <mc912d128.h> void delay1ms(void) { asm("ldy #2400"); asm("dbne y,."); // 3cyc x 135ns x 2400 = 0,994ms } void wait(int duration) { while(duration--) delay1ms(); } void main(void) { DDRH ^= 0x80; wait(1000); DDRH |=0x80; while(1){ } } THX!!!!!!
Da ist ein kleiner Rechenfehler drin. HC12 bei 8MHz Busclock = 125 ns Cycle. 1ms Verzögerung sind dann 8000 Buscycles, die man verbrennen muss. dbne... braucht 3 Cycles -> 8000/3=2666 also: asm("ldy #2600"); //2600 in Y-Register laden asm("dbne y,."); // Decrement, bis Y=0 ist / //3cyc x 125ns x 2666 = 0,99975ms (dabei ist zu hoffen, dass der icc das y Register sichert.)
Jochen R. schrieb: > Okay! > > Und warum blinkt es bei mir mit folgendem Code nur 1mal? > while(1){ > } Weil du da auf der Stelle stehen bleibst. Mit while(1) bleibst du dort stehen, aber du willst ja quasi unendlich lange blinken lassen also müssen deine Befehle IN die While-Schleife. Übrigens wie schon bei deinem letzen Post geschrieben solltest du den Port mit PTH ^= 0x80 setzen und nicht das DDR-Register dazu verwenden. Damit schaltest du dann ständig zwischen Tristate und Ausgang mit 0 hin und her.
So: void main(void) { DDRH |=0x80; // Auf Ausgang schalten while(1) { PORTH ^= 0x80; //Am Portpin wackeln wait(1000); } }
Muss mich mal registrieren, dass ich meinen Sch.. korrigieren kann. Das oben soll natürlich asm("ldy #2666"); //2666 in Y-Register laden asm("dbne y,."); // Decrement, bis Y=0 ist / //3cyc x 125ns x 2666 = 0,99975ms heißen.
APW schrieb: > Muss mich mal registrieren, dass ich meinen Sch.. korrigieren kann. > Das oben soll natürlich > > asm("ldy #2666"); //2666 in Y-Register laden > asm("dbne y,."); // Decrement, bis Y=0 ist / > //3cyc x 125ns x 2666 = 0,99975ms > > heißen. So jetzt nochmal den vollen Code! Mit Verbesserungen! ;) #include <stdio.h> #include <mc912d128.h> void delay1ms(void) { asm("ldy #2666"); //2666 in Y-Register laden asm("dbne y,."); // Decrement, bis Y=0 ist / //3cyc x 125ns x 2666 = 0,99975ms } void wait(int duration) { while(duration--) delay1ms(); } void main(void) { DDRH |= 0x80; while(1){ PORTH ^=0x80; wait(1000); } } Geht einwandfrei!!! Und ich habs endlich mal verstanden!!! Die while-Schleife läuft also so lange bis 0 eintritt! :) Was bei der 2ten mit 1 nie passiert... darum blinkt es durch.... freu THX!!!!
APW schrieb: > Da ist ein kleiner Rechenfehler drin. > HC12 bei 8MHz Busclock = 125 ns Cycle. > 1ms Verzögerung sind dann 8000 Buscycles, die man verbrennen muss. > dbne... braucht 3 Cycles -> 8000/3=2666 > also: Ja stimmt, ich hatte damals nen Baudratenquarz drin 7,3728 MHz, darum weichen die etwas ab.
Der Lerneffekt ist groß, wenn du mal solche einfachen Sachen Schritt für Schritt im Debugger auf Assemblerebene ausführst. Gelegentliche Blicke ins Listingfile sind auch hilfreich, da sieht man, was der Compiler aus dem C-Quellcode macht.
APW schrieb: > Der Lerneffekt ist groß, wenn du mal solche einfachen Sachen Schritt für > Schritt im Debugger auf Assemblerebene ausführst. > Gelegentliche Blicke ins Listingfile sind auch hilfreich, da sieht man, > was der Compiler aus dem C-Quellcode macht. Was nehme ich dann für das Debuggen auf Assemblerebene für ein Programm?? Am besten ein kostenloses! ;) THX!!!
Für ICC12 gibt den NoICE 12-Debugger (weiß gar nicht mehr ob der dabei ist)
Ich hab bis jetzt auf 2 Wegen HC(S) 12 programmiert: 1) ICC12 Comiler + StarProg zum Brennen über ComPod12 + NoIce Debugger 2) Freescale CodeWarrior + USBMultilinkBDM wobei 2) fast nur Vorteile hat (auch finanziell) und du auch ohne Mehrkosten HCS08 programmieren kannst.
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.