www.mikrocontroller.net

Forum: FPGA, VHDL & Co. ungeradzahlig teilen


Autor: Rolf Gärtner (haegar88)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich stehe vor dem Problem, dass ich von einem Drehgeber 2,671875 Pulse 
pro mm bekomme aber möglichst genau alle mm einen Zähler erhöhen will. 2 
ist falsch, 3 aber auch. Abwechselnd 2 und 3 in geschicktem Wechsel wäre 
am genauesten.. Hat sowas schonmal jemand gemacht? Vielen Dank im 
voraus!
Gruß Haegar

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
warum nicht den spiess umkehren?

Rechne aus welche strecke 1 impuls entspricht und rechne damit. Damit 
bis Du relativ genau.

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Abwechselnd 2 und 3 in geschicktem Wechsel wäre am genauesten.. Hat
> sowas schonmal jemand gemacht?

Nein, hätte aber trotzdem einen Vorschlag:
#define ZAEHLER 171
#define NENNER   64

unsigned int zaehl(void) {
  static unsigned int mm, summe/*=ZAEHLER/2*/;

  if((summe+=NENNER) >= ZAEHLER) {
    summe -= ZAEHLER;
    mm++;
  }
  return mm;
}

Die Funktion zaehl wird für jeden Puls aufgerufen und liefert die
ganzzahlige Wegstrecke in mm zurück, wobei weder Multiplikationen noch
Divisionen benötigt werden. Der Umrechnungsfaktor muss als Bruch >1
vorliegen (2,671875=171/64). Je nach Startbedingung und gewünschtem
Rundungsverfahren kann es sinnvoll sein, summe mit ZAEHLER/2 statt mit
0 zu initialisieren.

Das Verfahren entspricht dem Bresenham-Algorithmus zum Zeichnen von
Geraden auf Rasterausgabegeräten:

  http://de.wikipedia.org/wiki/Bresenham-Algorithmus

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach, ich sehe jetzt erst, dass das das Forum "FPGA, VHDL & Co." ist. Da
hat natürlich C nichts zu suchen. Betrachte den Code also als Pseudocode
und setze ihn in VHDL oder Verilog um. Das Verfahren ist gerade auch für
die Implementierung in Hardware gut geeignet,das es keine komplizierten
Rechenoperationen benötigt.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Durch 2**n Zahlen kann problemlos geteilt werden. Und weil sich der 
Bruch 171/64 als 171/(2**6) schreiben lässt, kann man das auch so 
machen:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity EncScale is
    Port ( posin  : in  STD_LOGIC_VECTOR (31 downto 0);
           posout : out STD_LOGIC_VECTOR (31 downto 0));
end EncScale;

architecture Behavioral of EncScale is
  signal poscnt : integer;
  signal posmm  : integer;
begin
  poscnt <= to_integer(signed(posin));
  posmm  <= (poscnt*171)/64; -- 171/64 = 2,671875
  posout <= std_logic_vector(to_signed(posmm,32));
end Behavioral;
posin enthält die Zählimpulse vom Geber, nur auf diesem Wert wirkt sich 
der Encoder unmittelbar aus. In der Hardware wird nicht geteilt, sondern 
nach der Multiplikation einfach die unteren 6 Bits abgeschnitten. Und 
weil der Multiplizierer ein kombinatrisches Element ist, muß das ganze 
nicht mal getaktet sein ;-)

Autor: Thomas Reinemann (Firma: abaxor engineering) (abaxor)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
yalu wrote:
>
> Das Verfahren entspricht dem Bresenham-Algorithmus zum Zeichnen von
> Geraden auf Rasterausgabegeräten:
>
>   http://de.wikipedia.org/wiki/Bresenham-Algorithmus

Ein Delta-Sigma-Modulator macht dasselbe. Das interessante daran ist, 
dass beide Verfahren zu Beginn der 1960er Jahre entstanden sind.

Tom

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist so wunderam nicht wenn man bedenkt, dass da Patente im Spiel 
waren. Ist so änhlich wie das dem Sigma-Delta-Prinzip hinterliegende 
Single-Slopw-Verfahren, welches es kurz nach der Patentierung auch als 
Dual- und Quadro-Verfahren gab.

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]
  • [vhdl]VHDL-Code[/vhdl]
  • [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.