Delay beim HC12 einbauen? In C. Für LED-Blinken!

OP #2085615
Lesenswert?

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!
#2086905
Lesenswert?

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)
OP #2086910
Lesenswert?

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!!! ;)
#2086938
Lesenswert?

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
OP #2086948
Lesenswert?

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!!!
#2086958
Lesenswert?

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
}
OP #2086964
Lesenswert?

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!!!!!!
Gast #2086968
Lesenswert?

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.)
#2086977
Lesenswert?

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.
Gast #2087000
Lesenswert?

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.
OP #2087030
Lesenswert?

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!!!!
Gast #2087049
Lesenswert?

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.
OP #2087061
Lesenswert?

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!!!
Gast #2087097
Lesenswert?

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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren