www.mikrocontroller.net

Forum: Mikrocontroller und Elektronik PIC verzögerung

Autor: rapeur (Gast)
Datum: 16.04.2008 16:24

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
Autor: rapeur (Gast)
Datum: 16.04.2008 18:10

Hallo,
kann niemand mir helfen ? ich suche die Lösung seit paar Tage.
Gruß
Autor: Mario (Gast)
Datum: 16.04.2008 18:26

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???
Autor: rapeur (Gast)
Datum: 16.04.2008 18:34

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)
Autor: Lötlackl (Gast)
Datum: 16.04.2008 19:31

Hallo,

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

mfg
Autor: rapeur (Gast)
Datum: 16.04.2008 19:34

Hallo
Ja
Gruß
Autor: Gerhard (Gast)
Datum: 16.04.2008 19:55
Dateianhang: LS_V3.zip (3,3 KB, 33 Downloads)

hallo

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

gerhard
Autor: kommutator (Gast)
Datum: 16.04.2008 19:57

@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?
Autor: holger (Gast)
Datum: 16.04.2008 20:03

>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ß
Autor: rapeur (Gast)
Datum: 16.04.2008 20:10

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ß
Autor: Bernd Rüter (bigwumpus)
Datum: 16.04.2008 20:17

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 ?
Autor: rapeur (Gast)
Datum: 16.04.2008 21:19

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.
Autor: Lötkünstler (Gast)
Datum: 16.04.2008 21:28

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>
Autor: rapeur (Gast)
Datum: 16.04.2008 21:35

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
Autor: Lötkünstler (Gast)
Datum: 16.04.2008 21:52

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>
Autor: BummsFallara (Gast)
Datum: 16.04.2008 22:19

Wie wird in deutschland eigendlich kommentiert? - Ausschließlich
englisch oder ist es abhängig von der Firmenphilosophie?
Autor: Lötkünstler (Gast)
Datum: 16.04.2008 22:26

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>
Autor: (ich) (bin) (ein) (Gast)
Datum: 17.04.2008 07:39

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!
Autor: Latissimo (Gast)
Datum: 17.04.2008 07:48

Siehe im Beitrag von karlheinz buchegger (moderator)

Beitrag "Große Zahl aus drei Variablen"

Da sind es 8-bittige unsigned Vars
Autor: Latissimo (Gast)
Datum: 17.04.2008 07:49

Also die "Antwort von" nicht: "der Beitrag von" ;)
Autor: Mario (Gast)
Datum: 17.04.2008 08:36

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 ....
Autor: rapeur (Gast)
Datum: 17.04.2008 19:38

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
Autor: holger (Gast)
Datum: 17.04.2008 20:35
Dateianhang: main.c (4 KB, 57 Downloads) | formatierter Code

>hilfe

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

Siehe Anhang.
Autor: rapeur (Gast)
Datum: 21.04.2008 13:52

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.

Antwort schreiben

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

Wichtige Regeln - erst lesen, dann posten!

  • Suchfunktion und Betreffsuche benutzen - vielleicht gibt es schon einen ähnlichen Beitrag
  • Aussagekräftigen Betreff wählen
  • Im Betreff angeben um welchen Controllertyp es geht (AVR, PIC, ...)
  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
  • JPEG-Dateien (.jpg) nur für Fotos und Scans verwenden
  • Schaltpläne, Screenshots usw. als PNG oder GIF anhängen

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [pre]vorformatierter Text (z.B. Code in anderen Sprachen)[/pre]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel






webmaster@mikrocontroller.netImpressumWerbung auf Mikrocontroller.net