Forum: Mikrocontroller und Digitale Elektronik PIC verzögerung


von rapeur (Gast)


Lesenswert?

Hallo zusammen,
 ich arbeite mit PIC18F4550 MPLAB und Compiler C mit frequenz 20MHz. und 
en Takt brauch 02µS aber mein Programm scheint nicht zu funktionnieren. 
so sieht es aus:

#include "Test.h"

#include <p18F4550>
unsigned int task0_counter=0;
unsigned int task1_counter=0;
unsigned int task2_counter=0;

#define TASK0_COUNTER_MAX 100
#define TASK1_COUNTER_MAX 200
#define TASK2_COUNTER_MAX 500  //100*200*500*0.2µS=2S

void interrupt(unsigned char PORTBbitsRB1, unsigned char PORTDbitsRD0)
{
T1CONbits.TMR1ON=1;
T1CONbits.TMR1CS=0;
T1CONbits.T1SYNC=1;
T1CONbits.T1OSCEN=1;
T1CONbits.T1CKPS0=1;
T1CONbits.T1CKPS1=1;
T1CONbits.T1RUN=1;
T1CONbits.RD16=0;
PIR1bits.TMR1IF=1;
PIR1bits.CCP1IF=1;
PIR1bits.SSPIF=1;

    if(task0_counter > TASK0_COUNTER_MAX)
      {
     task1_counter++;

       if(task1_counter > TASK1_COUNTER_MAX)
         {
          task2_counter++;
           if(task2_counter > TASK2_COUNTER_MAX)
             {
              task0_counter++;
               }
          }
if((task0_counter == TASK0_COUNTER_MAX)&&(task1_counter == 
TASK1_COUNTER_MAX)&&(task2_counter == TASK2_COUNTER_MAX))
          {
          PORTBbits.RB1=PORTDbits.RD0;
          task0_counter=0;
          task1_counter=0;
          task2_counter=0;
          }
      }
}


void main ()
{
  TRISB=0;
  TRISD=0x0F;
  while(1)
  {
  interrupt(PORTBbits.RB1,PORTDbits.RD0);
  PORTBbits.RB1=PORTDbits.RD0;
  }
}

aber es funktioniert nicht.
Hilfe

von rapeur (Gast)


Lesenswert?

Hallo,
kann niemand mir helfen ? ich suche die Lösung seit paar Tage.
Gruß

von Mario (Gast)


Lesenswert?

wie immer wenn man keine Antwort kriegt:

Einfach nur den Code zu posten ist einfach zu wenig!

Sollen wir jetzt raten was Du machen willst???

von rapeur (Gast)


Lesenswert?

Hallo
das ist noch das code
#include "Test.h"

#include <p18F4550>
unsigned int task0_counter=0;
unsigned int task1_counter=0;
unsigned int task2_counter=0;

#define TASK0_COUNTER_MAX 100
#define TASK1_COUNTER_MAX 200
#define TASK2_COUNTER_MAX 500  //100*200*500*0.2µS=2S

void interrupt(unsigned char PORTBbitsRB1, unsigned char PORTDbitsRD0)
{
T1CONbits.TMR1ON=1;
T1CONbits.TMR1CS=0;
T1CONbits.T1SYNC=1;
T1CONbits.T1OSCEN=1;
T1CONbits.T1CKPS0=1;
T1CONbits.T1CKPS1=1;
T1CONbits.T1RUN=1;
T1CONbits.RD16=0;
PIR1bits.TMR1IF=1;
PIR1bits.CCP1IF=1;
PIR1bits.SSPIF=1;

    if(task0_counter > TASK0_COUNTER_MAX)
      {
     task1_counter++;

       if(task1_counter > TASK1_COUNTER_MAX)
         {
          task2_counter++;
           if(task2_counter > TASK2_COUNTER_MAX)
             {
              task0_counter++;
               }
          }
if((task0_counter == TASK0_COUNTER_MAX)&&(task1_counter ==
TASK1_COUNTER_MAX)&&(task2_counter == TASK2_COUNTER_MAX))
          {
          PORTBbits.RB1=PORTDbits.RD0;
          task0_counter=0;
          task1_counter=0;
          task2_counter=0;
          }
      }
}

void main ()
{
  TRISB=0;
  TRISD=0x0F;
  while(1)
  {
  interrupt(PORTBbits.RB1,PORTDbits.RD0);
  PORTBbits.RB1=PORTDbits.RD0;
  }
}
ich moechte gern ein Verzögerung für ein Clock von z.B 2S realisiert 
ohne for und while (ausser main Programm)

von Lötlackl (Gast)


Lesenswert?

Hallo,

Wird beim PIC eine Interrupt-Serviceroutine als normale C-Funktion 
aufgerufen???

mfg

von rapeur (Gast)


Lesenswert?

Hallo
Ja
Gruß

von Gerhard (Gast)


Angehängte Dateien:

Lesenswert?

hallo

im Anhang ein Beispielcode für den Pic18F1320 mit Interrupt auf Timer1

gerhard

von kommutator (Gast)


Lesenswert?

@rapeur

Ähm, also eine kleine Erläuterung wäre ganz nett, es ist absolut 
unverständlich was das Programm tun soll - und auch in C schreibt man 
immer mit Kommentar... ;-)

Also erstmal ist die Routine "interrupt" keine echte Interrupt-Routine, 
sondern ein schlecht gewählter name. Geht das überhaupt durch den 
Compiler? Braucht der PIC nicht ein bisl mehr initialisierung?

von holger (Gast)


Lesenswert?

>Wird beim PIC eine Interrupt-Serviceroutine als normale C-Funktion
>aufgerufen???

>Hallo
>Ja
>Gruß

Hallo
Jein, siehe Gerhard.
In der main-loop ruft man sie nicht auf.
Gruß

von rapeur (Gast)


Lesenswert?

Hallo Kommutator,
ich moechte gern eine funktion mit verzögerung realisiert. nehmen wir 
ich duch den Clock das macht PORTBbits.RB1=PORTDbits.RD0; den Port B1 
enthalt 2S später den wert von Port D0. ich habe realisiert mit ein For 
schleife aber für das Programm pass nicht gut, deshalb wurde ich 
empfehlen mit interrupt zu machen. das problem ist ich habe noch nicht 
ein interrupt bearbeiten deshalb ist es neu für mich.ich moechte gern 
dass , die verzögerung kein einfluss auf das gesamte Programm nur wo ich 
will.und das ist das problemm. interrupt ist neu fur mich
Gruß

von Bernd R. (Firma: Promaxx.net) (bigwumpus)


Lesenswert?

Also,

in der INT-Routine wird der Timer0 gestartet und versch. INT-Flags 
gesetzt (kann die Software gar nicht, geht nur in Hardware).
Die INT-Enable-Bits werden nirgends gesetzt.

In der Int-Routine werden 3 Zähler nacheinander hochgezählt.
Erst Task0_Counter bis er über 100 ist.
Ab dann wird bei jedem Durchlauf Task1_Counter hochgezählt, bis er 200 
erreicht, ab dann wird Task2_Counter hochgezählt, bis er 500 erreicht, 
weil dann Task0_Counter weitergezählt wird.
Die IF-Bedingung wird eigentlich nie erfüllt.

Was soll das ganze ?
Wozu brauchst Du den Timer0 ?
Was hat das mit 20MHz zu tun ?

von rapeur (Gast)


Lesenswert?

Hallo,
ich sollte nur einfach und ich habe ein test Platine wo ich überprüfen 
kann. Und bei mein Test platine kann ich nicht die verzögerung merken. 
20MHz ist die Frequenz von Quartz. Warum wird die IF bedingungen nicht 
erfüllt?
Ich brauche Timer und ein Verzögerung zu realisiert.

von Lötkünstler (Gast)


Lesenswert?

Haste bei deiner Entwicklungsumgebung keinen Debugger?
Wenn du das Programm auf einen bestimmten Pic laufen lassen willst
brauchste außerdem einen Simulator.

Lötkünstler


<Mit der Lizenz zum löten>

von rapeur (Gast)


Lesenswert?

Hallo
Das MPLAB hat einen Debbuger, aber ich habe noch nicht benutzt. ich habe 
immer mit Oscilloscope gemessen. Aber wenn mann ein Verzögerung von 2S 
hat, kann man auf Platine merken oder?
Rapeur

von Lötkünstler (Gast)


Lesenswert?

Das Programm muß erst mal Fehlerfrei arbeiten,sonst haben Messungen 
keinen
Sinn,außerdem kann man mit dem normalen Oszilloskop nur periodische 
Signale messen.Debugging/Simulation ist jedenfalls der vernünftigere Weg 
Fehler zu finden.Ich würde mich mal angewöhnen das Programm zu 
kommentieren weil
es sonst nur schwer nachvollziehbar ist.

>void interrupt(unsigned char PORTBbitsRB1, unsigned char PORTDbitsRD0)
ist die Syntax ohne Trennungspunkte korrekt (PORTBbits.RB1  ?)
Fiel mir nur auf.
Mehr kann ich leider nicht dazu beitragen.

Lötkünstler


<Mit der Lizenz zum löten>

von BummsFallara (Gast)


Lesenswert?

Wie wird in deutschland eigendlich kommentiert? - Ausschließlich 
englisch oder ist es abhängig von der Firmenphilosophie?

von Lötkünstler (Gast)


Lesenswert?

Die Kommentierung soll ein Nachvollziehen des Programms erleichtern.
Wenn man nach einer gewissen Zeit Änderungen durchführen will sind
sinnreiche Kommentare hilfreich und Kollegen sind dann Dankbar wenn die
diese Ausgabe übernehmen müssen.
Bei Nationalem Gebrauch in der Landessprache sonst englisch.



Lötkünstler


<Mit der Lizenz zum löten>

von (ich) (bin) (ein) (Gast)


Lesenswert?

in der main-Funktion von dir rufst du den interrupt auf, als wenn es 
eine Funktion wäre....

Das geht so nicht!!!

Ein Interrupt ist immer unter gewissen Bedinungen aufgerufen! z.B. Wenn 
ein Flankenwechsel an einem PIN oder ein Timerüberlauf stattgefunden 
haben. Dann wird das Programm(egal, welche zeile gerade abgearbeitet 
wird) unterbrochen und es wird der code an der stelle des Interrupts 
ausgeführt. Danach springt der Ablauf dann wieder an die Stelle im 
Programm, wo er geendet(interrupted) hat.


außerdem solltest du dir noch mal die counter angucken, weil das so 
nicht läuft!
ich würde das nach folgendem prinzip aufbauen:

unsigned counter bis maximalen wert zählen lassen, bei maximalem wert 
nächsten counter inkrementieren. So ist sichergestellt, dass der zweite 
counter immer periodisch!!! inkrementiert wird, das ist so bei dir nicht 
der fall!

von Latissimo (Gast)


Lesenswert?

Siehe im Beitrag von karlheinz buchegger (moderator)

Beitrag "Große Zahl aus drei Variablen"

Da sind es 8-bittige unsigned Vars

von Latissimo (Gast)


Lesenswert?

Also die "Antwort von" nicht: "der Beitrag von" ;)

von Mario (Gast)


Lesenswert?

Also,

zunächst kann ich mir nicht verkneifen mich den vorangegangenen 
Kommentaren anzuschließen!

Was musst Du machen:
a) Test den Code in MPLAB, indem Du den den Debugger->select Tool->MPLAB 
SIM einstellst. Dann kannst Du schritt für schritt dein Programm 
ausführen lassen.

b) der neu zu schreiben. Vorschlag für die Implementierung:
   Nimm den Timer1 um die Verzögerung zu realisieren per 
interrupt-betrieb.
   Nimm einen zweiten interrupt der ausgelöst wird, wenn der Pegel sich
   am gewünschten Eingang verändert (Dazu musst du evtl. den Port B
   nehmen), initialisiere und starte dann den timer.
   Läuft der Timer ab, löst er den timer-interrupt aus der den Wert
   ausgibt und den timer-interrupt wieder abdreht.

Wenn Du jetzt eine 2S Verzögerung haben willst, wirds zusätzlich 
komliziert, denn dann musst du jede Änderung innerhalb der 2S 
abspeichern, d.h. einen Zeitstempel wann sich das Signal verändert hat. 
Wenn Du nur ein langsam änderndes Signal am Eingang hast, also seltener 
als 2S kannst Du dir das sparen. Und dann ist da noch das Problem wenn 
das Eingangssignal nicht ganz sauber ist ....

von rapeur (Gast)


Lesenswert?

ich habe noch so gebasteln. keine fehler aber funktionniert nicht
#include <p18F4550.h>
#include <stdio.h>
#include <delays.h>

unsigned char counter ;

void main ()
{
  TRISB=0;
  TRISD=0x07;
  INIT();
//  Timer0_isr();

  while(1)
  {
  INIT();
    if(INTCONbits.T0IF)
    {
      ++counter;

PORTDbits.RD4=PORTDbits.RD0;
//PORTBbits.RB1=delay(PORTDbits.RD0);


  PORTBbits.RB1=delay(PORTDbits.RD0);

  //INTCONbits.T0IF=0;
  }

}

}



#include "Test.h"

#include <p18F4550.h>


unsigned char task0_counter=0;


#define TASK0_COUNTER_MAX 8000000
     //unsigned char counter; //counter variable to count
                            // the number of TMR0 overflows

unsigned char counter1 ;

   void   INIT(void)
      {
//      TMR0=0;  //Clear the TMR0 register
TMR0H=20;
      // Configure Timer0
      T0CONbits.TMR0ON=0;
      T0CONbits.T08BIT=0;
      T0CONbits.T0CS=0;
      T0CONbits.T0SE=1;
      T0CONbits.PSA=1;
      T0CONbits.T0PS2=1;
      T0CONbits.T0PS1=0;
      T0CONbits.T0PS0=0;//1:32 Prescale value
      INTCONbits.T0IF=1;

  if(INTCONbits.T0IF)
  {
    task0_counter++; // zahl bis TASK0_COUNTER_MAX

}
 }

void Timer0_isr(void)
{
  INTCONbits.INT0IE=1;
  INTCONbits.INT0IF=1;
  INTCONbits.GIE=1;

    if(INTCONbits.T0IE && INTCONbits.T0IF)
    {
   INTCONbits.T0IF=0;    // zahl bis 255 und incrementieren counter
    ++counter1;
    }

}

 char delay(unsigned char PORTDbitsRD0)
 {
 Delay10KTCYx(200);
 return PORTDbitsRD0;

hilfe

von holger (Gast)


Angehängte Dateien:

Lesenswert?

>hilfe

Du stocherst blind rum. So geht das nicht.
Beim mcc18 ist doch ein Beispiel für
TMR0 Interrupt dabei.

Siehe Anhang.

von rapeur (Gast)


Lesenswert?

Hallo Zusammen
ich bedanke mich für ihre Beitrage
ich habe noch so Probiert und es funktionniert immer noch nicht. das ist 
mein neues Code
#include <p18F4550.h>

unsigned float task0_counter=0;
unsigned float task1_counter=0;



#define TASK0_COUNTER_MAX 250
#define TASK1_COUNTER_MAX 250
   void Timer0_isr(void)
      {

      T0CONbits.TMR0ON=1;
      T0CONbits.T08BIT=1;
      T0CONbits.T0CS=1;
      T0CONbits.T0SE=0;
      T0CONbits.PSA=0;    //Prescaler
      T0CONbits.T0PS2=1;
      T0CONbits.T0PS1=1;
      T0CONbits.T0PS0=1;   //256:1

      if(INTCONbits.T0IF)
         {//watre Zeit von TASK0_COUNTER_MAX*TASK1_COUNTER_MAX*51,2µ
        task0_counter++; // zahl bis TASK0_COUNTER_MAX
            if(task0_counter == TASK0_COUNTER_MAX)
              {

             task1_counter++; //zahl bis TASK1_COUNTER_MAX

              if(task1_counter == TASK1_COUNTER_MAX)
                {
                 // task1_counter=0;
               //INTCONbits.T0IF=0;

                }
               }
              }
      task0_counter=0;
      task1_counter=0;
  // PORTBbits.RB4^=1;

      }



void Timer0_ISR(void)
     {

     INTCONbits.T0IE=1;
     INTCONbits.T0IF=1;
       RCONbits.IPEN=1;
       INTCONbits.GIE=1;
       INTCONbits.PEIE=1;
       INTCONbits.RBIE=0;
       INTCONbits.TMR0IE=1;
       RCONbits.TO=0;
       RCONbits.PD=0;

  if((INTCONbits.T0IE)&&(INTCONbits.T0IF))
    {
      INTCONbits.T0IE=0;
    if(INTCONbits.GIE==1)
      {

  }
  }

}


void main ()
{
  TRISB=0;
  TRISD=0xFF;
  INIT();
  TMR0L=131;

  while(1)
    {

        }

 }

Port D4 sollte blinken mit 2s  Verzögerung.

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
Noch kein Account? Hier anmelden.