www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Drehzahlmessung mit mikroC


Autor: Remo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Programmierer

Habe mir das Board easyPIC 5 gekauft, programmiere in mikroC und komme 
einigermassen zurecht damit.
Nun habe ich auch schon meine erste Aufgabe.
Ich möchte gerne über einen Hallsensor die Drehzahl Messen
(60 bis ca. 6000 U/min).
Pro Umdrehung habe ich einen Impuls vom Hallsensor am eingang RB0.

Nun mein Gedanke: Ich messe die Zeit zwichen den Impulsen des 
Hallsensors und rechne daraus die Drehzahl. Ich lasse den TMR0 1:2 
laufen und zähle die Überläufe.
Anhand der Überläufe und des aktuellen TMR0-Standes sollte man nun die 
Drehzahl rechnen können oder?

a = Überläufe
b = TMR0
c = Vorteiler (2)
d = 4*(1/(1000*Clock_Khz))

Die Formel:

1/ (((256 * a)+b)*c*d)

Nun mein Problem ich kenne mich in rechnen mit PIC's noch nicht aus.
Die Variabeln werden bestimmt komastellen haben.
Was muss ich da für Datentypen nehmen?
Am schluss möchte ich die Drehzahl an einer 4-Stelligen 7-Segmentanzeige 
darstellen (als gerundete Ganzzahl).

Oder gibt es da vielleicht ein ganz anderer Grundsatz?

freundliche Grüsse

Remo Hug

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stelle deine Formel so auf, das du ohne Kommastellen auskommst. Wenn man 
es vermeiden kann, verwendet man keine Fließkommazahlen.

Autor: Remo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Martin

Jetzt hab ich ein Knopf.
Wenn ich eine division habe, kann es doch immer eine komastelle geben.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Remo wrote:
> Hallo Martin
>
> Jetzt hab ich ein Knopf.
> Wenn ich eine division habe, kann es doch immer eine komastelle geben.

Du willst zb. Preise addieren.
Das kannst du so machen:  2 Euro 20  plus  3 Euro 70
oder anders geschrieben: 2.20 + 3.70
ergibt 5.90, also 5 Euro 90

Du kannst aber auch so rechnen:
2 Euro 20, das sind 220 Cent   plus
3 Euro 70, das sind 370 Cent

 220 + 370 = 590

also ist das Ergebnis 590 Cent. Das wiederrum sind 5 Euro 90

Während der Berechnung hast du keine Kommastellen gebraucht.
Erst ganz zum Schluss, wenn es darum geht, das Ergebnis zu
begutachten und anzuzeigen, wurde bei der Ausgabe hinter
die Hunderterstelle ein Komma eingeschmuggelt um dem Benutzer
die 590 als 5.90 zu präsentieren.

Mann kann Formeln auch so umstellen, dass die Divisionen zum
Schluss erfolgen. Dadurch verliert man praktisch nichts wenn
vorher alles als ganze Zahlen gerechnet wird.

Autor: Michael K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bei sprut gibts da auch was dazu :

http://www.sprut.de/electronic/pic/projekte/dehzahl/dreh.htm

Sehr zu empfehlen !!!

Grüße
Michael

Autor: Remo Hug (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Michael

Kenne die seite vom Googeln her.
Da der Code aber in Assembler ist sagt mir das relativ wenig aus.

Noch eine Frage: Was steht in c, wenn ich Folgendes Rechne?

a=5
b=2
c (integer)

c= a/b

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
c = 2

Autor: Remo Hug (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

Könnte mir mal vielleicht jemand mein Programm anschauen?
Funktioniert dass?
Habe ich da keine Probleme mit Interrupt zeiten oder so?

#include "Display_utils.h"

unsigned short portd_array[4];
unsigned int i, X_high, y_low ,cntUberlauf, cntFlanke, digit, number;
unsigned long TMR1, Frequenz;

// Unterprogramme

void initialisieren(){
     //OPTION_REG = 0b01000000;
     TRISA = 0x00;
     TRISC = 0x00;
     TRISB = 0xFF;
     TRISC = 0x00;
     TRISD = 0x00;
     INTCON = 0b11010000;
     PIE1 = 0b00000001;
     T1CON = 0b00000001;

     PORTA = 0x00;
     PORTC = 0x00;
     PORTD = 0x00;

     TMR1H  = 0;
     TMR1L  = 0;
     cntUberlauf = 0;
     cntFlanke = 0;
     digit = 0;
     number = 0;

     Frequenz = 1000*Clock_Khz();

     digit = number / 1000u ;             // extract thousands digit
     portd_array[3] = mask(digit);        // and store it to PORTD array
     digit = (number / 100u) % 10u;       // extract hundreds digit
     portd_array[2] = mask(digit);        // and store it to PORTD array
     digit = (number / 10u) % 10u;        // extract tens digit
     portd_array[1] = mask(digit);        // and store it to PORTD array
     digit = number % 10u;                // extract ones digit
     portd_array[0] = mask(digit);
     }

unsigned float Drehzahl(unsigned int Uberlauf, unsigned int TMR){

         float a;
         const long Max_Zaehlerstand = 65535;
         const int TMR_Vorteiler = 1;
         const int Pulse_pro_Umdrehung = 1;

         a = 0;
         a = (Uberlauf*Max_Zaehlerstand)*TMR_Vorteiler;
         a = a+TMR;
         a = a*Pulse_pro_Umdrehung;
         a = a*4;
         a = a/Frequenz;
         a = 60/a;

         return a;
}

void interrupt() {
     INTCON.GIE = 0;

      if (INTCON.INTF == 1){
        if (cntFlanke = 0){
           TMR1H = 0x00;
           TMR1L = 0x00;
           cntUberlauf = 0;
           }

        INTCON.INTF = 0;
        cntFlanke++;
        }

      if (PIR1.TMR1IF == 1){
        PIR1.TMR1IF = 0;
        cntUberlauf++;
        PORTC = ~PORTC;
        }

     INTCON.GIE = 1;
}

// Hauptprogramm

void main() {

  initialisieren();

  while(1) {

     i=0;

     while(i<200){

         if (i==0 & cntFlanke==0){
             INTCON.GIE = 0;

             X_high = 0xAB;
             y_low = 0xCC;

             TMR1 = (X_high<<8)+y_low;

             //TMR1 = (TMR1H<<8)+TMR1L;
             number= Drehzahl(cntUberlauf,TMR1);
             digit = number / 1000u ;             // extract thousands 
digit
             portd_array[3] = mask(digit);        // and store it to 
PORTD array
             digit = (number / 100u) % 10u;       // extract hundreds 
digit
             portd_array[2] = mask(digit);        // and store it to 
PORTD array
             digit = (number / 10u) % 10u;        // extract tens digit
             portd_array[1] = mask(digit);        // and store it to 
PORTD array
             digit = number % 10u;                // extract ones digit
             portd_array[0] = mask(digit);

             cntUberlauf = 0;
             cntFlanke = 0;

             INTCON.GIE = 1;
         }

         PORTD = portd_array[0];
         PORTA = 0x01;
         Delay_us(500);
         PORTA = 0x00;

         if (number >= 10){
            PORTD = portd_array[1];
            PORTA = 0x02;
            Delay_us(500);
            PORTA = 0x00;
            }

         if (number >= 100){
            PORTD = portd_array[2];
            PORTA = 0x04;
            Delay_us(500);
            PORTA = 0x00;
            }

         if (number >= 1000){
            PORTD = portd_array[3];
            PORTA = 0x08;
            Delay_us(500);
            PORTA = 0x00;
            }

         i++;
     }
  }
}


freundliche Grüsse

Remo Hug

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.