www.mikrocontroller.net

Forum: Compiler & IDEs Programmierung Capture Schrittweite


Autor: Marc Ziegl (marc567)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,
ich möchte mit meinem Mega16 (@16MHZ)die Schrittweite eines Signals 
einlesen. 15khz (bei arithm. Mittel=0).
Leider will das Ganze nicht so wie ich es will.
Hat mir jemand einen Tip woran es liegen könnte?
Habe mal das Grundgerüst für das Capture aus meiner Software 
rausgezogen.
Vielen Dank




#include <inttypes.h>    //Header includen als Bibliotheken
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include <string.h>
#include <avr/eeprom.h>

volatile double rising = 0;    //Ergibt sich aus den beiden 8bit 
Variablen risinglow/risinghigh
volatile uint8_t risinglow = 0;    //8bit Variable zum Register auslesen
volatile uint8_t risinghigh = 0;  //8bit Variable zum Register auslesen
volatile long double risingtemp = 0;

volatile double falling = 0;    //Ergibt sich aus den beiden 8bit 
Variablen fallinglow/fallinghigh
volatile uint8_t fallinglow = 0;  //8bit Variable zum Register auslesen
volatile uint8_t fallinghigh = 0;  //8bit Variable zum Register auslesen
volatile long double fallingtemp = 0;

volatile uint16_t Overflows = 0;
volatile uchar status=0;
volatile uchar fertig=0;

int main (void)
{
//Capture Input
PORTD &= ~BIT6;    //Pullup aus
DDRD &= ~(1<<PD6);  //Eingang
InitTimer();     // SystemClock
sei();      // Freigabe Interrupts

if (ModulEingang1)
  {  fertig=0;
    status=0;
    //Overflows=0;
    lcd_cls();
    double long countstemp;
    double long countstemp1;

    if (fertig==1)
    {
    countstemp = (fallingtemp-risingtemp);//Schrittweite
    countstemp = (countstemp*0.0625);  //in Mikrocontrollertakten
    countstemp1 = (risingtemp-fallingtemp);

    countstemp1 = (countstemp1*0.0625);  //in Mikrocontrollertakten

      lcd_cls();
        lcd_outdouble(countstemp);
        lcd_outdouble(countstemp1);
      Overflows=0;
      wait(10000);
      fertig=0;
      status=0;
    }
  }
ISR(TIMER1_CAPT_vect)
{
      if (fertig==1){return;}
      if ((PIND & (1<<PIND6))&&(status==0))
                     {
                       risinglow=ICR1L;
      risinghigh=ICR1H;
      rising = risinglow;
      rising += (risinghigh<<8);
risingtemp = (long double)(rising+(Overflows*65536));
      //Overflows=0;
      TCCR1B = 0x81; //on falling edge, noise canceler, @16MHZ
      status=1;


         }
      else
      {
                       fallinglow=ICR1L;
      fallinghigh=ICR1H;
      falling = fallinglow;
      falling += (fallinghigh<<8);
 fallingtemp = (long double)(falling+(Overflows*65536));
      TCCR1B=0xC1;
      //Overflows=0;
      fertig=1;

            }

}

ISR(TIMER1_OVF_vect)
{
  Overflows++;
}

void InitTimer()
{
  TCCR0 = 0x01;   // no prescale -->16MHZ
  TCCR1A = 0x00;
  TCCR1B = 0xC1; //Noise Canceler on, trigger on rising edge, no 
prescale (16MHZ)
  TIMSK |= (1<<TOIE0)|(1<<TICIE1)|(1<<TOIE1);        // Timer0 OverFlow 
Interrupt Enable  (BIT0), Timer1:Interrupt wird ausgelöst wenn ICF1 Flag 
gesetzt wird (edge detector hat rising edge erkannt)

}

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bitte beim nächsten Mal den Code richtig formatieren!

> PORTD &= ~BIT6;    //Pullup aus
Das sieht schonmal verdächtig aus. Wie ist "BIT6" definiert?

> risinglow=ICR1L;
> risinghigh=ICR1H;
> rising = risinglow;
> rising += (risinghigh<<8);
Das ist Murks. Lass die 16-Bit-Zugriffe doch den Compiler machen. 
Schmeiß die ***low und ***high weg und schreib einfach
rising = ICR1;

Abgesehen davon kennt der AVR-GCC weder double noch long double (bzw. 
double kennt er zwar, aber es ist identisch mit float, also nur 32 Bit 
breit; 64-Bit-Gleitkomma gibt's im AVR-GCC nicht). Schau Dir bitte mal 
den Artikel zum Thema Festkommaarithmetik an. Ich bin überzeugt 
davon, dass Du für Dein Vorhaben mit Sicherheit keine 
Gleitkommaverrenkungen brauchst.

Zudem wendest Du Bitschiebe-Operationen auf Deine double-Variablen an. 
Das geht garantiert schief! Bitschiebereien sind generell nur für 
Ganzzahl-Werte (integer) definiert.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Fällt mir grad noch auf: Wo ist der Handler (ISR) für den Timer 0 
Overflow Interrupt?

Autor: Marc Ziegl (marc567)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
erstmals tausend dank für die Hilfe.

Hier der Timer0 Overflow:

ISR(TIMER0_OVF_vect)
{
  SystemClk++;

  if (SystemClk>=38)
    {
    SystemClk=0;
    DoForEver10ms=1;
    } // 38 * 256usec @16MHz -> 9,728msec
}


Bit6 ist wie folgt definiert:
#define BIT6  0x40

Ich probier das gleich mal aus - mit dem Register ICR1....
Vielen Dank nochmal....

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Marc Ziegl wrote:
> Ich probier das gleich mal aus - mit dem Register ICR1....
> Vielen Dank nochmal....
Das mit dem ICR ist aber Dein allerkleinstes Problem...

Autor: Marc Ziegl (marc567)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
...wie meinen?

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Marc Ziegl wrote:
> ...wie meinen?
Will sagen, dass das mit dem ICR noch nicht mal für die Funktion der 
ganzen Sache relevant ist, weil es so, wie es in Deinem Code steht (bis 
auf die double-Geschichten) noch nicht mal ein Fehler ist, sondern 
lediglich eine vermeidbare umständliche Vorgehensweise ist. Die 
Behandlung der anderen genannten Probleme ist da eindeutig zu 
priorisieren.

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.