www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Delay beim HC12 einbauen? In C. Für LED-Blinken!


Autor: J. R. (cia_man)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Lehrmann Michael (ubimbo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: J. R. (cia_man)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 ;)

Autor: J. R. (cia_man)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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!!!

Autor: Justus Skorps (jussa)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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...

Autor: Timmo H. (masterfx)
Datum:

Bewertung
0 lesenswert
nicht 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:
void delay1ms(void) {
  asm("ldy #2400");
  asm("dbne y,.");  // 3cyc x 135ns x 2400 = 0,994ms
}


void wait(int duration)
{
  while(duration--)
  delay1ms();
}

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)

Autor: J. R. (cia_man)
Datum:

Bewertung
0 lesenswert
nicht 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:
>
> void delay1ms(void) {
>   asm("ldy #2400");
>   asm("dbne y,.");  // 3cyc x 135ns x 2400 = 0,994ms
> }
> 
> 
> void wait(int duration)
> {
>   while(duration--)
>   delay1ms();
> }
> 
>
> 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!!! ;)

Autor: J. R. (cia_man)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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!!!

Autor: Timmo H. (masterfx)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: J. R. (cia_man)
Datum:

Bewertung
0 lesenswert
nicht 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!!!

Autor: Timmo H. (masterfx)
Datum:

Bewertung
0 lesenswert
nicht 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.
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
  }
}

Autor: J. R. (cia_man)
Datum:

Bewertung
0 lesenswert
nicht 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!!!!!!

Autor: APW (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.)

Autor: Heike L. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eventuell deswegen?

while(1){
  }

Autor: Timmo H. (masterfx)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: APW (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So:

void main(void) {

  DDRH |=0x80;  // Auf Ausgang schalten

  while(1)
  { PORTH ^= 0x80;  //Am Portpin wackeln
    wait(1000);
  }
}

Autor: APW (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kann sein dass icc das PTH statt PORTH nennt.

Autor: APW (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: J. R. (cia_man)
Datum:

Bewertung
0 lesenswert
nicht 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!!!!

Autor: Timmo H. (masterfx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: APW (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: J. R. (cia_man)
Datum:

Bewertung
0 lesenswert
nicht 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!!!

Autor: Timmo H. (masterfx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Für ICC12 gibt den NoICE 12-Debugger (weiß gar nicht mehr ob der dabei 
ist)

Autor: APW (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast du überhaupt einen BDM-Debugger?

Autor: APW (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: J. R. (cia_man)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
APW schrieb:
> Hast du überhaupt einen BDM-Debugger?

Ja! Hab ich!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.