<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>https://www.mikrocontroller.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Claus+w</id>
	<title>Mikrocontroller.net - Benutzerbeiträge [de]</title>
	<link rel="self" type="application/atom+xml" href="https://www.mikrocontroller.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Claus+w"/>
	<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/articles/Spezial:Beitr%C3%A4ge/Claus_w"/>
	<updated>2026-04-10T21:41:28Z</updated>
	<subtitle>Benutzerbeiträge</subtitle>
	<generator>MediaWiki 1.39.7</generator>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Kategorie:Mechanik&amp;diff=105953</id>
		<title>Kategorie:Mechanik</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Kategorie:Mechanik&amp;diff=105953"/>
		<updated>2023-03-17T18:40:59Z</updated>

		<summary type="html">&lt;p&gt;Claus w: Neue, mechanische Kategorie.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Elektronische Projekte sind teils mechanisch, wegen der Aktuatoren.&lt;br /&gt;
&lt;br /&gt;
* Elektromotoren und deren Steuerung.&lt;br /&gt;
* Werkstücke maßgerecht lasern und zerspanen.&lt;br /&gt;
* Verformung von Bauteilen unter Temperatureinfluss.  &lt;br /&gt;
* Elektronisch gesteuerte Pumpen.&lt;br /&gt;
&lt;br /&gt;
[Kategorie:!Hauptkategorie]]&lt;/div&gt;</summary>
		<author><name>Claus w</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Hauptseite&amp;diff=105952</id>
		<title>Hauptseite</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Hauptseite&amp;diff=105952"/>
		<updated>2023-03-17T18:29:43Z</updated>

		<summary type="html">&lt;p&gt;Claus w: Kategorie &amp;quot;Mechanik&amp;quot; hinzugefügt.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{| width=&amp;quot;100%&amp;quot;&lt;br /&gt;
	&lt;br /&gt;
|-&lt;br /&gt;
	&lt;br /&gt;
|style=&amp;quot;vertical-align:top&amp;quot; |&lt;br /&gt;
	&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin: 0; margin-right:10px; border: 1px solid #dfdfdf; padding: 1em 1em 1em 1em; background-color:#F8F8FF; align:right;&amp;quot;&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
Diese Artikelsammlung ist ein &amp;quot;Wiki&amp;quot;, das bedeutet jeder kann etwas an den bestehenden Artikeln verändern oder eigene Artikel erstellen.&amp;lt;/div&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin: 0; margin-top:10px; margin-right:10px; border: 1px solid #dfdfdf; padding: 0em 1em 1em 1em; background-color:#FFfFeF; align:right;&amp;quot;&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
== Artikelübersicht ==&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
* [[Spezial:Allpages|&#039;&#039;&#039;Alle Artikel&#039;&#039;&#039;]] - Eine Liste mit allen {{NUMBEROFARTICLES}} Artikeln im Wiki.&lt;br /&gt;
	&lt;br /&gt;
* [[Spezial:Kategorien|Alle Kategorien]] - Eine Liste aller Kategorien, also aller &amp;quot;Artikel-Schubladen&amp;quot;&lt;br /&gt;
	&lt;br /&gt;
* [[Spezial:Newpages|Neue Artikel]] - Eine Liste der zuletzt hinzugefügten Artikel.&lt;br /&gt;
	&lt;br /&gt;
* [[Spezial:Suche|Suche]] - Volltextsuche&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
== Artikel nach Kategorien ==  		&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
=== Grundlagen ===&lt;br /&gt;
	&lt;br /&gt;
&amp;lt;DynamicPageList&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
category             = Grundlagen&lt;br /&gt;
	&lt;br /&gt;
notcategory = Aufgegeben&lt;br /&gt;
	&lt;br /&gt;
count                = 500&lt;br /&gt;
	&lt;br /&gt;
ordermethod          = sortkey&lt;br /&gt;
	&lt;br /&gt;
order     = ascending&lt;br /&gt;
	&lt;br /&gt;
mode=inline&lt;br /&gt;
	&lt;br /&gt;
&amp;lt;/DynamicPageList&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
=== Datenübertragung ===&lt;br /&gt;
	&lt;br /&gt;
&amp;lt;DynamicPageList&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
category             = Datenübertragung&lt;br /&gt;
	&lt;br /&gt;
notcategory = Aufgegeben&lt;br /&gt;
	&lt;br /&gt;
count                = 500&lt;br /&gt;
	&lt;br /&gt;
ordermethod          = sortkey&lt;br /&gt;
	&lt;br /&gt;
order     = ascending&lt;br /&gt;
	&lt;br /&gt;
mode=inline&lt;br /&gt;
	&lt;br /&gt;
&amp;lt;/DynamicPageList&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
=== Projekte ===&lt;br /&gt;
	&lt;br /&gt;
&amp;lt;DynamicPageList&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
category             = Projekte&lt;br /&gt;
	&lt;br /&gt;
notcategory = Aufgegeben&lt;br /&gt;
	&lt;br /&gt;
count                = 500&lt;br /&gt;
	&lt;br /&gt;
ordermethod          = sortkey&lt;br /&gt;
	&lt;br /&gt;
order     = ascending&lt;br /&gt;
	&lt;br /&gt;
mode=inline&lt;br /&gt;
	&lt;br /&gt;
&amp;lt;/DynamicPageList&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
=== AVR-Tutorial ===&lt;br /&gt;
	&lt;br /&gt;
&amp;lt;DynamicPageList&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
category             = AVR-Tutorial&lt;br /&gt;
	&lt;br /&gt;
notcategory = Aufgegeben&lt;br /&gt;
	&lt;br /&gt;
count                = 500&lt;br /&gt;
	&lt;br /&gt;
ordermethod          = sortkey&lt;br /&gt;
	&lt;br /&gt;
order     = ascending&lt;br /&gt;
	&lt;br /&gt;
mode=inline&lt;br /&gt;
	&lt;br /&gt;
&amp;lt;/DynamicPageList&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
=== ARM ===&lt;br /&gt;
	&lt;br /&gt;
&amp;lt;DynamicPageList&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
category             = ARM&lt;br /&gt;
	&lt;br /&gt;
notcategory = Aufgegeben&lt;br /&gt;
	&lt;br /&gt;
count                = 500&lt;br /&gt;
	&lt;br /&gt;
ordermethod          = sortkey&lt;br /&gt;
	&lt;br /&gt;
order     = ascending&lt;br /&gt;
	&lt;br /&gt;
mode=inline&lt;br /&gt;
	&lt;br /&gt;
&amp;lt;/DynamicPageList&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
=== AVR ===&lt;br /&gt;
	&lt;br /&gt;
&amp;lt;DynamicPageList&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
category             = AVR&lt;br /&gt;
	&lt;br /&gt;
notcategory = Aufgegeben&lt;br /&gt;
	&lt;br /&gt;
count                = 500&lt;br /&gt;
	&lt;br /&gt;
ordermethod          = sortkey&lt;br /&gt;
	&lt;br /&gt;
order     = ascending&lt;br /&gt;
	&lt;br /&gt;
mode=inline&lt;br /&gt;
	&lt;br /&gt;
&amp;lt;/DynamicPageList&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
=== AVR32 ===&lt;br /&gt;
	&lt;br /&gt;
&amp;lt;DynamicPageList&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
category             = AVR32&lt;br /&gt;
	&lt;br /&gt;
notcategory = Aufgegeben&lt;br /&gt;
	&lt;br /&gt;
count                = 500&lt;br /&gt;
	&lt;br /&gt;
ordermethod          = lastedit&lt;br /&gt;
	&lt;br /&gt;
mode=inline&lt;br /&gt;
	&lt;br /&gt;
&amp;lt;/DynamicPageList&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
=== FPGA &amp;amp; Co. ===&lt;br /&gt;
	&lt;br /&gt;
&amp;lt;DynamicPageList&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
category             = FPGA und Co&lt;br /&gt;
	&lt;br /&gt;
notcategory = Aufgegeben&lt;br /&gt;
	&lt;br /&gt;
count                = 500&lt;br /&gt;
	&lt;br /&gt;
ordermethod          = sortkey&lt;br /&gt;
	&lt;br /&gt;
order     = ascending&lt;br /&gt;
	&lt;br /&gt;
mode=inline&lt;br /&gt;
	&lt;br /&gt;
&amp;lt;/DynamicPageList&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
=== DSP (Digitale Signalverarbeitung) ===&lt;br /&gt;
	&lt;br /&gt;
&amp;lt;DynamicPageList&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
category             = DSP&lt;br /&gt;
	&lt;br /&gt;
notcategory = Aufgegeben&lt;br /&gt;
	&lt;br /&gt;
count                = 500&lt;br /&gt;
	&lt;br /&gt;
ordermethod          = sortkey&lt;br /&gt;
	&lt;br /&gt;
order     = ascending&lt;br /&gt;
	&lt;br /&gt;
mode=inline&lt;br /&gt;
	&lt;br /&gt;
&amp;lt;/DynamicPageList&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
=== Mikrocontrollerfamilien ===&lt;br /&gt;
	&lt;br /&gt;
&amp;lt;DynamicPageList&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
category             = Mikrocontroller&lt;br /&gt;
	&lt;br /&gt;
notcategory = Aufgegeben&lt;br /&gt;
	&lt;br /&gt;
count                = 500&lt;br /&gt;
	&lt;br /&gt;
ordermethod          = sortkey&lt;br /&gt;
	&lt;br /&gt;
order     = ascending&lt;br /&gt;
	&lt;br /&gt;
mode=inline&lt;br /&gt;
	&lt;br /&gt;
&amp;lt;/DynamicPageList&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
=== Leistungselektronik===&lt;br /&gt;
	&lt;br /&gt;
&amp;lt;DynamicPageList&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
category             = Leistungselektronik&lt;br /&gt;
	&lt;br /&gt;
notcategory = Aufgegeben&lt;br /&gt;
	&lt;br /&gt;
count                = 500&lt;br /&gt;
	&lt;br /&gt;
ordermethod          = sortkey&lt;br /&gt;
	&lt;br /&gt;
order     = ascending&lt;br /&gt;
	&lt;br /&gt;
mode=inline&lt;br /&gt;
	&lt;br /&gt;
&amp;lt;/DynamicPageList&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
===Platinen===&lt;br /&gt;
	&lt;br /&gt;
&amp;lt;DynamicPageList&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
category             = Platinen&lt;br /&gt;
	&lt;br /&gt;
notcategory = Aufgegeben&lt;br /&gt;
	&lt;br /&gt;
count                = 500&lt;br /&gt;
	&lt;br /&gt;
ordermethod          = sortkey&lt;br /&gt;
	&lt;br /&gt;
order     = ascending&lt;br /&gt;
	&lt;br /&gt;
mode=inline&lt;br /&gt;
	&lt;br /&gt;
&amp;lt;/DynamicPageList&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
===Schaltplaneditoren===&lt;br /&gt;
	&lt;br /&gt;
&amp;lt;DynamicPageList&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
category             = Schaltplaneditoren&lt;br /&gt;
	&lt;br /&gt;
count                = 500&lt;br /&gt;
	&lt;br /&gt;
ordermethod          = sortkey&lt;br /&gt;
	&lt;br /&gt;
order     = ascending&lt;br /&gt;
	&lt;br /&gt;
mode=inline&lt;br /&gt;
	&lt;br /&gt;
&amp;lt;/DynamicPageList&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
===Lieferanten===&lt;br /&gt;
	&lt;br /&gt;
&amp;lt;DynamicPageList&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
category             = Lieferanten&lt;br /&gt;
	&lt;br /&gt;
notcategory = Aufgegeben&lt;br /&gt;
	&lt;br /&gt;
count                = 500&lt;br /&gt;
	&lt;br /&gt;
ordermethod          = sortkey&lt;br /&gt;
	&lt;br /&gt;
order     = ascending&lt;br /&gt;
	&lt;br /&gt;
mode=inline&lt;br /&gt;
	&lt;br /&gt;
&amp;lt;/DynamicPageList&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
=== Weitere interessante Kategorien ===&lt;br /&gt;
	&lt;br /&gt;
* [[:Kategorie:Algorithmen und Arithmetik|Algorithmen und Arithmetik]]&lt;br /&gt;
	&lt;br /&gt;
* [[:Kategorie:Bauteile|Bauteile]]&lt;br /&gt;
	&lt;br /&gt;
* [[:Kategorie:Beruf und Wirtschaft|Beruf und Wirtschaft]]&lt;br /&gt;
	&lt;br /&gt;
* [[:Kategorie:Boards|Boards]]&lt;br /&gt;
	&lt;br /&gt;
* [[:Kategorie:Displays und Anzeigen|Displays und Anzeigen]]&lt;br /&gt;
	&lt;br /&gt;
* [[:Kategorie:Entwicklungstools|Entwicklungstools]]&lt;br /&gt;
	&lt;br /&gt;
* [[:Kategorie:Multimedia|Multimedia]]&lt;br /&gt;
	&lt;br /&gt;
* [[:Kategorie:Oszilloskope und Analyzer|Oszilloskope und Analyzer]]&lt;br /&gt;
	&lt;br /&gt;
* [[:Kategorie:Sensorik|Sensorik]]&lt;br /&gt;
	&lt;br /&gt;
* [[:Kategorie:Spannungsversorgung und Energiequellen|Spannungsversorgung und Energiequellen]]&lt;br /&gt;
	&lt;br /&gt;
* [[:Kategorie:Speicher und Dateisysteme|Speicher und Dateisysteme]]&lt;br /&gt;
	&lt;br /&gt;
* [[:Kategorie:Timer und Uhren|Timer und Uhren]]&lt;br /&gt;
	&lt;br /&gt;
* [[:Kategorie:Verbrauchsmaterial|Verbrauchsmaterial]]&lt;br /&gt;
	&lt;br /&gt;
* [[:Kategorie:Mechanisches CAD-Programm|Mechanische CAD Programme (2D/3D) und 3D Modelling]]&lt;br /&gt;
&lt;br /&gt;
* [[:Kategorie:Mechanik]]&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
===Sonstiges===&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
* [[Linksammlung]]&lt;br /&gt;
	&lt;br /&gt;
* [[Datenblätter]]&lt;br /&gt;
	&lt;br /&gt;
* [[Spezial:Nicht kategorisierte Seiten|Artikel ohne Kategorie]]&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
=== Tipps für Autoren ===&lt;br /&gt;
	&lt;br /&gt;
&amp;lt;DynamicPageList&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
category             = Tipps für Autoren&lt;br /&gt;
	&lt;br /&gt;
notcategory = Aufgegeben&lt;br /&gt;
	&lt;br /&gt;
count                = 500&lt;br /&gt;
	&lt;br /&gt;
ordermethod          = lastedit&lt;br /&gt;
	&lt;br /&gt;
mode=inline&lt;br /&gt;
	&lt;br /&gt;
&amp;lt;/DynamicPageList&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
| width=&amp;quot;40%&amp;quot; style=&amp;quot;vertical-align:top&amp;quot; |&lt;br /&gt;
	&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin:0;  border:1px solid #dfdfdf; padding: 0em 1em 1em 1em; background-color:#efefef; align:left;&amp;quot;&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
=== Kann ich wirklich &amp;quot;einfach so&amp;quot; irgendetwas an den Seiten ändern? ===&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
Ja! Um eine Seite zu ändern reicht ein Klick auf den &amp;quot;Seite bearbeiten&amp;quot; Link.&lt;br /&gt;
	&lt;br /&gt;
Aber: Bitte lies Dir vorher die [[Uc-wiki:Wie man eine Seite bearbeitet|Bearbeitungshinweise]] durch und schau Dir ein paar der anderen Seiten an, um zu sehen wie das Ganze funktioniert.&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
=== Gibt es einen Testbereich, wo man das Ganze mal ausprobieren kann? ===&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
Ja - dafür gibt es die [[Testseite]].&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
=== Wie kann ich neue Seiten erstellen? ===&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
[[Anleitung: Artikel erstellen]]&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
=== Wozu ist der &amp;quot;Diskussion&amp;quot;-Link? ===&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
Auf den Diskussionsseiten kann man Kommentare, Kritik oder Fragen zum jeweiligen Artikel unterbringen.&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
=== Was ist dieses Wiki? ===&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
Dieses Wiki ist eine Artikelsammlung. Unter Artikeln sind dabei Einträge zu verstehen, die über reine enzyklopädische Grundlagenartikel hinausgehen. Solche Einträge sind besser in der [http://de.wikipedia.org Wikipedia] aufgehoben. Zu den Beiträgen dieses Wikis gehören daher Tutorials, Projektbeschreibungen sowie Erfahrungsberichte und Problemlösungen in der Elektronik im Allgemeinen und hinsichtlich Mikrocontrollern im Speziellen.&lt;br /&gt;
	&lt;br /&gt;
 &lt;br /&gt;
	&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
|}&lt;br /&gt;
	&lt;br /&gt;
 &lt;br /&gt;
	&lt;br /&gt;
__NOTOC__&lt;br /&gt;
	&lt;br /&gt;
__NOEDITSECTION__&lt;/div&gt;</summary>
		<author><name>Claus w</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Mikromotor_Kennlinie_messen&amp;diff=105951</id>
		<title>Mikromotor Kennlinie messen</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Mikromotor_Kennlinie_messen&amp;diff=105951"/>
		<updated>2023-03-17T18:29:17Z</updated>

		<summary type="html">&lt;p&gt;Claus w: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Vorrichtung mit Motor, Bremse und Lichtschranken&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Datei:TorqueSensor2.jpg|rahmenlos|Skizze]]&lt;br /&gt;
&lt;br /&gt;
Zweck um den Motor zu testen ist Drehzahl, Drehmoment und Wirkungsgrad zu erfahren. Beim entwickeln von Regelkreisen für Drehzahl und Drehmoment des Motors kann man mit der Test-Vorrichtung den Verlauf der Werte bei Änderung der Führungsgröße und der Störgröße messen (z.B. die Sprungantwort). Während die Feder gespannt wird, weichen die Werte ab.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Bereits aufgebaute Vorrichtung&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Datei:MotorTestMachine.jpg|rahmenlos|Skizze der Vorrichtung]]&lt;br /&gt;
&lt;br /&gt;
Auf dem Bild ist links eine handelsübliche Hysterese-Bremse für max. 20ooo RPM. Rechts befindet sich ein gewöhnlicher Modellbau-Motor als Testobjekt. Dazwischen ist auf den beiden Wellen je ein Flansch mit Mitnehmer montiert. Beide Mitnehmer spannen lastabhängig die Schenkelfeder. Auf beiden Mitnehmern sind auch Blenden angebracht, die die beiden Lichtschranken schalten. für 20ooo RPM beträgt die Frequenz 333Hz. Mit einem Zweistrahloszilloskop sieht man Drehzahl und Winkel der Feder (mit dem Cursor). Diese Idee habe ich aus diesem Forum und baute sie nach.&lt;br /&gt;
&lt;br /&gt;
[[Datei:HystereseBremse mit Halteblech.jpg|rahmenlos|Bremse und Halteblech]]&lt;br /&gt;
&lt;br /&gt;
Maßstab ist an den Schraubenbohrungen (M3) erkennbar. Die Hysterese-Bremse bremst durch absichtliche Ummagnetisierungsverluste die Welle mit einem Drehmoment, das einem angelegten Steuerstrom entspricht (aus einer Konstant-Stromquelle). Bei diesem Exemplar sind max. 50 Milli-Newton-Meter möglich. Die entnommene Leistung bestimmt sich aus &amp;quot; Drehzahl x Drehmoment x 6,28 &amp;quot; - Drehzahl hier pro Sekunde angegeben. Sie wird vollständig in Wärme umgesetzt. Die gesamte Vorrichtung kann statt mit der Schenkelfeder auch mit einer elastischen Kupplung betrieben werden, wobei man das Drehmoment nicht messen braucht sondern dem Datenblatt der Bremse entnehmen kann.&lt;br /&gt;
&lt;br /&gt;
[[Datei:Lichtschranke.jpg|rahmenlos|Flansche mit Blenden für die Lichtschranke]]&lt;br /&gt;
&lt;br /&gt;
Auf den Motorwellen sind Flansche angebracht, die bei jeder Umdrehung in einer bestimmten Winkelstellung die Lichtschranken schalten. Bei Stillstand kann man damit nicht arbeiten sondern muss den Winkel für das Drehmoment anderweitig messen. Ungenauigkeiten können auch durch Ripple und Rastmomente entstehen, die auf dem Umkreis unregelmäßig verteilt sind.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Auswertung&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Datei:TorqueSensor 1000mA.bmp|rahmenlos|Beide Lichtschranke bei der Arbeit (10 Watt).]]&lt;br /&gt;
&lt;br /&gt;
Das Schirmbild zeigt die Impulse beider Lichtschranken. Die Periode ergibt die Drehzahl (hier etwa 2200 RPM). Das Verschiebung der Flanken im Verhältnis zur Periode entspricht dem Drehwinkel der Feder (soll von Drehzahl NULL an aufaddiert werden, hier 398°).&lt;br /&gt;
&lt;br /&gt;
[[Datei:TorqueSprings.jpg|rahmenlos|TOR630L, 0.14 Nmm / °]]&lt;br /&gt;
&lt;br /&gt;
Derartige Spezialfedern werden teils nur gegen Firmenzugehörigkeit gehandelt. Die hier abgebildeten ALCOMEX-Federn waren frei erhältlich. Die kleinere der beiden mit der Bezeichnung TOR630L hat eine Federkonstante von 0,14 Nmm / °. Sie verträgt max. 394° (ist somit in dem Versuch überdehnt worden).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Rechenbeispiel&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Drehmoment bei ähnlichen Drehzahlen und unterschiedlich vorgegebener Bremswirkung&lt;br /&gt;
|-&lt;br /&gt;
! U/V !! I/A !! N/Hz !! PHI/°!! M/mNm !! P/W&lt;br /&gt;
|-&lt;br /&gt;
| 0 || 0 || 0 || 0 || 0 || 0&lt;br /&gt;
|-&lt;br /&gt;
| 10 || 0.5 || 43 || 179 || 25,1 || 6,8&lt;br /&gt;
|-&lt;br /&gt;
| 10 || 1,0 || 38 || 408 || 57,1 || 13.6&lt;br /&gt;
|-&lt;br /&gt;
| 10 || 1,5 || 37 || 613 || 85,8 || 19,9&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Man ermittelt das &amp;quot; Drehmoment = Winkel x Federkonstante &amp;quot; und setzt es in die Formel weiter oben ein um die Leistung auszurechnen. In der Rechnung in der Tabelle ist der Winkel für die Drehzahl NULL nicht ganz exakt. Bei der Rechnung nach elektrischen Werten kommt 30% weniger raus als bei den mech. Werten und das trotz dem Wirkungsgrad des Motors. Falls man es genauer braucht, ist eine Justierung bei Drehzahl NULL sicher möglich.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Medien&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Feder mit dem Motor spannen [ http://www.claus-wimmer.de/TorqueSpringOnly.mp4 ]&lt;br /&gt;
* Vorrichtung läuft mit langsamer Drehzahl [ http://www.claus-wimmer.de/MachineInAction.mp4 ]&lt;br /&gt;
&lt;br /&gt;
[[Category:Motoren]]&lt;br /&gt;
[[Category:Mechanik]]&lt;/div&gt;</summary>
		<author><name>Claus w</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Mikromotor_Kennlinie_messen&amp;diff=105950</id>
		<title>Mikromotor Kennlinie messen</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Mikromotor_Kennlinie_messen&amp;diff=105950"/>
		<updated>2023-03-17T16:37:35Z</updated>

		<summary type="html">&lt;p&gt;Claus w: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Vorrichtung mit Motor, Bremse und Lichtschranken&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Datei:TorqueSensor2.jpg|rahmenlos|Skizze]]&lt;br /&gt;
&lt;br /&gt;
Zweck um den Motor zu testen ist Drehzahl, Drehmoment und Wirkungsgrad zu erfahren. Beim entwickeln von Regelkreisen für Drehzahl und Drehmoment des Motors kann man mit der Test-Vorrichtung den Verlauf der Werte bei Änderung der Führungsgröße und der Störgröße messen (z.B. die Sprungantwort). Während die Feder gespannt wird, weichen die Werte ab.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Bereits aufgebaute Vorrichtung&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Datei:MotorTestMachine.jpg|rahmenlos|Skizze der Vorrichtung]]&lt;br /&gt;
&lt;br /&gt;
Auf dem Bild ist links eine handelsübliche Hysterese-Bremse für max. 20ooo RPM. Rechts befindet sich ein gewöhnlicher Modellbau-Motor als Testobjekt. Dazwischen ist auf den beiden Wellen je ein Flansch mit Mitnehmer montiert. Beide Mitnehmer spannen lastabhängig die Schenkelfeder. Auf beiden Mitnehmern sind auch Blenden angebracht, die die beiden Lichtschranken schalten. für 20ooo RPM beträgt die Frequenz 333Hz. Mit einem Zweistrahloszilloskop sieht man Drehzahl und Winkel der Feder (mit dem Cursor). Diese Idee habe ich aus diesem Forum und baute sie nach.&lt;br /&gt;
&lt;br /&gt;
[[Datei:HystereseBremse mit Halteblech.jpg|rahmenlos|Bremse und Halteblech]]&lt;br /&gt;
&lt;br /&gt;
Maßstab ist an den Schraubenbohrungen (M3) erkennbar. Die Hysterese-Bremse bremst durch absichtliche Ummagnetisierungsverluste die Welle mit einem Drehmoment, das einem angelegten Steuerstrom entspricht (aus einer Konstant-Stromquelle). Bei diesem Exemplar sind max. 50 Milli-Newton-Meter möglich. Die entnommene Leistung bestimmt sich aus &amp;quot; Drehzahl x Drehmoment x 6,28 &amp;quot; - Drehzahl hier pro Sekunde angegeben. Sie wird vollständig in Wärme umgesetzt. Die gesamte Vorrichtung kann statt mit der Schenkelfeder auch mit einer elastischen Kupplung betrieben werden, wobei man das Drehmoment nicht messen braucht sondern dem Datenblatt der Bremse entnehmen kann.&lt;br /&gt;
&lt;br /&gt;
[[Datei:Lichtschranke.jpg|rahmenlos|Flansche mit Blenden für die Lichtschranke]]&lt;br /&gt;
&lt;br /&gt;
Auf den Motorwellen sind Flansche angebracht, die bei jeder Umdrehung in einer bestimmten Winkelstellung die Lichtschranken schalten. Bei Stillstand kann man damit nicht arbeiten sondern muss den Winkel für das Drehmoment anderweitig messen. Ungenauigkeiten können auch durch Ripple und Rastmomente entstehen, die auf dem Umkreis unregelmäßig verteilt sind.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Auswertung&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Datei:TorqueSensor 1000mA.bmp|rahmenlos|Beide Lichtschranke bei der Arbeit (10 Watt).]]&lt;br /&gt;
&lt;br /&gt;
Das Schirmbild zeigt die Impulse beider Lichtschranken. Die Periode ergibt die Drehzahl (hier etwa 2200 RPM). Das Verschiebung der Flanken im Verhältnis zur Periode entspricht dem Drehwinkel der Feder (soll von Drehzahl NULL an aufaddiert werden, hier 398°).&lt;br /&gt;
&lt;br /&gt;
[[Datei:TorqueSprings.jpg|rahmenlos|TOR630L, 0.14 Nmm / °]]&lt;br /&gt;
&lt;br /&gt;
Derartige Spezialfedern werden teils nur gegen Firmenzugehörigkeit gehandelt. Die hier abgebildeten ALCOMEX-Federn waren frei erhältlich. Die kleinere der beiden mit der Bezeichnung TOR630L hat eine Federkonstante von 0,14 Nmm / °. Sie verträgt max. 394° (ist somit in dem Versuch überdehnt worden).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Rechenbeispiel&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Drehmoment bei ähnlichen Drehzahlen und unterschiedlich vorgegebener Bremswirkung&lt;br /&gt;
|-&lt;br /&gt;
! U/V !! I/A !! N/Hz !! PHI/°!! M/mNm !! P/W&lt;br /&gt;
|-&lt;br /&gt;
| 0 || 0 || 0 || 0 || 0 || 0&lt;br /&gt;
|-&lt;br /&gt;
| 10 || 0.5 || 43 || 179 || 25,1 || 6,8&lt;br /&gt;
|-&lt;br /&gt;
| 10 || 1,0 || 38 || 408 || 57,1 || 13.6&lt;br /&gt;
|-&lt;br /&gt;
| 10 || 1,5 || 37 || 613 || 85,8 || 19,9&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Man ermittelt das &amp;quot; Drehmoment = Winkel x Federkonstante &amp;quot; und setzt es in die Formel weiter oben ein um die Leistung auszurechnen. In der Rechnung in der Tabelle ist der Winkel für die Drehzahl NULL nicht ganz exakt. Bei der Rechnung nach elektrischen Werten kommt 30% weniger raus als bei den mech. Werten und das trotz dem Wirkungsgrad des Motors. Falls man es genauer braucht, ist eine Justierung bei Drehzahl NULL sicher möglich.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Medien&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Feder mit dem Motor spannen [ http://www.claus-wimmer.de/TorqueSpringOnly.mp4 ]&lt;br /&gt;
* Vorrichtung läuft mit langsamer Drehzahl [ http://www.claus-wimmer.de/MachineInAction.mp4 ]&lt;/div&gt;</summary>
		<author><name>Claus w</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Mikromotor_Kennlinie_messen&amp;diff=105949</id>
		<title>Mikromotor Kennlinie messen</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Mikromotor_Kennlinie_messen&amp;diff=105949"/>
		<updated>2023-03-17T16:25:27Z</updated>

		<summary type="html">&lt;p&gt;Claus w: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Vorrichtung mit Motor, Bremse und Lichtschranken&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Datei:TorqueSensor2.jpg|rahmenlos|Skizze]]&lt;br /&gt;
&lt;br /&gt;
Zweck um den Motor zu testen ist Drehzahl, Drehmoment und Wirkungsgrad zu erfahren. Beim entwickeln von Regelkreisen für Drehzahl und Drehmoment des Motors kann man mit der Test-Vorrichtung den Verlauf der Werte bei Änderung der Führungsgröße und der Störgröße messen (z.B. die Sprungantwort). Während die Feder gespannt wird, weichen die Werte ab.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Bereits aufgebaute Vorrichtung&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Datei:MotorTestMachine.jpg|rahmenlos|Skizze der Vorrichtung]]&lt;br /&gt;
&lt;br /&gt;
Auf dem Bild ist links eine handelsübliche Hysterese-Bremse für max. 20ooo RPM. Rechts befindet sich ein gewöhnlicher Modellbau-Motor als Testobjekt. Dazwischen ist auf den beiden Wellen je ein Flansch mit Mitnehmer montiert. Beide Mitnehmer spannen lastabhängig die Schenkelfeder. Auf beiden Mitnehmern sind auch Blenden angebracht, die die beiden Lichtschranken schalten. für 20ooo RPM beträgt die Frequenz 333Hz. Mit einem Zweistrahloszilloskop sieht man Drehzahl und Winkel der Feder (mit dem Cursor). Diese Idee habe ich aus diesem Forum und baute sie nach.&lt;br /&gt;
&lt;br /&gt;
[[Datei:HystereseBremse mit Halteblech.jpg|rahmenlos|Bremse und Halteblech]]&lt;br /&gt;
&lt;br /&gt;
Maßstab ist an den Schraubenbohrungen (M3) erkennbar. Die Hysterese-Bremse bremst durch absichtliche Ummagnetisierungsverluste die Welle mit einem Drehmoment, das einem angelegten Steuerstrom entspricht (aus einer Konstant-Stromquelle). Bei diesem Exemplar sind max. 50 Milli-Newton-Meter möglich. Die entnommene Leistung bestimmt sich aus &amp;quot; Drehzahl x Drehmoment x 6,28 &amp;quot; - Drehzahl hier pro Sekunde angegeben. Sie wird vollständig in Wärme umgesetzt. Die gesamte Vorrichtung kann statt mit der Schenkelfeder auch mit einer elastischen Kupplung betrieben werden, wobei man das Drehmoment nicht messen braucht sondern dem Datenblatt der Bremse entnehmen kann.&lt;br /&gt;
&lt;br /&gt;
[[Datei:Lichtschranke.jpg|rahmenlos|Flansche mit Blenden für die Lichtschranke]]&lt;br /&gt;
&lt;br /&gt;
Auf den Motorwellen sind Flansche angebracht, die bei jeder Umdrehung in einer bestimmten Winkelstellung die Lichtschranken schalten. Bei Stillstand kann man damit nicht arbeiten sondern muss den Winkel für das Drehmoment anderweitig messen. Ungenauigkeiten können auch durch Ripple und Rastmomente entstehen, die auf dem Umkreis unregelmäßig verteilt sind.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Auswertung&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Datei:TorqueSensor 1000mA.bmp|rahmenlos|Beide Lichtschranke bei der Arbeit (10 Watt).]]&lt;br /&gt;
&lt;br /&gt;
Das Schirmbild zeigt die Impulse beider Lichtschranken. Die Periode ergibt die Drehzahl (hier etwa 2200 RPM). Das Verschiebung der Flanken im Verhältnis zur Periode entspricht dem Drehwinkel der Feder (soll von Drehzahl NULL an aufaddiert werden, hier 398°).&lt;br /&gt;
&lt;br /&gt;
[[Datei:TorqueSprings.jpg|rahmenlos|TOR630L, 0.14 Nmm / °]]&lt;br /&gt;
&lt;br /&gt;
Derartige Spezialfedern werden teils nur gegen Firmenzugehörigkeit gehandelt. Die hier abgebildeten ALCOMEX-Federn waren frei erhältlich. Die kleinere der beiden mit der Bezeichnung TOR630L hat eine Federkonstante von 0,14 Nmm / °. Sie verträgt max. 394° (ist somit in dem Versuch überdehnt worden).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Rechenbeispiel&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Drehmoment bei ähnlichen Drehzahlen und unterschiedlich vorgegebener Bremswirkung&lt;br /&gt;
|-&lt;br /&gt;
! U/V !! I/A !! N/Hz !! PHI/°!! M/mNm !! P/W&lt;br /&gt;
|-&lt;br /&gt;
| 0 || 0 || 0 || 0 || 0 || 0&lt;br /&gt;
|-&lt;br /&gt;
| 10 || 0.5 || 43 || 179 || 25,1 || 6,8&lt;br /&gt;
|-&lt;br /&gt;
| 10 || 1,0 || 38 || 408 || 57,1 || 13.6&lt;br /&gt;
|-&lt;br /&gt;
| 10 || 1,5 || 37 || 613 || 85,8 || 19,9&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Man ermittelt das &amp;quot; Drehmoment = Winkel x Federkonstante &amp;quot; und setzt es in die Formel weiter oben ein um die Leistung auszurechnen. In der Rechnung in der Tabelle ist der Winkel für die Drehzahl NULL nicht ganz exakt. Bei der Rechnung nach elektrischen Werten kommt 30% weniger raus als bei den mech. Werten und das trotz dem Wirkungsgrad des Motors. Falls man es genauer braucht, ist eine Justierung bei Drehzahl NULL sicher möglich.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Medien&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Claus w</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Mikromotor_Kennlinie_messen&amp;diff=105948</id>
		<title>Mikromotor Kennlinie messen</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Mikromotor_Kennlinie_messen&amp;diff=105948"/>
		<updated>2023-03-17T16:02:16Z</updated>

		<summary type="html">&lt;p&gt;Claus w: Zusammenhang zwischen U, I, M und RPM für Motoren mit 20ooo RPM mechanisch messen&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Vorrichtung mit Motor, Bremse und Lichtschranken&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Datei:TorqueSensor2.jpg|rahmenlos|Skizze]]&lt;br /&gt;
&lt;br /&gt;
Zweck um den Motor zu testen ist Drehzahl, Drehmoment und Wirkungsgrad zu erfahren. Beim entwickeln von Regelkreisen für Drehzahl und Drehmoment des Motors kann man mit der Test-Vorrichtung den Verlauf der Werte bei Änderung der Führungsgröße und der Störgröße messen (z.B. die Sprungantwort). Während die Feder gespannt wird, weichen die Werte ab.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Bereits aufgebaute Vorrichtung&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Datei:MotorTestMachine.jpg|rahmenlos|Skizze der Vorrichtung]]&lt;br /&gt;
&lt;br /&gt;
Auf dem Bild sieht man links eine handelsübliche Hysterese-Bremse für max. 20ooo RPM. Rechts befindet sich ein gewöhnlicher Modellbau-Motor als Testobjekt. Dazwischen ist auf den beiden Wellen je ein Flansch mit Mitnehmer montiert. Beide Mitnehmer spannen lastabhängig die Schenkelfeder. Auf beiden Mitnehmern sind auch Blenden angebracht, die die beiden Lichtschranken schalten. für 20ooo RPM beträgt die Frequenz 333Hz. Mit einem Zweistrahloszilloskop kann man Drehzahl und Winkel der Feder (mit dem Cursor) ausmessen. Diese Idee habe ich aus diesem Forum und baute sie nach.&lt;br /&gt;
&lt;br /&gt;
[[Datei:HystereseBremse mit Halteblech.jpg|rahmenlos|Bremse und Halteblech]]&lt;br /&gt;
&lt;br /&gt;
Maßstab ist an den Schraubenbohrungen (M3) erkennbar. Die Hysterese-Bremse bremst durch absichtliche Ummagnetisierungsverluste die Welle mit einem Drehmoment, das einem angelegten Steuerstrom entspricht (aus einer Konstant-Stromquelle). Bei diesem Exemplar kann man max. 50 Milli-Newton-Meter abfordern. Die entnommene Leistung bestimmt sich aus &amp;quot; Drehzahl x Drehmoment x 6,28 &amp;quot; - Drehzahl hier pro Sekunde angegeben. Sie wird vollständig in Wärme umgesetzt. Die gesamte Vorrichtung kann statt mit der Schenkelfeder auch mit einer elastischen Kupplung betrieben werden, wobei man das Drehmoment nicht messen braucht sondern dem Datenblatt der Bremse entnehmen kann. Dabei muss man aber die Hysterese berücksichtigen (Spiel rausnehmen). Andererseits kann man auch mit Schenkelfeder ohne Hysterese-Bremse arbeiten und die Leistung mit einem elektr. Generator entnehmen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:Lichtschranke.jpg|rahmenlos|Flansche mit Blenden für die Lichtschranke]]&lt;br /&gt;
&lt;br /&gt;
Auf den Motorwellen sind Flansche angebracht, die bei jeder Umdrehung in einer bestimmten Winkelstellung die Lichtschranken schalten. Bei Stillstand kann man damit nicht arbeiten sondern muss den Winkel für das Drehmoment anderweitig messen. Ungenauigkeiten können auch durch Ripple und Rastmomente entstehen, die auf dem Umkreis unregelmäßig verteilt sind.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Auswertung&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Datei:TorqueSensor 1000mA.bmp|rahmenlos|Beide Lichtschranke bei der Arbeit (10 Watt).]]&lt;br /&gt;
&lt;br /&gt;
Das Schirmbild zeigt die Impulse beider Lichtschranken die man mit dem Cursor messen kann. Die Periode ergibt die Drehzahl (hier etwa 2200 RPM). Das Verschiebung der Flanken im Verhältnis zur Periode entspricht dem Drehwinkel der Feder (soll von Drehzahl NULL an aufaddiert werden, hier 398°).&lt;br /&gt;
&lt;br /&gt;
[[Datei:TorqueSprings.jpg|rahmenlos|TOR630L, 0.14Nmm/°]]&lt;br /&gt;
&lt;br /&gt;
Derartige Spezialfedern werden teils nur gegen Firmenzugehörigkeit gehandelt. Die hier abgebildeten ALCOMEX-Federn waren frei erhältlich. Die kleinere der beiden mit der Bezeichnung TOR630L hat eine Federkonstante von 0,14Nmm je °. Sie kann 394° verdreht werden (ist somit in dem Versuch überdehnt worden). Falls erforderlich kann man die Enden kürzen und mit Zangen ein wenig verbiegen.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Rechenbeispiel&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Drehmoment bei ähnlichen Drehzahlen und unterschiedlich vorgegebener Bremswirkung&lt;br /&gt;
|-&lt;br /&gt;
! U/V !! I/A !! N/Hz !! PHI/°!! M/mNm !! P/W&lt;br /&gt;
|-&lt;br /&gt;
| 0 || 0 || 0 || 0 || 0 || 0&lt;br /&gt;
|-&lt;br /&gt;
| 10 || 0.5 || 43 || 179 || 25,1 || 6,8&lt;br /&gt;
|-&lt;br /&gt;
| 10 || 1,0 || 38 || 408 || 57,1 || 13.6&lt;br /&gt;
|-&lt;br /&gt;
| 10 || 1,5 || 37 || 613 || 85,8 || 19,9&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Man ermittelt das &amp;quot; Drehmoment = Winkel x Federkonstante &amp;quot; und setzt es in die Formel weiter oben ein um die Leistung auszurechnen. In der Rechnung in der Tabelle ist der Winkel für die Drehzahl NULL nicht ganz exakt. Bei der Rechnung nach elektrischen Werten kommt 30% weniger raus als bei den mech. Werten und das trotz dem Wirkungsgrad des Motors. Falls man es genauer braucht, ist eine Justierung bei Drehzahl NULL sicher möglich.&lt;/div&gt;</summary>
		<author><name>Claus w</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Datei:TorqueSprings.jpg&amp;diff=105947</id>
		<title>Datei:TorqueSprings.jpg</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Datei:TorqueSprings.jpg&amp;diff=105947"/>
		<updated>2023-03-17T15:33:03Z</updated>

		<summary type="html">&lt;p&gt;Claus w: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Alcomex-Schenkelfedern.&lt;/div&gt;</summary>
		<author><name>Claus w</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Datei:TorqueSensor_1000mA.bmp&amp;diff=105946</id>
		<title>Datei:TorqueSensor 1000mA.bmp</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Datei:TorqueSensor_1000mA.bmp&amp;diff=105946"/>
		<updated>2023-03-17T15:27:43Z</updated>

		<summary type="html">&lt;p&gt;Claus w: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Beide Lichtschranke im Schüler-Oszilloskop.&lt;/div&gt;</summary>
		<author><name>Claus w</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Datei:Lichtschranke.jpg&amp;diff=105944</id>
		<title>Datei:Lichtschranke.jpg</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Datei:Lichtschranke.jpg&amp;diff=105944"/>
		<updated>2023-03-17T15:18:44Z</updated>

		<summary type="html">&lt;p&gt;Claus w: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Blenden am Flansch steuern die Lichtschranke.&lt;/div&gt;</summary>
		<author><name>Claus w</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Datei:HystereseBremse_mit_Halteblech.jpg&amp;diff=105943</id>
		<title>Datei:HystereseBremse mit Halteblech.jpg</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Datei:HystereseBremse_mit_Halteblech.jpg&amp;diff=105943"/>
		<updated>2023-03-17T15:09:35Z</updated>

		<summary type="html">&lt;p&gt;Claus w: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Elektrisch gesteuerte Bremse die Ummagnetisierungsverluste nutzt.&lt;/div&gt;</summary>
		<author><name>Claus w</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Datei:MotorTestMachine.jpg&amp;diff=105942</id>
		<title>Datei:MotorTestMachine.jpg</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Datei:MotorTestMachine.jpg&amp;diff=105942"/>
		<updated>2023-03-17T15:00:00Z</updated>

		<summary type="html">&lt;p&gt;Claus w: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Mikromotor testen und Teile klein halten wegen hoher Drehzahlen.&lt;/div&gt;</summary>
		<author><name>Claus w</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Datei:TorqueSensor2.jpg&amp;diff=105941</id>
		<title>Datei:TorqueSensor2.jpg</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Datei:TorqueSensor2.jpg&amp;diff=105941"/>
		<updated>2023-03-17T14:47:55Z</updated>

		<summary type="html">&lt;p&gt;Claus w: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Die Schenkelfeder zwischen Motor und Bremse verdreht sich bei Last. Der Drehwinkel ist proportional zum Drehmoment.&lt;/div&gt;</summary>
		<author><name>Claus w</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Datei:TorqueSensor.jpg&amp;diff=105940</id>
		<title>Datei:TorqueSensor.jpg</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Datei:TorqueSensor.jpg&amp;diff=105940"/>
		<updated>2023-03-17T14:31:49Z</updated>

		<summary type="html">&lt;p&gt;Claus w: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In der Vorrichtung ist zwischen Motor und Bremse eine Schenkelfeder eingebaut deren Verdrehung ein Maß für das Drehmoment an der Motor-Welle ist.&lt;/div&gt;</summary>
		<author><name>Claus w</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Hilbert-Transformator_(Phasenschieber)_mit_ATmega&amp;diff=102911</id>
		<title>Hilbert-Transformator (Phasenschieber) mit ATmega</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Hilbert-Transformator_(Phasenschieber)_mit_ATmega&amp;diff=102911"/>
		<updated>2021-01-09T23:33:37Z</updated>

		<summary type="html">&lt;p&gt;Claus w: /* Hilbert Transformator nach der FIR-Methode */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Dieser Artikel ist eine Fortsetzung von [[Digitalfilter mit ATmega]] und behandelt ein spezielles Digitalfilter namens Hilbert-Transformator.&lt;br /&gt;
&lt;br /&gt;
Neben den üblichen Filtern, Tiefpass, Hochpass, Bandpass und Bandsperre, gibt es einige weitere Typen. In der Literatur findet man u.a. noch den Allpass, Phasenschieber, Integrator und Differentiator.&lt;br /&gt;
&lt;br /&gt;
===Der Hilbert-Transformator, ein Breitband-90-Grad-Phasenschieber===&lt;br /&gt;
&lt;br /&gt;
In den Lehrbüchern wird er völlig zu Unrecht eher am Rande abgehandelt. Tatsächlich findet man ihn in allen Schaltungen zur Datenübertragung, zu Modulation oder Demodulation mit I/Q-Mischern, im „Software-defined radio“.&lt;br /&gt;
&lt;br /&gt;
Auch ein Hilbert-Transformator kann mithilfe von Scilab berechnet werden. Allerdings gibt es keine fertige Software, man muss sich durch einige Literatur hindurchfressen, z.&amp;amp;nbsp;B. ISBN 0471619957 Sanjit Mitra, Handbook for DSP (1993), Kapitel „Special Filter Designs“ von [https://web.archive.org/web/20100610031102/http://faculty.cua.edu/regalia/ Phillip Regalia].&lt;br /&gt;
[https://web.itu.edu.tr/hulyayalcin/Signal_Processing_Books/DSP_Applications_Mitra.pdf Matlab-Plots dazu hier ab Seitenzahl 41]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
GNU Octave stellt die Hilbert-Transformation und den Parks-McClellan-hilbert-FIR-Filterentwurf im [http://octave.sourceforge.net/signal/function/remez.html octave-forge Paket &amp;quot;signal&amp;quot;] zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
Eine Fundgrube sind die Matlab-Texte von Prof. Schüssler, die vorab 1998 zum  zweiten Band seines Lehrbuchs auf seiner Webseite veröffentlicht wurden. Inzwischen ist der erste Band in der fünften Auflage erschienen [http://www.springer.com/engineering/signals/book/978-3-540-78250-6 ISBN 9783540782506] , der zweite Band ISBN 9783642011184 2010 erstmalig erschienen,  [http://www.lms.lnt.de/forschung/veroeffentlichungen/buecher/dsv.shtml Software-Download hier] aber die Webseite ist nach seinem Tod 2007 abgeschaltet. Zum Glück gibt es das  &lt;br /&gt;
[http://web.archive.org/web/20041206171820/www.nt.e-technik.uni-erlangen.de/~hws/dsv2programs/index.html  Webarchiv], wo die Texte noch zu finden sind.&lt;br /&gt;
&lt;br /&gt;
Zu dieser Zeit waren die Matlab-Programme noch nicht in „Toolboxen“ untergebracht, deren Funktion von außen nicht mehr sichtbar ist. Daher lassen sie sich relativ einfach in Scilab oder Octave übersetzen.&lt;br /&gt;
&lt;br /&gt;
Vier Versionen von Hilbert-Transformatoren werden hier berechnet: &lt;br /&gt;
* FIR-Hilbert, aufwendig, aber streng linearphasig, der bekannteste Typ, da schon lange mit dem Matlab-Befehl remez / firpm und Parameter &#039;hilbert&#039; berechenbar. Mit dem octave-forge Paket &amp;quot;signal&amp;quot; ist remez mit &amp;quot;hilbert&amp;quot; verfügbar. Scilab kennt diesen Parameter nicht.&lt;br /&gt;
* näherungsweise linearphasiger IIR-Hilbert, maximal flach,&lt;br /&gt;
* näherungsweise linearphasiger IIR-Hilbert, Tschebyscheff &lt;br /&gt;
* minimalphasiger IIR-Hilbert, kompakt, aber mit großen Gruppenlaufzeitschwankungen, eher für Audioanwendungen als Digitalsignale.&lt;br /&gt;
&lt;br /&gt;
Im Artikel von Schüßler/Steffen (siehe unten) sind in zwei vergleichenden Beispielen die Gruppenlaufzeitschwankungen des maximal Flachen etwa halb so groß, des Minimalphasigen etwa fünf Mal so groß wie die Tschbyscheff-Version.&lt;br /&gt;
&lt;br /&gt;
Zumindest der kompakte IIR-Hilbert lässt sich auch in einem ATmega unterbringen. Er besteht aus einer Verzögerung und zwei Allpässen, die wieder aus SOS-Teilfiltern aufgebaut sind. Pro Teilfilter gibt es nur einen Koeffizienten, sodass man mindestens acht Teilfilter verwenden kann.&lt;br /&gt;
&lt;br /&gt;
===Ein Hilbert-Kochrezept (noch unvollständig)===&lt;br /&gt;
&lt;br /&gt;
Folgen wir dem Zahlenbeispiel und Berechnungsweg im „Handbook for DSP“.&lt;br /&gt;
&lt;br /&gt;
Zuerst berechnen wir einen elliptischen &#039;&#039;Halbband&#039;&#039;-Tiefpass. Halbband besagt, dass die beiden Grenzfrequenzen symmetrisch zur halben Nyquist- Frequenz also 0,25 * Abtastfrequenz liegen, siehe Bild oben rechts. Die genauen Bedingungen lauten in der Schreibweise des Buches (&#039;&#039;p&#039;&#039;=passband, &#039;&#039;s&#039;&#039;=stopband):&lt;br /&gt;
* Omega&amp;lt;sub&amp;gt;s&amp;lt;/sub&amp;gt; + Omega&amp;lt;sub&amp;gt;p&amp;lt;/sub&amp;gt; = Pi &amp;lt;br&amp;gt; (auf Omega&amp;lt;sub&amp;gt;sample&amp;lt;/sub&amp;gt; normierte Skala: Samplerate=2*Pi)&lt;br /&gt;
* (1-Delta&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;)&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; +Delta&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;=1&lt;br /&gt;
&lt;br /&gt;
Als Zahlenwerte werden Omega&amp;lt;sub&amp;gt;s&amp;lt;/sub&amp;gt; = 0,55*Pi und Delta&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;=0,01 gewählt, und damit ein elliptischer IIR-Tiefpass 7.Ordnung berechnet.&lt;br /&gt;
Damit erhält er folgende Zahlenwerte der Pole:&lt;br /&gt;
&lt;br /&gt;
 0  0,436688  0,743707 0,927758&lt;br /&gt;
&lt;br /&gt;
===Scilab-Berechnung des Halbbandfilters===&lt;br /&gt;
&lt;br /&gt;
Mit Scilab erhalten wir nach einigem Ausprobieren praktisch dieselben Zahlenwerte, siehe Bild. Die Pole müssten für ein ideales Halbbandfilter genau auf der imaginären Achse liegen, der Realteil genau Null sein (Der Fehler kommt daher, dass die Angabe von f&amp;lt;sub&amp;gt;stop&amp;lt;/sub&amp;gt; vom Programm nicht berücksichtigt wird, das Filter wäre überbestimmt).&lt;br /&gt;
Diese Zahlen werden noch quadriert (&#039;&#039;konjugiert komplexe&#039;&#039; Pole zusammengefasst) und bilden schließlich die Koeffizienten des Hilbert-Transformators.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Halbbandfilter.png|Mit Scilab berechnetes Halbbandfilter 7.Ordnung|640px]]&lt;br /&gt;
&lt;br /&gt;
Die Übertragungsfunktion des gesuchten Hilbert-Transformators soll wie bisher H(z) heißen. Zur Unterscheidung nennen wir die bis jetzt berechnete Tiefpassfunktion G(z). &lt;br /&gt;
&lt;br /&gt;
Wieder wird sie in SOS-Teilfilter aufgeteilt. Hier allerdings in die &amp;lt;u&amp;gt;Summe&amp;lt;/u&amp;gt; von zwei &amp;lt;u&amp;gt;parallel&amp;lt;/u&amp;gt; geschalteten &#039;&#039;Allpass&#039;&#039;-Funktionen A&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; und A&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt; plus eine Verzögerung um einen Sampletakt, in der Übertragungsfunktion als „z&amp;lt;sup&amp;gt;-1&amp;lt;/sup&amp;gt;“ ausgedrückt.&lt;br /&gt;
&lt;br /&gt;
Ein Allpass läßt alle Signalfrequenzen mit unveränderter Amplitude durch, verändert nur die Phase. Seine SOS-Teilfunktion ist besonders einfach aufgebaut, zwei Koeffizienten sind Null, zwei sind gleich Eins und die beiden restlichen identisch. Damit benötigt man nur eine Multiplikation pro Teilfilter.&lt;br /&gt;
&lt;br /&gt;
Die Tiefpass-Übertragungsfunktion erhält so die Form:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;G(z) = ½ * ( A&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; (z&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;) + z&amp;lt;sup&amp;gt;-1&amp;lt;/sup&amp;gt; * A&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt; (z&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;))&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
mit&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
A_{1}(z^{2})=\frac{z^{-2}+0,190696}{1+0,190696\ast z^{-2}}\ast&lt;br /&gt;
{\frac{z^{-2}+0,860735}{1+0,860735\ast z^{-2}}}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
A_{2}(z^{2})=\frac{z^{-2}+0,553100}{1+0,553100\ast z^{-2}}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn man die beiden Ausgänge nicht addiert, sondern subtrahiert, entsteht ein Hochpass gleicher Grenzfrequenz. Beides kombiniert ergibt eine digitale &#039;&#039;Frequenzweiche&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Zum Übergang auf den Hilbert-Transformator ersetzen (&#039;&#039;substituieren&#039;&#039;) wir das z durch -jz und multiplizieren das ganze mit 2:&lt;br /&gt;
&lt;br /&gt;
H(z)= 2*G(-jz)&lt;br /&gt;
  &lt;br /&gt;
&#039;&#039;&#039;H(z) = A&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; (-z&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;) + j* z&amp;lt;sup&amp;gt;-1&amp;lt;/sup&amp;gt; * A&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt; (-z&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
mit&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
A_{1}(-z^{2})=\frac{z^{-2}-0,190696}{1-0,190696\ast z^{-2}}\ast&lt;br /&gt;
{\frac{z^{-2}-0,860735}{1-0,860735\ast z^{-2}}}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
A_{2}(-z^{2})=\frac{z^{-2}-0,553100}{1-0,553100\ast z^{-2}}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie man sieht, ändern sich nur die Vorzeichen. Die Pole liegen aber im Pol-Nullstellendiagramm auf der reellen Achse.&lt;br /&gt;
&lt;br /&gt;
Die Ausgänge der beiden Allpässe sind jetzt gegeneinander um 90 Grad phasenverschoben, und können auf einen I/Q-Modulator gegeben werden. Umgekehrt kann man auch die beiden Eingänge auftrennen, und zwei um 90 Grad versetzte Signale aus einem I/Q-Demodulator einspeisen und die Ausgangssignale addieren oder subtrahieren, je nach gewünschtem Seitenband.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Allpaesse.png]]&lt;br /&gt;
&lt;br /&gt;
Und weil das so gut funktionierte, hier noch die Berechnung des Hilbert-Transformators [http://www.mikrocontroller.net/topic/92630#new von Olli Niemitalo] mit einem Halbband-Tiefpass 17.Ordnung, was zu acht SOS-Teilfiltern führt, dazu folgt unten ein ATmega48-Programm.&lt;br /&gt;
Die originalen URL sind verwaist, aber im Webarchiv noch zu finden:&amp;lt;br&amp;gt;&lt;br /&gt;
https://web.archive.org/web/20070719141658/http://yehar.com/ViewHome.pl?page=dsp/hilbert/ &amp;lt;br&amp;gt;&lt;br /&gt;
https://web.archive.org/web/20070814013543/http://yehar.com/ViewHome.pl?page=dsp/hilbert/011729.html &amp;lt;br&amp;gt;&lt;br /&gt;
Olli ist auch heute (2019) noch aktiv:&amp;lt;br&amp;gt;&lt;br /&gt;
http://yehar.com/blog/&amp;lt;br&amp;gt;&lt;br /&gt;
speziell sein IIR-Hilbert:&amp;lt;br&amp;gt;&lt;br /&gt;
http://yehar.com/blog/?p=368&amp;lt;br&amp;gt;&lt;br /&gt;
Diskussion auch dazu:&amp;lt;br&amp;gt;&lt;br /&gt;
https://dsp.stackexchange.com/questions/37411/iir-hilbert-transformer/59157#59157&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Bild:Halbbandfilter2.png|Halbbandfilter 17.Ordnung|640px]]&lt;br /&gt;
&lt;br /&gt;
===Der näherungsweise linearphasige Hilbert-Transformator===&lt;br /&gt;
&lt;br /&gt;
Er wird im Handbook for DSP auf zwei Seiten sehr kurz abgehandelt. Statt aus zwei Allpässen besteht er aus einem einzigen, im anderen Zweig wird das Signal nur zeitverzögert, was mit einem Ringpuffer wenig Rechenzeit kostet. Eine Zeitverzögerung ist sozusagen die einfachste Form eines Allpasses, damit ist diese Bauform ein Spezialfall der oben gezeigten. Aus Schüsslers Texten erfahren wir noch, dass das Halbband-Tiefpassfilter zur Berechnung hier Tschebyscheff-Charakter haben muß.&lt;br /&gt;
&lt;br /&gt;
Das Zahlenbeispiel zitiert Regalia aus einer anderen Veröffentlichung [http://www.cs.tut.fi/~mr/MRJulk92.html (M. Renfors and T. Saramäki, A class of approximately linear phase digital filters composed of allpass subfilters 1986 ) ] Der Allpass hat neun Koeffizienten, die Zeitverzögerung beträgt 17 Sampletakte. Der Halbband-Tiefpass hat eine Sperrdämpfung von &amp;gt; 49 dB. Sein Frequenzgang und der Phasengang des berechneten Hilbert-Transformators sind als Bild gezeigt.&lt;br /&gt;
&lt;br /&gt;
Zum Allpass gibt es noch folgende Zahlenwerte:&lt;br /&gt;
&lt;br /&gt;
Pole location for A(z)&amp;lt;br&amp;gt;&lt;br /&gt;
z= 	-0.8699928078&amp;lt;br&amp;gt;&lt;br /&gt;
	 0.491194141 ± j0.183666529&amp;lt;br&amp;gt;&lt;br /&gt;
	 0.252724179 ± j0.463085544&amp;lt;br&amp;gt;&lt;br /&gt;
	-0.109950894 ± j0.548611467&amp;lt;br&amp;gt;&lt;br /&gt;
	-0.447326028 ± j0.356810323&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das könnte also ebenfalls noch in einen  ATmega passen.&lt;br /&gt;
&lt;br /&gt;
===Hilbert ohne Multiplizierer===&lt;br /&gt;
&lt;br /&gt;
Eine interessante Variante wird im Artikel [http://kondor.etf.bg.ac.yu/~lutovac/pdf/eusi98lm.pdf Design of multiplierless elliptic IIR halfband filters and Hilbert transformers] vorgestellt. Ähnlich wie im Cordic-Algorithmus für trigonometrische Funktionen werden Multiplikationen vermieden, durch geschickte Wahl der Koeffizienten als Zweierpotenzen.&lt;br /&gt;
&lt;br /&gt;
Die beiden Allpässe des Zahlenbeispiels haben folgende Übertragungsfunktionen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
A_1(z^{-2})&lt;br /&gt;
&amp;amp;=\frac{z^{-2}-0{,}12109375}{1-0{,}12109375 \cdot z^{-2}}&lt;br /&gt;
\cdot\frac{z^{-2}-0{,}6640625}{1-0{,}6640625 \cdot z^{-2}} \\&lt;br /&gt;
&amp;amp;=\frac{z^{-2}-(\frac18 - \frac1{256})}{1-(\frac18 - \frac1{256}) \cdot z^{-2}}&lt;br /&gt;
\cdot\frac{z^{-2}-(\frac12 + \frac18 + \frac1{32} + \frac1{128})}{1-(\frac12 + \frac18 + \frac1{32} + \frac1{128})\cdot z^{-2}}\\&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
A_2(z^{-2})\cdot{z^{-1}}&lt;br /&gt;
&amp;amp;=z^{-1}&lt;br /&gt;
\cdot\frac{z^{-2}-0{,}390625}{1-0{,}390625 \cdot z^{-2}}&lt;br /&gt;
\cdot\frac{z^{-2}-0{,}890625}{1-0{,}890625 \cdot z^{-2}}\\&lt;br /&gt;
&amp;amp;=z^{-1}&lt;br /&gt;
\cdot\frac{z^{-2}-(\frac14 + \frac18 + \frac1{64})}{1-(\frac14 + \frac18 + \frac1{64}) \cdot z^{-2}}&lt;br /&gt;
\cdot\frac{z^{-2}-(1 - \frac18 + \frac1{64})}{1-(1 - \frac18 + \frac1{64}) \cdot z^{-2}}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Hilbert Transformator nach der FIR-Methode ==&lt;br /&gt;
&lt;br /&gt;
Nach dem Additionstheorem ergibt sich aus dem multiplikativen Mischen (u_prod = u_1 * u_2) zweier Wechselspannungen eine Überlagerung (u_sum = u_3 + u_4) zweier anderer Wechelspannungen; die Frequenz der einen Wechselspannung ist die Summe der Frequenzen der Faktor-Spannungen - die Frequenz der anderen Wechselspannung ist die Differenz der Frequenzen der Faktorspannungen. Jeweils eine der beiden Frequenzen ist das Nutz-Signal, die andere Frequenz ist die Spiegelfrequenz.&lt;br /&gt;
&lt;br /&gt;
Der Hilbert-Tranformator ist ein Mittel um nur das Nutzsignal und nicht die Spiegelfrequenz zu mischen. Es wird nach den Regeln der Multiplikation komplexer Zahlen gemischt. Eingabesignal und Mischoszillator müssen in der Form der EULERschen Identität vorliegen: &lt;br /&gt;
&lt;br /&gt;
y = A * exp( j * phi )  = A * ( cos( phi ) + j * sin( phi )  ) ; phi = omega * t ; omega = 2 * pi * f ; f ... Frequenz ; A ... Amplitude ; t ... Zeit&lt;br /&gt;
&lt;br /&gt;
Mit der exp() - Darstellung kann man mischen, indem man den Ausdruck phi = 2 * pi * t * (f1 + f2) anwendet. Dabei addieren sich die Frequenzen ohne Spiegelfrequenz. Beide Frequenzen müssen als komplexe Zahlen vorliegen, also jede Frequenz als zwei Wechselspannungen mit (jeweils pro Frequenz) gleicher Amplitude. Liegt nur ein einfaches Sinus-Signal vor, kann man das dazugehörige Cosinus-Signal durch Phasenverschiebung um 90° mit einem Hilbert-Transformator erreichen. Danach wendet man die Multiplikation an:&lt;br /&gt;
&lt;br /&gt;
y[ re, j * im ]:= x1[ re, j * im ]* x2[ re, j * im ] = (x1.re * x2.re - x1.im * x2.im) + j * (x1.re * x2.im + x2.re * x1.im) ; re ... Realteil ; im ... Imag. Teil&lt;br /&gt;
&lt;br /&gt;
Jedes Glied des einen Faktors mit jedem Glied des anderen Faktors unter Beachtung der imaginären Einheit multiplizieren. Wendet man bei dem Signal einer der beiden Frequenzen nur einen der beiden Anteile (entweder nur realen Cosinus-Teil oder imaginären Sinusteil) so entsteht eine &amp;quot;negative&amp;quot; Frequenz (der Zeiger in der komplexen Zahlenebene dreht sich andersherum). Somit wird diese Frequenz von der anderen subtrahiert (phi = 2 * pi * t * (f1 - f2)). Das kann sowohl rechnerisch als auch durch Umpolen einer Bandfilterwicklung errreicht werden. Für Zwischenergebnisse nutzt man beide Signalteile weiter, für z.B. eine Audioausgabe genügt einer.&lt;br /&gt;
&lt;br /&gt;
Kann man zu einem Sinussignal das Cosinus-Signal auch ohne synthetisches Filter erhalten? Genau weiß ich es nicht. Für einen Oszillator braucht man mindestens zwei Energiespeicher. Beide sind (wenn es kein Drehstromoszillator ist) um 90° phasenverschoben. Hier kommt man ohne synthetisches Filter aus. Anders bei Schallwellen. Der eine Speicher besteht hier sowohl aus Schalldruck als auch aus Schallschnelle. Sind beide um 0° phasenverschoben, so bewegt sich die Welle in die eine Richtung, bei 180° entsprechend entgegengesetzt. Der andere Speicher ist die 1. Ableitung von jeweils Schalldruck und Schallschnelle. Die Ableitung ist um 90° phasenverschoben aber bei frequenzabhängiger Amplitude ( y = A * sin( omega * t ) ; y&#039; = omega * A * cos( omega * t ) ). Ohne Spiegelfrequenz kann man das nur für eine feste Frequenz mischen. Bei einem Frequenzband braucht man das synthetische Filter.&lt;br /&gt;
&lt;br /&gt;
Der Hilbert-Transformator erzeugt aus einem Sinus-Signal das um 90° verschobene Cosinus-Signal. Ein Beispiel in Python:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Begin Hilbert FIR filter.&lt;br /&gt;
import math # Math&lt;br /&gt;
import numpy as np # Math&lt;br /&gt;
import matplotlib as mlp # Plot&lt;br /&gt;
import matplotlib.pyplot as plt # Plot&lt;br /&gt;
&lt;br /&gt;
FREQUENCY = 400.0 # 1 / s&lt;br /&gt;
RATE = 48000.0 # samples / s&lt;br /&gt;
SAMPLES = 4000&lt;br /&gt;
CELLS = 501&lt;br /&gt;
STEPS = SAMPLES - CELLS&lt;br /&gt;
PREFIX = (CELLS - 1) / 2&lt;br /&gt;
SUFFIX = CELLS - PREFIX&lt;br /&gt;
POSTFIX = SAMPLES - CELLS&lt;br /&gt;
&lt;br /&gt;
samples = range(SAMPLES)&lt;br /&gt;
cells = range(CELLS)&lt;br /&gt;
steps = range(STEPS)&lt;br /&gt;
prefixes = range(PREFIX)&lt;br /&gt;
suffixes = range(SUFFIX)&lt;br /&gt;
postfixes = range(POSTFIX)&lt;br /&gt;
&lt;br /&gt;
input = []&lt;br /&gt;
re = []&lt;br /&gt;
im = []&lt;br /&gt;
coefficients = []&lt;br /&gt;
&lt;br /&gt;
def plot():&lt;br /&gt;
&lt;br /&gt;
	for sample in samples:&lt;br /&gt;
		if(SAMPLES / 2 &amp;gt; sample):&lt;br /&gt;
			_phi = FREQUENCY * sample / RATE * 2.0 * math.pi&lt;br /&gt;
		else:&lt;br /&gt;
			_phi = 5 * FREQUENCY * sample / RATE * 2.0 * math.pi&lt;br /&gt;
		input.append(math.sin(_phi))&lt;br /&gt;
&lt;br /&gt;
	for cell in cells:&lt;br /&gt;
		arg = cell - (CELLS - 1) / 2.0&lt;br /&gt;
		if(0.0 == arg):&lt;br /&gt;
			coefficients.append(0.0)&lt;br /&gt;
		else:&lt;br /&gt;
			arg *= math.pi&lt;br /&gt;
			coefficients.append((1.0 - math.cos(arg)) / arg)&lt;br /&gt;
	&lt;br /&gt;
	for postfix in postfixes:&lt;br /&gt;
		coefficients.append(0.0)&lt;br /&gt;
	&lt;br /&gt;
	for prefix in prefixes:&lt;br /&gt;
		re.append(0.0)&lt;br /&gt;
		im.append(0.0)&lt;br /&gt;
		&lt;br /&gt;
	for step in steps:&lt;br /&gt;
		re.append(input[step + PREFIX])&lt;br /&gt;
		sum = 0.0&lt;br /&gt;
		for cell in cells:&lt;br /&gt;
			sum += input[step + cell] * coefficients[cell];&lt;br /&gt;
		im.append(sum)&lt;br /&gt;
		&lt;br /&gt;
	for suffix in suffixes:&lt;br /&gt;
		re.append(0.0)&lt;br /&gt;
		im.append(0.0)&lt;br /&gt;
	&lt;br /&gt;
	# Prepare the plot.&lt;br /&gt;
	plt.ylabel(&#039;amplitude&#039;)&lt;br /&gt;
	plt.xlabel(&#039;timesteps&#039;)&lt;br /&gt;
	plt.axis([0, SAMPLES - 1, -1.5, 1.5])&lt;br /&gt;
	plt.grid(True)&lt;br /&gt;
	plt.plot(samples, re, &#039;r-&#039;)&lt;br /&gt;
	plt.plot(samples, im, &#039;b-&#039;)&lt;br /&gt;
	plt.show()&lt;br /&gt;
# End.&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
Neben ein Array aus abgetasteten Werten eines akustischen Signales (hier Sinus-Signal, künstlich berechnet) wird das Array des Transformationskerns gelegt. Das Array des Transformationskerns ist dabei viel kürzer und es wird nur der gemeinsame Bereich berechnet. Der Wert des Cosinus-Signals, das zu dem Sinus-Signal gehört, das sich auf der Position der Mitte des Transformationskerns befindet, ergibt sich aus der Summe der Werte aus dem Sinus-Signal multiplizert mit den Faktoren aus dem Transformationskern mit gleichem Index. Das folgende Cosinus-Signal wird berechnet indem man zuvor den Transformationskern um einen Index gegenüber dem Eingabe-Sinus-Signal weiterschiebt (usw. bis zum Ende des Signales). Am Anfang und am Ende des berechneten Cosinus-Signales entsteht ein Stück Verlust der jeweils halb so lang wie der Transformationskern ist. Bei sehr lang dauernden Signalen (fast immer) ist statt dessen mit einem Ringpuffer zu arbeiten.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
t ... Zeit&lt;br /&gt;
b[Länge k] ... Transformationskern&lt;br /&gt;
i[undendlich lang] ... Sinus - Signal oder Summe aus Sinus-Signalen&lt;br /&gt;
o[undendlich lang] ... um 90° verschobenes Cosinus - Signal&lt;br /&gt;
=&amp;gt;&lt;br /&gt;
o[t] := Summe { i[n+t] * b[n+t] } ; -k/2 &amp;lt;= n &amp;lt;= +k/2 ; t &amp;gt;= k/2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Der Transformationskern kann wie folgt ermittelt werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x ... natürliche Zahl &amp;gt; 0&lt;br /&gt;
k ... 4 * x + 1&lt;br /&gt;
b[] ... Transformationskern der Länge k&lt;br /&gt;
n ... Index innerhalb des Tranformationskerns; -k/2 &amp;lt;= n &amp;lt;= +k/2&lt;br /&gt;
pi ... 3.14159...&lt;br /&gt;
b[n] := ( 1 - cos( n * pi ) ) / ( n * pi ) ; Ausnahme ist b[0] := 0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Datei:FIR_Kernel_Small.png|200px|thumb|right|Hilbert Transformationskern klein]]&lt;br /&gt;
&lt;br /&gt;
Dabei ist das Argument der cos() - Funktion immer ganzzahlig. &amp;quot;1 - cos(...)&amp;quot; ist für ungerade &amp;quot;n&amp;quot; immer NULL. Der Kern hat nahe n == 0 maximale Werte und nimmt zum Rand hin ab. Ein Kern mit zuwenig Länge (k ist zu klein) wirkt als Hochpass und verkleinert die Amplitude von Signalen kleiner Frequenz (ist unbrauchbar). Kommen hohe und tiefe Frequenzen im Signal gleichzeitig vor, dann braucht man sowohl eine hohe Abtastrate als auch einen langen Kern ( k wird groß, z.B. Größenordnung 801 bei einem Audiosignal). Ändert sich das Nutzsignal unerwartet sprungartig so erhält man im Cosinus-Signal eine Art Sprungantwort.&lt;br /&gt;
&lt;br /&gt;
* Großer Transformationskern : [[Medium:FIR_Kernel_Big.png]]&lt;br /&gt;
* Transformation zweier Signale verschiedener Frequenz : [[Medium:Hilber_FIR_OK.png]]&lt;br /&gt;
* Transformation eines Sprunges im Signal : [[Medium:Hilbert_FIR_OK_Lense.png]]&lt;br /&gt;
* Transformationsfehler bei zu kleinem Kern (k ist zu klein) :  [[Medium:Hilbert_FIR_Too_Small_Kernel.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Zusammenfassung&amp;lt;/b&amp;gt;&lt;br /&gt;
Hilbert-Transformation ermittelt zu einem Sinus-Signal das um 90° verschobene Cosinus-Signal. Das gilt auch für eine Summe von Sinussignalen unterschiedlicher Frequenzen und Amplituden. Die Amplitude des Cosinus-Signales ist gleich der Amplitude des Sinus-Signales (kann geringfügig abweichen aber korrigiert werden). Das Transformieren erfolgt meist synthetisch, z.B. in digitalen Signal Prozessoren. Die Hilbert-Transformation wird verwendet, wenn man Sinus-Signal und Cosinus-Signal benötigt aber nur das Sinus-Signal vorliegt. Beide Signale (sin(...) und cos(...)) zusammen entsprechen einer Folge komplexer Zahlen. Damit kann man multiplikativ mischen ohne Spiegelfrequenz. Liegen beide Faktoren der Mischung als komplexe Zahlen vor, kann man jedes Glied der einen Zahl mit jedem Glied der anderen Zahl multiplizieren unter Beachtung der komplexen Einheit &amp;quot;j&amp;quot;. Falls man sich dabei beide Faktoren jedoch in der exp( j * omega * t ) Schreibweise denkt, so multipliziert man statt dessen Potenzen, indem man die Exponenten addiert. Für eine Berechnung braucht man 4 Multiplikationen, was entweder digital erfolgen kann oder im analogen Fall vier Mischer (z.B. Ringmischer oder Gilbertzellen) benötigt, wenn man das ganze Ergebnis braucht. Der Transformationskern ist ein Array aus Zahlen deren Werte in der Mitte des Arrays groß sind und zum Rand hin abnehmen.&lt;br /&gt;
&lt;br /&gt;
==Weitere Literatur zu Hilbert==&lt;br /&gt;
* Schüssler / [http://www.lnt.de/LMS/staff/index.php?lang=de&amp;amp;function=1&amp;amp;person=5 Steffen] &amp;quot;Halfband Filters and Hilbert Transformers&amp;quot; &amp;lt;br&amp;gt; Irgendwo im Web hatte ich den vollständigen Artikel als PDF gefunden, leider die Adresse nicht notiert, Google findet nur [http://www.springerlink.com/content/p5480n6p8t73t633/ kostenpflichtige Downloads].&lt;br /&gt;
* Dutta / Kumar [http://eprint.iitd.ac.in/dspace/bitstream/2074/1608/1/roydig1989.pdf On Digital Differentiators, Hilbert Transformers, and Half-Band Low-Pass Filters] &amp;lt;br&amp;gt; dank Schrifterkennungsprogramm leicht lädiert&lt;br /&gt;
* Miroslav Lutovac / Ljiljana Milic [http://www.telfor.rs/telfor2000/radovi/7-10.pdf Half-band IIR Filter Design Using Matlab],  [http://kondor.etf.bg.ac.yu/~lutovac/confer.htm weitere Artikel der Autoren]&lt;br /&gt;
* Göckler / Damjanovic [http://www.dsv.rub.de/imperia/md/content/public/wsr06_goecklerdamjanovic.pdf A Family of Efficient Complex Halfband Filters]&lt;br /&gt;
&lt;br /&gt;
==ATmega-Programm Hilbert-Transformer ( fast fertig, schwingt leider)==&lt;br /&gt;
Da der Adressenbereich des ATmega nicht groß genug ist, wird die Tabelle im SRAM in zwei Hälften geteilt.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;* Hilbert transformer with ATmega48P, 90 degree broadband phase shifter   *&lt;br /&gt;
;* 15 MHz xtal, input ADC0, PWM-output OCR1a/b, test output PD0            *&lt;br /&gt;
;* Christoph Kessler 2008                         db1uq_at_t-online_dot_de *&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
.nolist&lt;br /&gt;
.include &amp;quot;m48pdef.inc&amp;quot;&lt;br /&gt;
.list&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;* register 0-15 (no &amp;quot;immediate&amp;quot;-operations possible):&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
.def	mult_l	= r0	; multiplier result&lt;br /&gt;
.def	mult_h	= r1	; multiplier result&lt;br /&gt;
.def	zero	= r2	; zero register (used to add carry flag)&lt;br /&gt;
.def	savsrg	= r3	; save status register during interrupt routine&lt;br /&gt;
.def	reg04	= r4	; free&lt;br /&gt;
.def	reg05	= r5	; free&lt;br /&gt;
.def	reg06	= r6	; free&lt;br /&gt;
.def	reg07	= r7	; free&lt;br /&gt;
.def	reg08	= r8	; free&lt;br /&gt;
.def	reg09	= r9	; free&lt;br /&gt;
.def	reg10	= r10	; free&lt;br /&gt;
.def	reg11	= r11	; free&lt;br /&gt;
.def	reg12	= r12	; free&lt;br /&gt;
.def	accu0	= r13	; Accumulator - 32bit for Interrupt routine&lt;br /&gt;
.def	accu1	= r14	; Accumulator - 32bit for Interrupt routine&lt;br /&gt;
.def	accu2	= r15	; Accumulator - 32bit for Interrupt routine&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;* register 16-23 (&amp;quot;immediate&amp;quot;-operations possible):&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
.def	accu3	= r16	; Accumulator - 32bit for Interrupt routine&lt;br /&gt;
.def	reg17	= r17	; free&lt;br /&gt;
.def	reg18	= r18	; free&lt;br /&gt;
.def	reg19	= r19	; free&lt;br /&gt;
.def	datal	= r20	; Data samples mul register&lt;br /&gt;
.def	datah	= r21	;  for Interrupt routine&lt;br /&gt;
.def	coefl	= r22	; Filter coefficient mul register&lt;br /&gt;
.def	coefh	= r23	;  for Interrupt routine&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;* register 24-31    (16Bit-registers) &lt;br /&gt;
;***************************************************************************&lt;br /&gt;
.def	tmp1	= r24	; general temporary register&lt;br /&gt;
.def	tmp2	= r25	; general temporary register&lt;br /&gt;
;	XL	= r26	; free&lt;br /&gt;
;	XH	= r27	; free&lt;br /&gt;
;	YL	= r28	; used by Interrupt routine&lt;br /&gt;
;	YH	= r29	; used by Interrupt routine&lt;br /&gt;
;	ZL	= r30	; init routine only, free for main program&lt;br /&gt;
;	ZH	= r31	; init routine only, free for main program&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* constants :&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;1st table:&lt;br /&gt;
	;&amp;quot;allpass&amp;quot;0:&lt;br /&gt;
.equ	 x10	= 0&lt;br /&gt;
	; allpass 2:&lt;br /&gt;
.equ	 x12	= 2&lt;br /&gt;
.equ	 x22	= 4&lt;br /&gt;
.equ	 y02	= 6&lt;br /&gt;
.equ	 y12	= 8&lt;br /&gt;
.equ	 y22	= 10&lt;br /&gt;
	; allpass 4:&lt;br /&gt;
.equ	 x14	= 12&lt;br /&gt;
.equ	 x24	= 14&lt;br /&gt;
.equ	 y04	= 16&lt;br /&gt;
.equ	 y14	= 18&lt;br /&gt;
.equ	 y24	= 20&lt;br /&gt;
	; allpass 6:&lt;br /&gt;
.equ	 x16	= 22&lt;br /&gt;
.equ	 x26	= 24&lt;br /&gt;
.equ	 y06	= 26&lt;br /&gt;
.equ	 y16	= 28&lt;br /&gt;
.equ	 y26	= 30&lt;br /&gt;
	; allpass 8:&lt;br /&gt;
.equ	 x18	= 32&lt;br /&gt;
.equ	 x28	= 34&lt;br /&gt;
.equ	 y08	= 36&lt;br /&gt;
.equ	 y18	= 38&lt;br /&gt;
.equ	 y28	= 40&lt;br /&gt;
&lt;br /&gt;
.equ	 k2	= 42&lt;br /&gt;
.equ	 k4	= 44&lt;br /&gt;
.equ	 k6	= 46&lt;br /&gt;
.equ	 k8	= 48&lt;br /&gt;
;2nd table:&lt;br /&gt;
.equ	 k1	= 0&lt;br /&gt;
.equ	 k3	= 2&lt;br /&gt;
.equ	 k5	= 4&lt;br /&gt;
.equ	 k7	= 6&lt;br /&gt;
	; allpass 1:&lt;br /&gt;
.equ	 x11	= 8&lt;br /&gt;
.equ	 x21	= 10&lt;br /&gt;
.equ	 y01	= 12&lt;br /&gt;
.equ	 y11	= 14&lt;br /&gt;
.equ	 y21	= 16&lt;br /&gt;
	; allpass 3:&lt;br /&gt;
.equ	 x13	= 18&lt;br /&gt;
.equ	 x23	= 20&lt;br /&gt;
.equ	 y03	= 22&lt;br /&gt;
.equ	 y13	= 24&lt;br /&gt;
.equ	 y23	= 26&lt;br /&gt;
	; allpass 5:&lt;br /&gt;
.equ	 x15	= 28&lt;br /&gt;
.equ	 x25	= 30&lt;br /&gt;
.equ	 y05	= 32&lt;br /&gt;
.equ	 y15	= 34&lt;br /&gt;
.equ	 y25	= 36&lt;br /&gt;
	; allpass 7:&lt;br /&gt;
.equ	 x17	= 38&lt;br /&gt;
.equ	 x27	= 40&lt;br /&gt;
.equ	 y07	= 42&lt;br /&gt;
.equ	 y17	= 44&lt;br /&gt;
.equ	 y27	= 46&lt;br /&gt;
;*****************************************************&lt;br /&gt;
;* Macros&lt;br /&gt;
;*****************************************************&lt;br /&gt;
.MACRO load_node&lt;br /&gt;
	ldd	datal,Y+@0	; Load low byte of node &lt;br /&gt;
	ldd	datah,Y+@0+1	; Load high byte of node&lt;br /&gt;
.ENDMACRO&lt;br /&gt;
.MACRO update_node&lt;br /&gt;
	std	Y+@0,datal	; Store low byte of node &lt;br /&gt;
	std	Y+@0+1,datah	; Store high byte of node&lt;br /&gt;
.ENDMACRO&lt;br /&gt;
.MACRO add_node&lt;br /&gt;
	ldd	coefl,Y+@0	; Load 2nd node low&lt;br /&gt;
	ldd	coefh,Y+@0+1	; Load 2nd node high&lt;br /&gt;
	add	datal,coefl	; Add low bytes&lt;br /&gt;
	adc	datah,coefh	; Add with carry high bytes&lt;br /&gt;
.ENDMACRO&lt;br /&gt;
.MACRO mult_32&lt;br /&gt;
	ldd	coefl,Y+@0	; Load low byte of coefficient&lt;br /&gt;
	ldd	coefh,Y+@0+1	; Load high byte of coefficient&lt;br /&gt;
	muls	coefh,datah	; Signed multiply, coefficient high byte and data high byte&lt;br /&gt;
	mov     accu2,mult_l	; Copy result word into accumulator byte 2:3&lt;br /&gt;
	mov     accu3,mult_h	; Copy result word into accumulator byte 2:3&lt;br /&gt;
	mul	coefl,datal	; Unsigned multiply, coefficient low byte and data low byte&lt;br /&gt;
	mov	accu0,mult_l	; Copy result word into accumulator byte 2:3&lt;br /&gt;
	mov	accu1,mult_h	; Copy result word into accumulator byte 2:3&lt;br /&gt;
	mulsu	coefh,datal	; Signed-unsigned multiply, coefficient high byte and data low byte&lt;br /&gt;
	sbc	accu3,zero	; Sign extention&lt;br /&gt;
	add	accu1,mult_l	; Add low byte of result to accumulator byte 1&lt;br /&gt;
	adc	accu2,mult_h	; Add with carry high byte of result to accumulator byte 2&lt;br /&gt;
	adc	accu3,zero	; Add carry to accumulator byte 3&lt;br /&gt;
	mulsu	datah,coefl	; Signed-unsigned multiply, data high byte and coefficient low byte&lt;br /&gt;
	sbc	accu3,zero	; Sign extention&lt;br /&gt;
	add	accu1,mult_l	; Add low byte of result to accumulator byte 1&lt;br /&gt;
	adc	accu2,mult_h	; Add with carry high byte of result to accumulator byte 2&lt;br /&gt;
	adc	accu3,zero	; Add carry to accumulator byte 3&lt;br /&gt;
.ENDMACRO&lt;br /&gt;
.MACRO subtr_node&lt;br /&gt;
	ldd	datal,Y+@0	; Load 2nd node low&lt;br /&gt;
	ldd	datah,Y+@0+1	; Load 2nd node high&lt;br /&gt;
	sub	accu0,datal	; Subtract low byte&lt;br /&gt;
	sbc	accu1,datah	; Subtract with carry high byte&lt;br /&gt;
	sbc	accu2,zero	;&lt;br /&gt;
	sbc	accu3,zero	;&lt;br /&gt;
.ENDMACRO&lt;br /&gt;
.MACRO limit_store&lt;br /&gt;
	cpi	accu3,$40	; accu &amp;lt;   $40000000 ?&lt;br /&gt;
	brlo	NoLimit1	;&lt;br /&gt;
	cpi	accu3,-$40	; accu &amp;gt;= -$40000000 ?&lt;br /&gt;
	brsh	NoLimit1	;&lt;br /&gt;
	clr	accu2		; accu2 = $00&lt;br /&gt;
	cpi	accu3,0		;&lt;br /&gt;
	brge	PosLim1		; &lt;br /&gt;
	ldi	accu3,$80	; accu3 = $80&lt;br /&gt;
	rjmp	Limit1		; &lt;br /&gt;
PosLim1:&lt;br /&gt;
	ldi	accu3,$7F	; accu3 = $7F	&lt;br /&gt;
	com	accu2		; accu2 = $FF	&lt;br /&gt;
	rjmp	Limit1		; &lt;br /&gt;
NoLimit1:&lt;br /&gt;
	lsl	accu1		; Scaling to gain factor 2^16&lt;br /&gt;
	rol	accu2		; &lt;br /&gt;
	rol	accu3		; &lt;br /&gt;
Limit1:&lt;br /&gt;
	std	Y+@0,accu2	; &lt;br /&gt;
	std	Y+@0+1,accu3	; &lt;br /&gt;
.ENDMACRO&lt;br /&gt;
.LISTMAC&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* reset/interrupt-vectors:&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
.cseg&lt;br /&gt;
	rjmp	Initial		; after RESET to main program&lt;br /&gt;
	reti			; External Interrupt Request 0&lt;br /&gt;
	reti			; External Interrupt Request 1&lt;br /&gt;
	reti			; Pin Change Interrupt Request 0&lt;br /&gt;
	reti			; Pin Change Interrupt Request 1&lt;br /&gt;
	reti			; Pin Change Interrupt Request 2&lt;br /&gt;
	reti			; Watchdog Time-out Interrupt&lt;br /&gt;
	reti			; Timer/Counter2 Compare Match A&lt;br /&gt;
	reti			; Timer/Counter2 Compare Match B&lt;br /&gt;
	reti			; Timer/Counter2 Overflow&lt;br /&gt;
	reti			; Timer/Counter1 Capture Event&lt;br /&gt;
	reti			; Timer/Counter1 Compare Match A&lt;br /&gt;
	reti			; Timer/Counter1 Compare Match B&lt;br /&gt;
	reti			; Timer/Counter1 Overflow&lt;br /&gt;
	reti			; Timer/Counter0 Compare Match A&lt;br /&gt;
	reti			; Timer/Counter0 Compare Match B&lt;br /&gt;
	reti			; Timer/Counter0 Overflow&lt;br /&gt;
	reti			; SPI Serial Transfer Complete&lt;br /&gt;
	reti			; USART0, Rx Complete&lt;br /&gt;
	reti			; USART0 Data register Empty&lt;br /&gt;
	reti			; USART0, Tx Complete&lt;br /&gt;
	rjmp	ADCint		; ADC Conversion Complete&lt;br /&gt;
	reti			; EEPROM Ready   &lt;br /&gt;
	reti			; 2-wire Serial Interface&lt;br /&gt;
	reti			; Store Program Memory Read&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* after reset: initialise stack,ports&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
Initial: &lt;br /&gt;
	ldi	tmp1,Low(RAMEND)&lt;br /&gt;
	out	SPL,tmp1	;&lt;br /&gt;
	ldi	tmp1,High(RAMEND)&lt;br /&gt;
	out	SPH,tmp1	; stack initialised&lt;br /&gt;
	clr	zero		; always zero&lt;br /&gt;
	ldi	tmp1,$FF	; &lt;br /&gt;
	out	PortB,tmp1	; PortB = % 1111 1111&lt;br /&gt;
	out	PortC,zero	; PortC = % 0000 0000&lt;br /&gt;
	out	PortD,tmp1	; PortD = % 1111 1111&lt;br /&gt;
	out	DDRB,tmp1	; PortB direction = % 1111 1111&lt;br /&gt;
	out	DDRC,zero	; PortC direction = % 0000 0000&lt;br /&gt;
	out	DDRD,tmp1	; PortD direction = % 1111 1111&lt;br /&gt;
	ldi	tmp1,$A1	; pos. outputs, fast PWM 8Bit&lt;br /&gt;
	sts	TCCR1A,tmp1	;&lt;br /&gt;
	ldi	tmp1,$09	; fast PWM 8Bit, clk/1 (no prescaling)&lt;br /&gt;
	sts	TCCR1B,tmp1	;&lt;br /&gt;
	sts	OCR1AH,zero	;&lt;br /&gt;
	sts	OCR1AL,zero	;&lt;br /&gt;
	sts	OCR1BH,zero	;&lt;br /&gt;
	sts	OCR1BL,zero	;&lt;br /&gt;
	ldi	tmp1,$40	; Ref=Vcc, right-adj, ADC0=input&lt;br /&gt;
	sts	ADMUX,tmp1	;&lt;br /&gt;
	ldi	tmp1,$EE	; Start,Auto, enable Int, Clk/64&lt;br /&gt;
;	ldi	tmp1,$EF	; Start,Auto, enable Int, Clk/128&lt;br /&gt;
	sts	ADCSRA,tmp1	;&lt;br /&gt;
	ldi	tmp1,$00	; free running&lt;br /&gt;
	sts	ADCSRB,tmp1	;&lt;br /&gt;
	ldi	tmp1,$01	; disable ADC0 dig.inp (optional)&lt;br /&gt;
	sts	DIDR0,tmp1	;&lt;br /&gt;
	ldi	ZL,low(CoTblF&amp;lt;&amp;lt;1)	; move filter coefficents&lt;br /&gt;
	ldi	ZH,high(CoTblF&amp;lt;&amp;lt;1)	; from program-flash&lt;br /&gt;
	ldi	YL,low(CoTblS)	; to SRAM&lt;br /&gt;
	ldi	YH,high(CoTblS)	;&lt;br /&gt;
	ldi	tmp1,16		; count 8 * 2-Byte coefficients&lt;br /&gt;
TbLoop:&lt;br /&gt;
	lpm	tmp2,Z+		; fetch 1 byte from coefficient table&lt;br /&gt;
	st	Y+,tmp2		; copy coefficient to Sram, increment Y&lt;br /&gt;
	dec	tmp1&lt;br /&gt;
	brne	TbLoop&lt;br /&gt;
	ldi	YL,low(DatTbl1)	; load SRAM-Pointer for Interrupt routine&lt;br /&gt;
	ldi	YH,high(DatTbl1)	;&lt;br /&gt;
	sei			; enable interrupts&lt;br /&gt;
&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* Main program:&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
Endless:&lt;br /&gt;
	rjmp	Endless		; &lt;br /&gt;
&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* ADC-Interrupt routine: compute filter and update PWM output&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
ADCint:&lt;br /&gt;
	sbi	PortD,0		; just to measure INT-Time&lt;br /&gt;
	in	savsrg,SREG	; save status register&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
&lt;br /&gt;
; allpass 2&lt;br /&gt;
	load_node 	x10	;&lt;br /&gt;
	add_node 	y22	;         y22   +---+ y12 +---+&lt;br /&gt;
	mult_32		k2	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+&lt;br /&gt;
	subtr_node	x22	;          |    +---+     +---+    |&lt;br /&gt;
	limit_store 	y02	;          v                       |&lt;br /&gt;
	load_node 	x12	;   x10  +---+   +---+    +---+    | &lt;br /&gt;
	update_node 	x22	;    o--&amp;gt;| + |--&amp;gt;|*K2|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	load_node 	x10	;    |   +---+   +---+  + +---+   y02&lt;br /&gt;
	update_node 	x12	;    |                    - A&lt;br /&gt;
	lds	datal,ADCL	;    |    +---+     +---+   |&lt;br /&gt;
	lds	datah,ADCH	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o&lt;br /&gt;
	dec	datah		;    |    +---+ x12 +---+  x22&lt;br /&gt;
	dec	datah		;    |&lt;br /&gt;
	lsl	datal		;    +-----------+&lt;br /&gt;
	rol	datah		;         +---+  |&lt;br /&gt;
	lsl	datal		;  ADC &amp;gt;--|1/z|--+&lt;br /&gt;
	rol	datah		;         +---+ &lt;br /&gt;
	lsl	datal		; &lt;br /&gt;
	rol	datah		; &lt;br /&gt;
	lsl	datal		; convert 10 bit unsigned &lt;br /&gt;
	rol	datah		; to 15 Bit signed&lt;br /&gt;
	lsl	datal		; $03FF -&amp;gt; $01FF -&amp;gt; $3FE0&lt;br /&gt;
	rol	datah		; $0000 -&amp;gt; $FE00 -&amp;gt; $C000&lt;br /&gt;
	lsl	datal		;  &lt;br /&gt;
	rol	datah		; &lt;br /&gt;
	update_node 	x10	; save new sample for 2nd allpass-chain&lt;br /&gt;
	load_node 	y12	; &lt;br /&gt;
	update_node 	y22	; &lt;br /&gt;
	load_node 	y02	;&lt;br /&gt;
	update_node 	y12	;&lt;br /&gt;
&lt;br /&gt;
; allpass 4&lt;br /&gt;
	add_node 	y24	;&lt;br /&gt;
	mult_32		k4	;         y24   +---+ y14 +---+&lt;br /&gt;
	subtr_node	x24	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+&lt;br /&gt;
	limit_store 	y04	;          |    +---+     +---+    |&lt;br /&gt;
	load_node 	x14	;          v                       |&lt;br /&gt;
	update_node 	x24	;   y02  +---+   +---+    +---+    | &lt;br /&gt;
	load_node 	y02	;  -&amp;gt;o--&amp;gt;| + |--&amp;gt;|*K4|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	update_node 	x14	;    |   +---+   +---+  + +---+   y04&lt;br /&gt;
	load_node 	y14	;    |                    - A&lt;br /&gt;
	update_node 	y24	;    |    +---+     +---+   |&lt;br /&gt;
	load_node 	y04	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o&lt;br /&gt;
	update_node 	y14	;         +---+ x14 +---+  x24&lt;br /&gt;
&lt;br /&gt;
; allpass 6&lt;br /&gt;
	add_node 	y26	;&lt;br /&gt;
	mult_32		k6	;         y26   +---+ y16 +---+ &lt;br /&gt;
	subtr_node	x26	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+ &lt;br /&gt;
	limit_store 	y06	;          |    +---+     +---+    | &lt;br /&gt;
	load_node 	x16	;          v                       |&lt;br /&gt;
	update_node 	x26	;   y04  +---+   +---+    +---+    | &lt;br /&gt;
	load_node 	y04	;  -&amp;gt;o--&amp;gt;| + |--&amp;gt;|*K6|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	update_node 	x16	;    |   +---+   +---+  + +---+   y06&lt;br /&gt;
	load_node 	y16	;    |                    - A&lt;br /&gt;
	update_node 	y26	;    |    +---+     +---+   |&lt;br /&gt;
	load_node 	y06	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o&lt;br /&gt;
	update_node 	y16	;         +---+ x16 +---+  x26&lt;br /&gt;
&lt;br /&gt;
; allpass 8&lt;br /&gt;
	add_node 	y28	;&lt;br /&gt;
	mult_32		k8	;         y28   +---+ y18 +---+ &lt;br /&gt;
	subtr_node	x28	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+&lt;br /&gt;
	limit_store 	y08	;          |    +---+     +---+    |&lt;br /&gt;
	load_node 	x18	;          v                       |&lt;br /&gt;
	update_node 	x28	;   y06  +---+   +---+    +---+    | &lt;br /&gt;
	load_node 	y06	;  -&amp;gt;o--&amp;gt;| + |--&amp;gt;|*K8|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	update_node 	x18	;    |   +---+   +---+  + +---+   y08&lt;br /&gt;
	load_node 	y18	;    |                    - A&lt;br /&gt;
	update_node 	y28	;    |    +---+     +---+   |&lt;br /&gt;
	load_node 	y08	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o &lt;br /&gt;
	update_node 	y18	;         +---+ x18 +---+  x28 &lt;br /&gt;
	load_node 	x10	;&lt;br /&gt;
	ldi	YL,Low(DatTbl2)	;&lt;br /&gt;
&lt;br /&gt;
; allpass 1&lt;br /&gt;
	add_node 	y21	;&lt;br /&gt;
	mult_32		k1	;         y21   +---+ y11 +---+&lt;br /&gt;
	subtr_node	x21	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+&lt;br /&gt;
	limit_store 	y01	;          |    +---+     +---+    |&lt;br /&gt;
	load_node 	x11	;          v                       |&lt;br /&gt;
	update_node 	x21	;   x10  +---+   +---+    +---+    | &lt;br /&gt;
	load_node 	x10	;  -&amp;gt;o--&amp;gt;| + |--&amp;gt;|*K1|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	update_node 	x11	;    |   +---+   +---+  + +---+   y01&lt;br /&gt;
	load_node 	y11	;    |                    - A&lt;br /&gt;
	update_node 	y21	;    |    +---+     +---+   |&lt;br /&gt;
	load_node 	y01	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o&lt;br /&gt;
	update_node 	y11	;         +---+ x11 +---+  x21&lt;br /&gt;
&lt;br /&gt;
; allpass 3&lt;br /&gt;
	add_node 	y23	;&lt;br /&gt;
	mult_32		k3	;         y23   +---+ y13 +---+&lt;br /&gt;
	subtr_node	x23	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+&lt;br /&gt;
	limit_store 	y03	;          |    +---+     +---+    |&lt;br /&gt;
	load_node 	x13	;          v                       |&lt;br /&gt;
	update_node 	x23	;   y01  +---+   +---+    +---+    | &lt;br /&gt;
	load_node 	y01	;  -&amp;gt;o--&amp;gt;| + |--&amp;gt;|*K3|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	update_node 	x13	;    |   +---+   +---+  + +---+   y03&lt;br /&gt;
	load_node 	y13	;    |                    - A&lt;br /&gt;
	update_node 	y23	;    |    +---+     +---+   |&lt;br /&gt;
	load_node 	y03	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o&lt;br /&gt;
	update_node 	y13	;         +---+ x13 +---+  x23&lt;br /&gt;
&lt;br /&gt;
; allpass 5&lt;br /&gt;
	add_node 	y25	;&lt;br /&gt;
	mult_32		k5	;         y25   +---+ y15 +---+&lt;br /&gt;
	subtr_node	x25	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+&lt;br /&gt;
	limit_store 	y05	;          |    +---+     +---+    |&lt;br /&gt;
	load_node 	x15	;          v                       |&lt;br /&gt;
	update_node 	x25	;   y03  +---+   +---+    +---+    | &lt;br /&gt;
	load_node 	y03	;  -&amp;gt;o--&amp;gt;| + |--&amp;gt;|*K5|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	update_node 	x15	;    |   +---+   +---+  + +---+   y05&lt;br /&gt;
	load_node 	y15	;    |                    - A&lt;br /&gt;
	update_node 	y25	;    |    +---+     +---+   |&lt;br /&gt;
	load_node 	y05	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o&lt;br /&gt;
	update_node 	y15	;         +---+ x15 +---+  x25&lt;br /&gt;
&lt;br /&gt;
; allpass 7&lt;br /&gt;
	add_node 	y27	;&lt;br /&gt;
	mult_32		k7	;         y27   +---+ y17 +---+&lt;br /&gt;
	subtr_node	x27	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+&lt;br /&gt;
	limit_store 	y07	;          |    +---+     +---+    |&lt;br /&gt;
	load_node 	x17	;          v                       |&lt;br /&gt;
	update_node 	x27	;   y05  +---+   +---+    +---+    | &lt;br /&gt;
	load_node 	y05	;  -&amp;gt;o--&amp;gt;| + |--&amp;gt;|*K7|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	update_node 	x17	;    |   +---+   +---+  + +---+   y07&lt;br /&gt;
	load_node 	y17	;    |                    - A&lt;br /&gt;
	update_node 	y27	;    |    +---+     +---+   | &lt;br /&gt;
	load_node 	y07	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o &lt;br /&gt;
	update_node 	y17	;         +---+ x17 +---+  x27&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* PWM - D/A-output&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
; output y07 to PWM-DAC&lt;br /&gt;
&lt;br /&gt;
;test: output y01&lt;br /&gt;
	ldd	accu3, Y+y01+1	;&lt;br /&gt;
;&lt;br /&gt;
	subi	accu3,$80	; signed to unsigned  $8000 -&amp;gt;$0000, $7FFF -&amp;gt;$FFFF&lt;br /&gt;
	sts	OCR1AH,zero	; &lt;br /&gt;
	sts	OCR1AL,accu3	; fast PWM 8 bit y07 output to OCR1A&lt;br /&gt;
	ldi	YL,Low(DatTbl1)	; back to 1st data table&lt;br /&gt;
; output y08 to PWM-DAC&lt;br /&gt;
;	load_node 	y08	; load y08&lt;br /&gt;
&lt;br /&gt;
; test outpt y02&lt;br /&gt;
	load_node 	y02	; load y02&lt;br /&gt;
;&lt;br /&gt;
	subi	datah,$80	; signed to unsigned  $8000 -&amp;gt;$0000, $7FFF -&amp;gt;$FFFF&lt;br /&gt;
	sts	OCR1BH,zero	; &lt;br /&gt;
	sts	OCR1BL,accu3	; fast PWM 8 bit y08 output to OCR1B&lt;br /&gt;
	cbi	PortD,0		; just to measure INT-Time&lt;br /&gt;
	out	SREG,savsrg	; restore status register&lt;br /&gt;
	reti			; &lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* coefficient table in flash memory&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
CoTblF:&lt;br /&gt;
	.dw 	15709 	 	; k2 *32768 (0,4794008655888)&lt;br /&gt;
	.dw 	28712	 	; k4 *32768 (0,8762184935393)&lt;br /&gt;
	.dw 	32001		; k6 *32768 (0,9765975895082)&lt;br /&gt;
	.dw 	32686	 	; k8 *32768 (0,9974992559356)&lt;br /&gt;
	.dw 	 5301	 	; k1 *32768 (0,1617584983677)&lt;br /&gt;
	.dw 	24020		; k3 *32768 (0,7330289323415)&lt;br /&gt;
	.dw 	30977 		; k5 *32768 (0,9453497003291)&lt;br /&gt;
	.dw 	32460	 	; k7 *32768 (0,9905991566845)&lt;br /&gt;
&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* data in SRAM&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
.dseg&lt;br /&gt;
.org	$0100&lt;br /&gt;
DatTbl1:&lt;br /&gt;
	; &amp;quot;allpass&amp;quot; 0&lt;br /&gt;
	.dw 	$0000 	 	; x10&lt;br /&gt;
	; allpass 2&lt;br /&gt;
	.dw 	$0000 	 	; x12&lt;br /&gt;
	.dw 	$0000 	 	; x22&lt;br /&gt;
	.dw 	$0000 	 	; y02&lt;br /&gt;
	.dw 	$0000 	 	; y12&lt;br /&gt;
	.dw 	$0000 	 	; y22&lt;br /&gt;
	; allpass 4&lt;br /&gt;
	.dw 	$0000 	 	; x14&lt;br /&gt;
	.dw 	$0000 	 	; x24&lt;br /&gt;
	.dw 	$0000 	 	; y04&lt;br /&gt;
	.dw 	$0000 	 	; y14&lt;br /&gt;
	.dw 	$0000 	 	; y24&lt;br /&gt;
	; allpass 6&lt;br /&gt;
	.dw 	$0000 	 	; x16&lt;br /&gt;
	.dw 	$0000 	 	; x26&lt;br /&gt;
	.dw 	$0000 	 	; y06&lt;br /&gt;
	.dw 	$0000 	 	; y16&lt;br /&gt;
	.dw 	$0000 	 	; y26&lt;br /&gt;
	; allpass 8&lt;br /&gt;
	.dw 	$0000 	 	; x18&lt;br /&gt;
	.dw 	$0000 	 	; x28&lt;br /&gt;
	.dw 	$0000 	 	; y08&lt;br /&gt;
	.dw 	$0000 	 	; y18&lt;br /&gt;
	.dw 	$0000 	 	; y28&lt;br /&gt;
CoTblS:&lt;br /&gt;
	.dw 	$0000 	 	; k2&lt;br /&gt;
	.dw 	$0000 	 	; k4&lt;br /&gt;
	.dw 	$0000		; k6&lt;br /&gt;
	.dw 	$0000	 	; k8&lt;br /&gt;
DatTbl2:&lt;br /&gt;
	.dw 	$0000	 	; k1&lt;br /&gt;
	.dw 	$0000		; k3&lt;br /&gt;
	.dw 	$0000 		; k5&lt;br /&gt;
	.dw 	$0000	 	; k7&lt;br /&gt;
	; allpass 1&lt;br /&gt;
	.dw 	$0000 	 	; x11&lt;br /&gt;
	.dw 	$0000 	 	; x21&lt;br /&gt;
	.dw 	$0000 	 	; y01&lt;br /&gt;
	.dw 	$0000 	 	; y11&lt;br /&gt;
	.dw 	$0000 	 	; y21&lt;br /&gt;
	; allpass 3&lt;br /&gt;
	.dw 	$0000 	 	; x13&lt;br /&gt;
	.dw 	$0000 	 	; x23&lt;br /&gt;
	.dw 	$0000 	 	; y03&lt;br /&gt;
	.dw 	$0000 	 	; y13&lt;br /&gt;
	.dw 	$0000 	 	; y23&lt;br /&gt;
	; allpass 5&lt;br /&gt;
	.dw 	$0000 	 	; x15&lt;br /&gt;
	.dw 	$0000 	 	; x25&lt;br /&gt;
	.dw 	$0000 	 	; y05&lt;br /&gt;
	.dw 	$0000 	 	; y15&lt;br /&gt;
	.dw 	$0000 	 	; y25&lt;br /&gt;
	; allpass 7&lt;br /&gt;
	.dw 	$0000 	 	; x17&lt;br /&gt;
	.dw 	$0000 	 	; x27&lt;br /&gt;
	.dw 	$0000 	 	; y07&lt;br /&gt;
	.dw 	$0000 	 	; y17&lt;br /&gt;
	.dw 	$0000 	 	; y27&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Kategorie:AVR-Projekte]]&lt;br /&gt;
[[Category:DSP]]&lt;/div&gt;</summary>
		<author><name>Claus w</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Hilbert-Transformator_(Phasenschieber)_mit_ATmega&amp;diff=102908</id>
		<title>Hilbert-Transformator (Phasenschieber) mit ATmega</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Hilbert-Transformator_(Phasenschieber)_mit_ATmega&amp;diff=102908"/>
		<updated>2021-01-09T22:57:48Z</updated>

		<summary type="html">&lt;p&gt;Claus w: /* Hilbert Transformator nach der FIR-Methode */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Dieser Artikel ist eine Fortsetzung von [[Digitalfilter mit ATmega]] und behandelt ein spezielles Digitalfilter namens Hilbert-Transformator.&lt;br /&gt;
&lt;br /&gt;
Neben den üblichen Filtern, Tiefpass, Hochpass, Bandpass und Bandsperre, gibt es einige weitere Typen. In der Literatur findet man u.a. noch den Allpass, Phasenschieber, Integrator und Differentiator.&lt;br /&gt;
&lt;br /&gt;
===Der Hilbert-Transformator, ein Breitband-90-Grad-Phasenschieber===&lt;br /&gt;
&lt;br /&gt;
In den Lehrbüchern wird er völlig zu Unrecht eher am Rande abgehandelt. Tatsächlich findet man ihn in allen Schaltungen zur Datenübertragung, zu Modulation oder Demodulation mit I/Q-Mischern, im „Software-defined radio“.&lt;br /&gt;
&lt;br /&gt;
Auch ein Hilbert-Transformator kann mithilfe von Scilab berechnet werden. Allerdings gibt es keine fertige Software, man muss sich durch einige Literatur hindurchfressen, z.&amp;amp;nbsp;B. ISBN 0471619957 Sanjit Mitra, Handbook for DSP (1993), Kapitel „Special Filter Designs“ von [https://web.archive.org/web/20100610031102/http://faculty.cua.edu/regalia/ Phillip Regalia].&lt;br /&gt;
[https://web.itu.edu.tr/hulyayalcin/Signal_Processing_Books/DSP_Applications_Mitra.pdf Matlab-Plots dazu hier ab Seitenzahl 41]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
GNU Octave stellt die Hilbert-Transformation und den Parks-McClellan-hilbert-FIR-Filterentwurf im [http://octave.sourceforge.net/signal/function/remez.html octave-forge Paket &amp;quot;signal&amp;quot;] zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
Eine Fundgrube sind die Matlab-Texte von Prof. Schüssler, die vorab 1998 zum  zweiten Band seines Lehrbuchs auf seiner Webseite veröffentlicht wurden. Inzwischen ist der erste Band in der fünften Auflage erschienen [http://www.springer.com/engineering/signals/book/978-3-540-78250-6 ISBN 9783540782506] , der zweite Band ISBN 9783642011184 2010 erstmalig erschienen,  [http://www.lms.lnt.de/forschung/veroeffentlichungen/buecher/dsv.shtml Software-Download hier] aber die Webseite ist nach seinem Tod 2007 abgeschaltet. Zum Glück gibt es das  &lt;br /&gt;
[http://web.archive.org/web/20041206171820/www.nt.e-technik.uni-erlangen.de/~hws/dsv2programs/index.html  Webarchiv], wo die Texte noch zu finden sind.&lt;br /&gt;
&lt;br /&gt;
Zu dieser Zeit waren die Matlab-Programme noch nicht in „Toolboxen“ untergebracht, deren Funktion von außen nicht mehr sichtbar ist. Daher lassen sie sich relativ einfach in Scilab oder Octave übersetzen.&lt;br /&gt;
&lt;br /&gt;
Vier Versionen von Hilbert-Transformatoren werden hier berechnet: &lt;br /&gt;
* FIR-Hilbert, aufwendig, aber streng linearphasig, der bekannteste Typ, da schon lange mit dem Matlab-Befehl remez / firpm und Parameter &#039;hilbert&#039; berechenbar. Mit dem octave-forge Paket &amp;quot;signal&amp;quot; ist remez mit &amp;quot;hilbert&amp;quot; verfügbar. Scilab kennt diesen Parameter nicht.&lt;br /&gt;
* näherungsweise linearphasiger IIR-Hilbert, maximal flach,&lt;br /&gt;
* näherungsweise linearphasiger IIR-Hilbert, Tschebyscheff &lt;br /&gt;
* minimalphasiger IIR-Hilbert, kompakt, aber mit großen Gruppenlaufzeitschwankungen, eher für Audioanwendungen als Digitalsignale.&lt;br /&gt;
&lt;br /&gt;
Im Artikel von Schüßler/Steffen (siehe unten) sind in zwei vergleichenden Beispielen die Gruppenlaufzeitschwankungen des maximal Flachen etwa halb so groß, des Minimalphasigen etwa fünf Mal so groß wie die Tschbyscheff-Version.&lt;br /&gt;
&lt;br /&gt;
Zumindest der kompakte IIR-Hilbert lässt sich auch in einem ATmega unterbringen. Er besteht aus einer Verzögerung und zwei Allpässen, die wieder aus SOS-Teilfiltern aufgebaut sind. Pro Teilfilter gibt es nur einen Koeffizienten, sodass man mindestens acht Teilfilter verwenden kann.&lt;br /&gt;
&lt;br /&gt;
===Ein Hilbert-Kochrezept (noch unvollständig)===&lt;br /&gt;
&lt;br /&gt;
Folgen wir dem Zahlenbeispiel und Berechnungsweg im „Handbook for DSP“.&lt;br /&gt;
&lt;br /&gt;
Zuerst berechnen wir einen elliptischen &#039;&#039;Halbband&#039;&#039;-Tiefpass. Halbband besagt, dass die beiden Grenzfrequenzen symmetrisch zur halben Nyquist- Frequenz also 0,25 * Abtastfrequenz liegen, siehe Bild oben rechts. Die genauen Bedingungen lauten in der Schreibweise des Buches (&#039;&#039;p&#039;&#039;=passband, &#039;&#039;s&#039;&#039;=stopband):&lt;br /&gt;
* Omega&amp;lt;sub&amp;gt;s&amp;lt;/sub&amp;gt; + Omega&amp;lt;sub&amp;gt;p&amp;lt;/sub&amp;gt; = Pi &amp;lt;br&amp;gt; (auf Omega&amp;lt;sub&amp;gt;sample&amp;lt;/sub&amp;gt; normierte Skala: Samplerate=2*Pi)&lt;br /&gt;
* (1-Delta&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;)&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; +Delta&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;=1&lt;br /&gt;
&lt;br /&gt;
Als Zahlenwerte werden Omega&amp;lt;sub&amp;gt;s&amp;lt;/sub&amp;gt; = 0,55*Pi und Delta&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;=0,01 gewählt, und damit ein elliptischer IIR-Tiefpass 7.Ordnung berechnet.&lt;br /&gt;
Damit erhält er folgende Zahlenwerte der Pole:&lt;br /&gt;
&lt;br /&gt;
 0  0,436688  0,743707 0,927758&lt;br /&gt;
&lt;br /&gt;
===Scilab-Berechnung des Halbbandfilters===&lt;br /&gt;
&lt;br /&gt;
Mit Scilab erhalten wir nach einigem Ausprobieren praktisch dieselben Zahlenwerte, siehe Bild. Die Pole müssten für ein ideales Halbbandfilter genau auf der imaginären Achse liegen, der Realteil genau Null sein (Der Fehler kommt daher, dass die Angabe von f&amp;lt;sub&amp;gt;stop&amp;lt;/sub&amp;gt; vom Programm nicht berücksichtigt wird, das Filter wäre überbestimmt).&lt;br /&gt;
Diese Zahlen werden noch quadriert (&#039;&#039;konjugiert komplexe&#039;&#039; Pole zusammengefasst) und bilden schließlich die Koeffizienten des Hilbert-Transformators.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Halbbandfilter.png|Mit Scilab berechnetes Halbbandfilter 7.Ordnung|640px]]&lt;br /&gt;
&lt;br /&gt;
Die Übertragungsfunktion des gesuchten Hilbert-Transformators soll wie bisher H(z) heißen. Zur Unterscheidung nennen wir die bis jetzt berechnete Tiefpassfunktion G(z). &lt;br /&gt;
&lt;br /&gt;
Wieder wird sie in SOS-Teilfilter aufgeteilt. Hier allerdings in die &amp;lt;u&amp;gt;Summe&amp;lt;/u&amp;gt; von zwei &amp;lt;u&amp;gt;parallel&amp;lt;/u&amp;gt; geschalteten &#039;&#039;Allpass&#039;&#039;-Funktionen A&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; und A&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt; plus eine Verzögerung um einen Sampletakt, in der Übertragungsfunktion als „z&amp;lt;sup&amp;gt;-1&amp;lt;/sup&amp;gt;“ ausgedrückt.&lt;br /&gt;
&lt;br /&gt;
Ein Allpass läßt alle Signalfrequenzen mit unveränderter Amplitude durch, verändert nur die Phase. Seine SOS-Teilfunktion ist besonders einfach aufgebaut, zwei Koeffizienten sind Null, zwei sind gleich Eins und die beiden restlichen identisch. Damit benötigt man nur eine Multiplikation pro Teilfilter.&lt;br /&gt;
&lt;br /&gt;
Die Tiefpass-Übertragungsfunktion erhält so die Form:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;G(z) = ½ * ( A&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; (z&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;) + z&amp;lt;sup&amp;gt;-1&amp;lt;/sup&amp;gt; * A&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt; (z&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;))&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
mit&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
A_{1}(z^{2})=\frac{z^{-2}+0,190696}{1+0,190696\ast z^{-2}}\ast&lt;br /&gt;
{\frac{z^{-2}+0,860735}{1+0,860735\ast z^{-2}}}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
A_{2}(z^{2})=\frac{z^{-2}+0,553100}{1+0,553100\ast z^{-2}}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn man die beiden Ausgänge nicht addiert, sondern subtrahiert, entsteht ein Hochpass gleicher Grenzfrequenz. Beides kombiniert ergibt eine digitale &#039;&#039;Frequenzweiche&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Zum Übergang auf den Hilbert-Transformator ersetzen (&#039;&#039;substituieren&#039;&#039;) wir das z durch -jz und multiplizieren das ganze mit 2:&lt;br /&gt;
&lt;br /&gt;
H(z)= 2*G(-jz)&lt;br /&gt;
  &lt;br /&gt;
&#039;&#039;&#039;H(z) = A&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; (-z&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;) + j* z&amp;lt;sup&amp;gt;-1&amp;lt;/sup&amp;gt; * A&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt; (-z&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
mit&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
A_{1}(-z^{2})=\frac{z^{-2}-0,190696}{1-0,190696\ast z^{-2}}\ast&lt;br /&gt;
{\frac{z^{-2}-0,860735}{1-0,860735\ast z^{-2}}}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
A_{2}(-z^{2})=\frac{z^{-2}-0,553100}{1-0,553100\ast z^{-2}}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie man sieht, ändern sich nur die Vorzeichen. Die Pole liegen aber im Pol-Nullstellendiagramm auf der reellen Achse.&lt;br /&gt;
&lt;br /&gt;
Die Ausgänge der beiden Allpässe sind jetzt gegeneinander um 90 Grad phasenverschoben, und können auf einen I/Q-Modulator gegeben werden. Umgekehrt kann man auch die beiden Eingänge auftrennen, und zwei um 90 Grad versetzte Signale aus einem I/Q-Demodulator einspeisen und die Ausgangssignale addieren oder subtrahieren, je nach gewünschtem Seitenband.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Allpaesse.png]]&lt;br /&gt;
&lt;br /&gt;
Und weil das so gut funktionierte, hier noch die Berechnung des Hilbert-Transformators [http://www.mikrocontroller.net/topic/92630#new von Olli Niemitalo] mit einem Halbband-Tiefpass 17.Ordnung, was zu acht SOS-Teilfiltern führt, dazu folgt unten ein ATmega48-Programm.&lt;br /&gt;
Die originalen URL sind verwaist, aber im Webarchiv noch zu finden:&amp;lt;br&amp;gt;&lt;br /&gt;
https://web.archive.org/web/20070719141658/http://yehar.com/ViewHome.pl?page=dsp/hilbert/ &amp;lt;br&amp;gt;&lt;br /&gt;
https://web.archive.org/web/20070814013543/http://yehar.com/ViewHome.pl?page=dsp/hilbert/011729.html &amp;lt;br&amp;gt;&lt;br /&gt;
Olli ist auch heute (2019) noch aktiv:&amp;lt;br&amp;gt;&lt;br /&gt;
http://yehar.com/blog/&amp;lt;br&amp;gt;&lt;br /&gt;
speziell sein IIR-Hilbert:&amp;lt;br&amp;gt;&lt;br /&gt;
http://yehar.com/blog/?p=368&amp;lt;br&amp;gt;&lt;br /&gt;
Diskussion auch dazu:&amp;lt;br&amp;gt;&lt;br /&gt;
https://dsp.stackexchange.com/questions/37411/iir-hilbert-transformer/59157#59157&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Bild:Halbbandfilter2.png|Halbbandfilter 17.Ordnung|640px]]&lt;br /&gt;
&lt;br /&gt;
===Der näherungsweise linearphasige Hilbert-Transformator===&lt;br /&gt;
&lt;br /&gt;
Er wird im Handbook for DSP auf zwei Seiten sehr kurz abgehandelt. Statt aus zwei Allpässen besteht er aus einem einzigen, im anderen Zweig wird das Signal nur zeitverzögert, was mit einem Ringpuffer wenig Rechenzeit kostet. Eine Zeitverzögerung ist sozusagen die einfachste Form eines Allpasses, damit ist diese Bauform ein Spezialfall der oben gezeigten. Aus Schüsslers Texten erfahren wir noch, dass das Halbband-Tiefpassfilter zur Berechnung hier Tschebyscheff-Charakter haben muß.&lt;br /&gt;
&lt;br /&gt;
Das Zahlenbeispiel zitiert Regalia aus einer anderen Veröffentlichung [http://www.cs.tut.fi/~mr/MRJulk92.html (M. Renfors and T. Saramäki, A class of approximately linear phase digital filters composed of allpass subfilters 1986 ) ] Der Allpass hat neun Koeffizienten, die Zeitverzögerung beträgt 17 Sampletakte. Der Halbband-Tiefpass hat eine Sperrdämpfung von &amp;gt; 49 dB. Sein Frequenzgang und der Phasengang des berechneten Hilbert-Transformators sind als Bild gezeigt.&lt;br /&gt;
&lt;br /&gt;
Zum Allpass gibt es noch folgende Zahlenwerte:&lt;br /&gt;
&lt;br /&gt;
Pole location for A(z)&amp;lt;br&amp;gt;&lt;br /&gt;
z= 	-0.8699928078&amp;lt;br&amp;gt;&lt;br /&gt;
	 0.491194141 ± j0.183666529&amp;lt;br&amp;gt;&lt;br /&gt;
	 0.252724179 ± j0.463085544&amp;lt;br&amp;gt;&lt;br /&gt;
	-0.109950894 ± j0.548611467&amp;lt;br&amp;gt;&lt;br /&gt;
	-0.447326028 ± j0.356810323&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das könnte also ebenfalls noch in einen  ATmega passen.&lt;br /&gt;
&lt;br /&gt;
===Hilbert ohne Multiplizierer===&lt;br /&gt;
&lt;br /&gt;
Eine interessante Variante wird im Artikel [http://kondor.etf.bg.ac.yu/~lutovac/pdf/eusi98lm.pdf Design of multiplierless elliptic IIR halfband filters and Hilbert transformers] vorgestellt. Ähnlich wie im Cordic-Algorithmus für trigonometrische Funktionen werden Multiplikationen vermieden, durch geschickte Wahl der Koeffizienten als Zweierpotenzen.&lt;br /&gt;
&lt;br /&gt;
Die beiden Allpässe des Zahlenbeispiels haben folgende Übertragungsfunktionen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
A_1(z^{-2})&lt;br /&gt;
&amp;amp;=\frac{z^{-2}-0{,}12109375}{1-0{,}12109375 \cdot z^{-2}}&lt;br /&gt;
\cdot\frac{z^{-2}-0{,}6640625}{1-0{,}6640625 \cdot z^{-2}} \\&lt;br /&gt;
&amp;amp;=\frac{z^{-2}-(\frac18 - \frac1{256})}{1-(\frac18 - \frac1{256}) \cdot z^{-2}}&lt;br /&gt;
\cdot\frac{z^{-2}-(\frac12 + \frac18 + \frac1{32} + \frac1{128})}{1-(\frac12 + \frac18 + \frac1{32} + \frac1{128})\cdot z^{-2}}\\&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
A_2(z^{-2})\cdot{z^{-1}}&lt;br /&gt;
&amp;amp;=z^{-1}&lt;br /&gt;
\cdot\frac{z^{-2}-0{,}390625}{1-0{,}390625 \cdot z^{-2}}&lt;br /&gt;
\cdot\frac{z^{-2}-0{,}890625}{1-0{,}890625 \cdot z^{-2}}\\&lt;br /&gt;
&amp;amp;=z^{-1}&lt;br /&gt;
\cdot\frac{z^{-2}-(\frac14 + \frac18 + \frac1{64})}{1-(\frac14 + \frac18 + \frac1{64}) \cdot z^{-2}}&lt;br /&gt;
\cdot\frac{z^{-2}-(1 - \frac18 + \frac1{64})}{1-(1 - \frac18 + \frac1{64}) \cdot z^{-2}}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Hilbert Transformator nach der FIR-Methode ==&lt;br /&gt;
&lt;br /&gt;
Nach dem Additionstheorem ergibt sich aus dem multiplikativen Mischen (u_prod = u_1 * u_2) zweier Wechselspannungen eine Überlagerung (u_sum = u_3 + u_4) zweier anderer Wechelspannungen; die Frequenz der einen Wechselspannung ist die Summe der Frequenzen der Faktor-Spannungen - die Frequenz der anderen Wechselspannung ist die Differenz der Frequenzen der Faktorspannungen. Jeweils eine der beiden Frequenzen ist das Nutz-Signal, die andere Frequenz ist die Spiegelfrequenz.&lt;br /&gt;
&lt;br /&gt;
Der Hilbert-Tranformator ist ein Mittel um nur das Nutzsignal und nicht die Spiegelfrequenz zu mischen. Es wird nach den Regeln der Multiplikation komplexer Zahlen gemischt. Eingabesignal und Mischoszillator müssen in der Form der EULERschen Identität vorliegen: &lt;br /&gt;
&lt;br /&gt;
y = A * exp( j * phi )  = A * ( cos( phi ) + j * sin( phi )  ) ; phi = omega * t ; omega = 2 * pi * f ; f ... Frequenz ; A ... Amplitude ; t ... Zeit&lt;br /&gt;
&lt;br /&gt;
Mit der exp() - Darstellung kann man mischen, indem man den Ausdruck phi = 2 * pi * t * (f1 + f2) anwendet. Dabei addieren sich die Frequenzen ohne Spiegelfrequenz. Beide Frequenzen müssen als komplexe Zahlen vorliegen, also jede Frequenz als zwei Wechselspannungen mit (jeweils pro Frequenz) gleicher Amplitude. Liegt nur ein einfaches Sinus-Signal vor, kann man das dazugehörige Cosinus-Signal durch Phasenverschiebung um 90° mit einem Hilbert-Transformator erreichen. Danach wendet man die Multiplikation an:&lt;br /&gt;
&lt;br /&gt;
y[ re, j * im ]:= x1[ re, j * im ]* x2[ re, j * im ] = (x1.re * x2.re - x1.im * x2.im) + j * (x1.re * x2.im + x2.re * x1.im) ; re ... Realteil ; im ... Imag. Teil&lt;br /&gt;
&lt;br /&gt;
Jedes Glied des einen Faktors mit jedem Glied des anderen Faktors unter Beachtung der imaginären Einheit multiplizieren. Wendet man bei dem Signal einer der beiden Frequenzen nur einen der beiden Anteile (entweder nur realen Cosinus-Teil oder imaginären Sinusteil) so entsteht eine &amp;quot;negative&amp;quot; Frequenz (der Zeiger in der komplexen Zahlenebene dreht sich andersherum). Somit wird diese Frequenz von der anderen subtrahiert (phi = 2 * pi * t * (f1 - f2)). Das kann sowohl rechnerisch als auch durch Umpolen einer Bandfilterwicklung errreicht werden. Für Zwischenergebnisse nutzt man beide Signalteile weiter, für z.B. eine Audioausgabe genügt einer.&lt;br /&gt;
&lt;br /&gt;
Kann man zu einem Sinussignal das Cosinus-Signal auch ohne synthetisches Filter erhalten? Genau weiß ich es nicht. Für einen Oszillator braucht man mindestens zwei Energiespeicher. Beide sind (wenn es kein Drehstromoszillator ist) um 90° phasenverschoben. Hier kommt man ohne synthetisches Filter aus. Anders bei Schallwellen. Der eine Speicher besteht hier sowohl aus Schalldruck als auch aus Schallschnelle. Sind beide um 0° phasenverschoben, so bewegt sich die Welle in die eine Richtung, bei 180° entsprechend entgegengesetzt. Der andere Speicher ist die 1. Ableitung von jeweils Schalldruck und Schallschnelle. Die Ableitung ist um 90° phasenverschoben aber bei frequenzabhängiger Amplitude ( y = A * sin( omega * t ) ; y&#039; = omega * A * cos( omega * t ) ). Ohne Spiegelfrequenz kann man das nur für eine feste Frequenz mischen. Bei einem Frequenzband braucht man das synthetische Filter.&lt;br /&gt;
&lt;br /&gt;
Der Hilbert-Transformator erzeugt aus einem Sinus-Signal das um 90° verschobene Cosinus-Signal. Ein Beispiel in Python:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Begin Hilbert FIR filter.&lt;br /&gt;
import math # Math&lt;br /&gt;
import numpy as np # Math&lt;br /&gt;
import matplotlib as mlp # Plot&lt;br /&gt;
import matplotlib.pyplot as plt # Plot&lt;br /&gt;
&lt;br /&gt;
FREQUENCY = 400.0 # 1 / s&lt;br /&gt;
RATE = 48000.0 # samples / s&lt;br /&gt;
SAMPLES = 4000&lt;br /&gt;
CELLS = 501&lt;br /&gt;
STEPS = SAMPLES - CELLS&lt;br /&gt;
PREFIX = (CELLS - 1) / 2&lt;br /&gt;
SUFFIX = CELLS - PREFIX&lt;br /&gt;
POSTFIX = SAMPLES - CELLS&lt;br /&gt;
&lt;br /&gt;
samples = range(SAMPLES)&lt;br /&gt;
cells = range(CELLS)&lt;br /&gt;
steps = range(STEPS)&lt;br /&gt;
prefixes = range(PREFIX)&lt;br /&gt;
suffixes = range(SUFFIX)&lt;br /&gt;
postfixes = range(POSTFIX)&lt;br /&gt;
&lt;br /&gt;
input = []&lt;br /&gt;
re = []&lt;br /&gt;
im = []&lt;br /&gt;
coefficients = []&lt;br /&gt;
&lt;br /&gt;
def plot():&lt;br /&gt;
&lt;br /&gt;
	for sample in samples:&lt;br /&gt;
		if(SAMPLES / 2 &amp;gt; sample):&lt;br /&gt;
			_phi = FREQUENCY * sample / RATE * 2.0 * math.pi&lt;br /&gt;
		else:&lt;br /&gt;
			_phi = 5 * FREQUENCY * sample / RATE * 2.0 * math.pi&lt;br /&gt;
		input.append(math.sin(_phi))&lt;br /&gt;
&lt;br /&gt;
	for cell in cells:&lt;br /&gt;
		arg = cell - (CELLS - 1) / 2.0&lt;br /&gt;
		if(0.0 == arg):&lt;br /&gt;
			coefficients.append(0.0)&lt;br /&gt;
		else:&lt;br /&gt;
			arg *= math.pi&lt;br /&gt;
			coefficients.append((1.0 - math.cos(arg)) / arg)&lt;br /&gt;
	&lt;br /&gt;
	for postfix in postfixes:&lt;br /&gt;
		coefficients.append(0.0)&lt;br /&gt;
	&lt;br /&gt;
	for prefix in prefixes:&lt;br /&gt;
		re.append(0.0)&lt;br /&gt;
		im.append(0.0)&lt;br /&gt;
		&lt;br /&gt;
	for step in steps:&lt;br /&gt;
		re.append(input[step + PREFIX])&lt;br /&gt;
		sum = 0.0&lt;br /&gt;
		for cell in cells:&lt;br /&gt;
			sum += input[step + cell] * coefficients[cell];&lt;br /&gt;
		im.append(sum)&lt;br /&gt;
		&lt;br /&gt;
	for suffix in suffixes:&lt;br /&gt;
		re.append(0.0)&lt;br /&gt;
		im.append(0.0)&lt;br /&gt;
	&lt;br /&gt;
	# Prepare the plot.&lt;br /&gt;
	plt.ylabel(&#039;amplitude&#039;)&lt;br /&gt;
	plt.xlabel(&#039;timesteps&#039;)&lt;br /&gt;
	plt.axis([0, SAMPLES - 1, -1.5, 1.5])&lt;br /&gt;
	plt.grid(True)&lt;br /&gt;
	plt.plot(samples, re, &#039;r-&#039;)&lt;br /&gt;
	plt.plot(samples, im, &#039;b-&#039;)&lt;br /&gt;
	plt.show()&lt;br /&gt;
# End.&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
Neben ein Array aus abgetasteten Werten eines akustischen Signales (hier Sinus-Signal, künstlich berechnet) wird das Array des Transformationskerns gelegt. Das Array des Transformationskerns ist dabei viel kürzer und es wird nur der gemeinsame Bereich berechnet. Der Wert des Cosinus-Signals, das zu dem Sinus-Signal gehört, das sich auf der Position der Mitte des Transformationskerns befindet, ergibt sich aus der Summe der Werte aus dem Sinus-Signal multiplizert mit den Faktoren aus dem Transformationskern mit gleichem Index. Das folgende Cosinus-Signal wird berechnet indem man zuvor den Transformationskern um einen Index gegenüber dem Eingabe-Sinus-Signal weiterschiebt (usw. bis zum Ende des Signales). Am Anfang und am Ende des berechneten Cosinus-Signales entsteht ein Stück Verlust der jeweils halb so lang wie der Transformationskern ist. Bei sehr lang dauernden Signalen (fast immer) ist statt dessen mit einem Ringpuffer zu arbeiten.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
t ... Zeit&lt;br /&gt;
b[Länge k] ... Transformationskern&lt;br /&gt;
i[undendlich lang] ... Sinus - Signal oder Summe aus Sinus-Signalen&lt;br /&gt;
o[undendlich lang] ... um 90° verschobenes Cosinus - Signal&lt;br /&gt;
=&amp;gt;&lt;br /&gt;
o[t] := Summe { i[n+t] * b[n+t] } ; -k/2 &amp;lt;= n &amp;lt;= +k/2 ; t &amp;gt;= k/2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Der Transformationskern kann wie folgt ermittelt werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x ... natürliche Zahl &amp;gt; 0&lt;br /&gt;
k ... 4 * x + 1&lt;br /&gt;
b[] ... Transformationskern der Länge k&lt;br /&gt;
n ... Index innerhalb des Tranformationskerns&lt;br /&gt;
pi ... 3.14159...&lt;br /&gt;
b[n] := ( 1 - cos( n * pi ) ) / ( n * pi ) ; Ausnahme ist b[0] := 0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Datei:FIR_Kernel_Small.png|200px|thumb|right|Hilbert Transformationskern klein]]&lt;br /&gt;
&lt;br /&gt;
Dabei ist das Argument der cos() - Funktion immer ganzzahlig. &amp;quot;1 - cos(...)&amp;quot; ist für ungerade &amp;quot;n&amp;quot; immer NULL. Der Kern hat nahe n == 0 maximale Werte und nimmt zum Rand hin ab. Ein Kern mit zuwenig Länge (k ist zu klein) wirkt als Hochpass und verkleinert die Amplitude von Signalen kleiner Frequenz (ist unbrauchbar). Kommen hohe und tiefe Frequenzen im Signal gleichzeitig vor, dann braucht man sowohl eine hohe Abtastrate als auch einen langen Kern ( k wird groß, z.B. Größenordnung 801 bei einem Audiosignal). Ändert sich das Nutzsignal unerwartet sprungartig so erhält man im Cosinus-Signal eine Art Sprungantwort.&lt;br /&gt;
&lt;br /&gt;
* Großer Transformationskern : [[Medium:FIR_Kernel_Big.png]]&lt;br /&gt;
* Transformation zweier Signale verschiedener Frequenz : [[Medium:Hilber_FIR_OK.png]]&lt;br /&gt;
* Transformation eines Sprunges im Signal : [[Medium:Hilbert_FIR_OK_Lense.png]]&lt;br /&gt;
* Transformationsfehler bei zu kleinem Kern (k ist zu klein) :  [[Medium:Hilbert_FIR_Too_Small_Kernel.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Zusammenfassung&amp;lt;/b&amp;gt;&lt;br /&gt;
Hilbert-Transformation ermittelt zu einem Sinus-Signal das um 90° verschobene Cosinus-Signal. Das gilt auch für eine Summe von Sinussignalen unterschiedlicher Frequenzen und Amplituden. Die Amplitude des Cosinus-Signales ist gleich der Amplitude des Sinus-Signales (kann geringfügig abweichen aber korrigiert werden). Das Transformieren erfolgt meist synthetisch, z.B. in digitalen Signal Prozessoren. Die Hilbert-Transformation wird verwendet, wenn man Sinus-Signal und Cosinus-Signal benötigt aber nur das Sinus-Signal vorliegt. Beide Signale (sin(...) und cos(...)) zusammen entsprechen einer Folge komplexer Zahlen. Damit kann man multiplikativ mischen ohne Spiegelfrequenz. Liegen beide Faktoren der Mischung als komplexe Zahlen vor, kann man jedes Glied der einen Zahl mit jedem Glied der anderen Zahl multiplizieren unter Beachtung der komplexen Einheit &amp;quot;j&amp;quot;. Falls man sich dabei beide Faktoren jedoch in der exp( j * omega * t ) Schreibweise denkt, so multipliziert man statt dessen Potenzen, indem man die Exponenten addiert. Für eine Berechnung braucht man 4 Multiplikationen, was entweder digital erfolgen kann oder im analogen Fall vier Mischer (z.B. Ringmischer oder Gilbertzellen) benötigt, wenn man das ganze Ergebnis braucht. Der Transformationskern ist ein Array aus Zahlen deren Werte in der Mitte des Arrays groß sind und zum Rand hin abnehmen.&lt;br /&gt;
&lt;br /&gt;
==Weitere Literatur zu Hilbert==&lt;br /&gt;
* Schüssler / [http://www.lnt.de/LMS/staff/index.php?lang=de&amp;amp;function=1&amp;amp;person=5 Steffen] &amp;quot;Halfband Filters and Hilbert Transformers&amp;quot; &amp;lt;br&amp;gt; Irgendwo im Web hatte ich den vollständigen Artikel als PDF gefunden, leider die Adresse nicht notiert, Google findet nur [http://www.springerlink.com/content/p5480n6p8t73t633/ kostenpflichtige Downloads].&lt;br /&gt;
* Dutta / Kumar [http://eprint.iitd.ac.in/dspace/bitstream/2074/1608/1/roydig1989.pdf On Digital Differentiators, Hilbert Transformers, and Half-Band Low-Pass Filters] &amp;lt;br&amp;gt; dank Schrifterkennungsprogramm leicht lädiert&lt;br /&gt;
* Miroslav Lutovac / Ljiljana Milic [http://www.telfor.rs/telfor2000/radovi/7-10.pdf Half-band IIR Filter Design Using Matlab],  [http://kondor.etf.bg.ac.yu/~lutovac/confer.htm weitere Artikel der Autoren]&lt;br /&gt;
* Göckler / Damjanovic [http://www.dsv.rub.de/imperia/md/content/public/wsr06_goecklerdamjanovic.pdf A Family of Efficient Complex Halfband Filters]&lt;br /&gt;
&lt;br /&gt;
==ATmega-Programm Hilbert-Transformer ( fast fertig, schwingt leider)==&lt;br /&gt;
Da der Adressenbereich des ATmega nicht groß genug ist, wird die Tabelle im SRAM in zwei Hälften geteilt.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;* Hilbert transformer with ATmega48P, 90 degree broadband phase shifter   *&lt;br /&gt;
;* 15 MHz xtal, input ADC0, PWM-output OCR1a/b, test output PD0            *&lt;br /&gt;
;* Christoph Kessler 2008                         db1uq_at_t-online_dot_de *&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
.nolist&lt;br /&gt;
.include &amp;quot;m48pdef.inc&amp;quot;&lt;br /&gt;
.list&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;* register 0-15 (no &amp;quot;immediate&amp;quot;-operations possible):&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
.def	mult_l	= r0	; multiplier result&lt;br /&gt;
.def	mult_h	= r1	; multiplier result&lt;br /&gt;
.def	zero	= r2	; zero register (used to add carry flag)&lt;br /&gt;
.def	savsrg	= r3	; save status register during interrupt routine&lt;br /&gt;
.def	reg04	= r4	; free&lt;br /&gt;
.def	reg05	= r5	; free&lt;br /&gt;
.def	reg06	= r6	; free&lt;br /&gt;
.def	reg07	= r7	; free&lt;br /&gt;
.def	reg08	= r8	; free&lt;br /&gt;
.def	reg09	= r9	; free&lt;br /&gt;
.def	reg10	= r10	; free&lt;br /&gt;
.def	reg11	= r11	; free&lt;br /&gt;
.def	reg12	= r12	; free&lt;br /&gt;
.def	accu0	= r13	; Accumulator - 32bit for Interrupt routine&lt;br /&gt;
.def	accu1	= r14	; Accumulator - 32bit for Interrupt routine&lt;br /&gt;
.def	accu2	= r15	; Accumulator - 32bit for Interrupt routine&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;* register 16-23 (&amp;quot;immediate&amp;quot;-operations possible):&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
.def	accu3	= r16	; Accumulator - 32bit for Interrupt routine&lt;br /&gt;
.def	reg17	= r17	; free&lt;br /&gt;
.def	reg18	= r18	; free&lt;br /&gt;
.def	reg19	= r19	; free&lt;br /&gt;
.def	datal	= r20	; Data samples mul register&lt;br /&gt;
.def	datah	= r21	;  for Interrupt routine&lt;br /&gt;
.def	coefl	= r22	; Filter coefficient mul register&lt;br /&gt;
.def	coefh	= r23	;  for Interrupt routine&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;* register 24-31    (16Bit-registers) &lt;br /&gt;
;***************************************************************************&lt;br /&gt;
.def	tmp1	= r24	; general temporary register&lt;br /&gt;
.def	tmp2	= r25	; general temporary register&lt;br /&gt;
;	XL	= r26	; free&lt;br /&gt;
;	XH	= r27	; free&lt;br /&gt;
;	YL	= r28	; used by Interrupt routine&lt;br /&gt;
;	YH	= r29	; used by Interrupt routine&lt;br /&gt;
;	ZL	= r30	; init routine only, free for main program&lt;br /&gt;
;	ZH	= r31	; init routine only, free for main program&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* constants :&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;1st table:&lt;br /&gt;
	;&amp;quot;allpass&amp;quot;0:&lt;br /&gt;
.equ	 x10	= 0&lt;br /&gt;
	; allpass 2:&lt;br /&gt;
.equ	 x12	= 2&lt;br /&gt;
.equ	 x22	= 4&lt;br /&gt;
.equ	 y02	= 6&lt;br /&gt;
.equ	 y12	= 8&lt;br /&gt;
.equ	 y22	= 10&lt;br /&gt;
	; allpass 4:&lt;br /&gt;
.equ	 x14	= 12&lt;br /&gt;
.equ	 x24	= 14&lt;br /&gt;
.equ	 y04	= 16&lt;br /&gt;
.equ	 y14	= 18&lt;br /&gt;
.equ	 y24	= 20&lt;br /&gt;
	; allpass 6:&lt;br /&gt;
.equ	 x16	= 22&lt;br /&gt;
.equ	 x26	= 24&lt;br /&gt;
.equ	 y06	= 26&lt;br /&gt;
.equ	 y16	= 28&lt;br /&gt;
.equ	 y26	= 30&lt;br /&gt;
	; allpass 8:&lt;br /&gt;
.equ	 x18	= 32&lt;br /&gt;
.equ	 x28	= 34&lt;br /&gt;
.equ	 y08	= 36&lt;br /&gt;
.equ	 y18	= 38&lt;br /&gt;
.equ	 y28	= 40&lt;br /&gt;
&lt;br /&gt;
.equ	 k2	= 42&lt;br /&gt;
.equ	 k4	= 44&lt;br /&gt;
.equ	 k6	= 46&lt;br /&gt;
.equ	 k8	= 48&lt;br /&gt;
;2nd table:&lt;br /&gt;
.equ	 k1	= 0&lt;br /&gt;
.equ	 k3	= 2&lt;br /&gt;
.equ	 k5	= 4&lt;br /&gt;
.equ	 k7	= 6&lt;br /&gt;
	; allpass 1:&lt;br /&gt;
.equ	 x11	= 8&lt;br /&gt;
.equ	 x21	= 10&lt;br /&gt;
.equ	 y01	= 12&lt;br /&gt;
.equ	 y11	= 14&lt;br /&gt;
.equ	 y21	= 16&lt;br /&gt;
	; allpass 3:&lt;br /&gt;
.equ	 x13	= 18&lt;br /&gt;
.equ	 x23	= 20&lt;br /&gt;
.equ	 y03	= 22&lt;br /&gt;
.equ	 y13	= 24&lt;br /&gt;
.equ	 y23	= 26&lt;br /&gt;
	; allpass 5:&lt;br /&gt;
.equ	 x15	= 28&lt;br /&gt;
.equ	 x25	= 30&lt;br /&gt;
.equ	 y05	= 32&lt;br /&gt;
.equ	 y15	= 34&lt;br /&gt;
.equ	 y25	= 36&lt;br /&gt;
	; allpass 7:&lt;br /&gt;
.equ	 x17	= 38&lt;br /&gt;
.equ	 x27	= 40&lt;br /&gt;
.equ	 y07	= 42&lt;br /&gt;
.equ	 y17	= 44&lt;br /&gt;
.equ	 y27	= 46&lt;br /&gt;
;*****************************************************&lt;br /&gt;
;* Macros&lt;br /&gt;
;*****************************************************&lt;br /&gt;
.MACRO load_node&lt;br /&gt;
	ldd	datal,Y+@0	; Load low byte of node &lt;br /&gt;
	ldd	datah,Y+@0+1	; Load high byte of node&lt;br /&gt;
.ENDMACRO&lt;br /&gt;
.MACRO update_node&lt;br /&gt;
	std	Y+@0,datal	; Store low byte of node &lt;br /&gt;
	std	Y+@0+1,datah	; Store high byte of node&lt;br /&gt;
.ENDMACRO&lt;br /&gt;
.MACRO add_node&lt;br /&gt;
	ldd	coefl,Y+@0	; Load 2nd node low&lt;br /&gt;
	ldd	coefh,Y+@0+1	; Load 2nd node high&lt;br /&gt;
	add	datal,coefl	; Add low bytes&lt;br /&gt;
	adc	datah,coefh	; Add with carry high bytes&lt;br /&gt;
.ENDMACRO&lt;br /&gt;
.MACRO mult_32&lt;br /&gt;
	ldd	coefl,Y+@0	; Load low byte of coefficient&lt;br /&gt;
	ldd	coefh,Y+@0+1	; Load high byte of coefficient&lt;br /&gt;
	muls	coefh,datah	; Signed multiply, coefficient high byte and data high byte&lt;br /&gt;
	mov     accu2,mult_l	; Copy result word into accumulator byte 2:3&lt;br /&gt;
	mov     accu3,mult_h	; Copy result word into accumulator byte 2:3&lt;br /&gt;
	mul	coefl,datal	; Unsigned multiply, coefficient low byte and data low byte&lt;br /&gt;
	mov	accu0,mult_l	; Copy result word into accumulator byte 2:3&lt;br /&gt;
	mov	accu1,mult_h	; Copy result word into accumulator byte 2:3&lt;br /&gt;
	mulsu	coefh,datal	; Signed-unsigned multiply, coefficient high byte and data low byte&lt;br /&gt;
	sbc	accu3,zero	; Sign extention&lt;br /&gt;
	add	accu1,mult_l	; Add low byte of result to accumulator byte 1&lt;br /&gt;
	adc	accu2,mult_h	; Add with carry high byte of result to accumulator byte 2&lt;br /&gt;
	adc	accu3,zero	; Add carry to accumulator byte 3&lt;br /&gt;
	mulsu	datah,coefl	; Signed-unsigned multiply, data high byte and coefficient low byte&lt;br /&gt;
	sbc	accu3,zero	; Sign extention&lt;br /&gt;
	add	accu1,mult_l	; Add low byte of result to accumulator byte 1&lt;br /&gt;
	adc	accu2,mult_h	; Add with carry high byte of result to accumulator byte 2&lt;br /&gt;
	adc	accu3,zero	; Add carry to accumulator byte 3&lt;br /&gt;
.ENDMACRO&lt;br /&gt;
.MACRO subtr_node&lt;br /&gt;
	ldd	datal,Y+@0	; Load 2nd node low&lt;br /&gt;
	ldd	datah,Y+@0+1	; Load 2nd node high&lt;br /&gt;
	sub	accu0,datal	; Subtract low byte&lt;br /&gt;
	sbc	accu1,datah	; Subtract with carry high byte&lt;br /&gt;
	sbc	accu2,zero	;&lt;br /&gt;
	sbc	accu3,zero	;&lt;br /&gt;
.ENDMACRO&lt;br /&gt;
.MACRO limit_store&lt;br /&gt;
	cpi	accu3,$40	; accu &amp;lt;   $40000000 ?&lt;br /&gt;
	brlo	NoLimit1	;&lt;br /&gt;
	cpi	accu3,-$40	; accu &amp;gt;= -$40000000 ?&lt;br /&gt;
	brsh	NoLimit1	;&lt;br /&gt;
	clr	accu2		; accu2 = $00&lt;br /&gt;
	cpi	accu3,0		;&lt;br /&gt;
	brge	PosLim1		; &lt;br /&gt;
	ldi	accu3,$80	; accu3 = $80&lt;br /&gt;
	rjmp	Limit1		; &lt;br /&gt;
PosLim1:&lt;br /&gt;
	ldi	accu3,$7F	; accu3 = $7F	&lt;br /&gt;
	com	accu2		; accu2 = $FF	&lt;br /&gt;
	rjmp	Limit1		; &lt;br /&gt;
NoLimit1:&lt;br /&gt;
	lsl	accu1		; Scaling to gain factor 2^16&lt;br /&gt;
	rol	accu2		; &lt;br /&gt;
	rol	accu3		; &lt;br /&gt;
Limit1:&lt;br /&gt;
	std	Y+@0,accu2	; &lt;br /&gt;
	std	Y+@0+1,accu3	; &lt;br /&gt;
.ENDMACRO&lt;br /&gt;
.LISTMAC&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* reset/interrupt-vectors:&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
.cseg&lt;br /&gt;
	rjmp	Initial		; after RESET to main program&lt;br /&gt;
	reti			; External Interrupt Request 0&lt;br /&gt;
	reti			; External Interrupt Request 1&lt;br /&gt;
	reti			; Pin Change Interrupt Request 0&lt;br /&gt;
	reti			; Pin Change Interrupt Request 1&lt;br /&gt;
	reti			; Pin Change Interrupt Request 2&lt;br /&gt;
	reti			; Watchdog Time-out Interrupt&lt;br /&gt;
	reti			; Timer/Counter2 Compare Match A&lt;br /&gt;
	reti			; Timer/Counter2 Compare Match B&lt;br /&gt;
	reti			; Timer/Counter2 Overflow&lt;br /&gt;
	reti			; Timer/Counter1 Capture Event&lt;br /&gt;
	reti			; Timer/Counter1 Compare Match A&lt;br /&gt;
	reti			; Timer/Counter1 Compare Match B&lt;br /&gt;
	reti			; Timer/Counter1 Overflow&lt;br /&gt;
	reti			; Timer/Counter0 Compare Match A&lt;br /&gt;
	reti			; Timer/Counter0 Compare Match B&lt;br /&gt;
	reti			; Timer/Counter0 Overflow&lt;br /&gt;
	reti			; SPI Serial Transfer Complete&lt;br /&gt;
	reti			; USART0, Rx Complete&lt;br /&gt;
	reti			; USART0 Data register Empty&lt;br /&gt;
	reti			; USART0, Tx Complete&lt;br /&gt;
	rjmp	ADCint		; ADC Conversion Complete&lt;br /&gt;
	reti			; EEPROM Ready   &lt;br /&gt;
	reti			; 2-wire Serial Interface&lt;br /&gt;
	reti			; Store Program Memory Read&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* after reset: initialise stack,ports&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
Initial: &lt;br /&gt;
	ldi	tmp1,Low(RAMEND)&lt;br /&gt;
	out	SPL,tmp1	;&lt;br /&gt;
	ldi	tmp1,High(RAMEND)&lt;br /&gt;
	out	SPH,tmp1	; stack initialised&lt;br /&gt;
	clr	zero		; always zero&lt;br /&gt;
	ldi	tmp1,$FF	; &lt;br /&gt;
	out	PortB,tmp1	; PortB = % 1111 1111&lt;br /&gt;
	out	PortC,zero	; PortC = % 0000 0000&lt;br /&gt;
	out	PortD,tmp1	; PortD = % 1111 1111&lt;br /&gt;
	out	DDRB,tmp1	; PortB direction = % 1111 1111&lt;br /&gt;
	out	DDRC,zero	; PortC direction = % 0000 0000&lt;br /&gt;
	out	DDRD,tmp1	; PortD direction = % 1111 1111&lt;br /&gt;
	ldi	tmp1,$A1	; pos. outputs, fast PWM 8Bit&lt;br /&gt;
	sts	TCCR1A,tmp1	;&lt;br /&gt;
	ldi	tmp1,$09	; fast PWM 8Bit, clk/1 (no prescaling)&lt;br /&gt;
	sts	TCCR1B,tmp1	;&lt;br /&gt;
	sts	OCR1AH,zero	;&lt;br /&gt;
	sts	OCR1AL,zero	;&lt;br /&gt;
	sts	OCR1BH,zero	;&lt;br /&gt;
	sts	OCR1BL,zero	;&lt;br /&gt;
	ldi	tmp1,$40	; Ref=Vcc, right-adj, ADC0=input&lt;br /&gt;
	sts	ADMUX,tmp1	;&lt;br /&gt;
	ldi	tmp1,$EE	; Start,Auto, enable Int, Clk/64&lt;br /&gt;
;	ldi	tmp1,$EF	; Start,Auto, enable Int, Clk/128&lt;br /&gt;
	sts	ADCSRA,tmp1	;&lt;br /&gt;
	ldi	tmp1,$00	; free running&lt;br /&gt;
	sts	ADCSRB,tmp1	;&lt;br /&gt;
	ldi	tmp1,$01	; disable ADC0 dig.inp (optional)&lt;br /&gt;
	sts	DIDR0,tmp1	;&lt;br /&gt;
	ldi	ZL,low(CoTblF&amp;lt;&amp;lt;1)	; move filter coefficents&lt;br /&gt;
	ldi	ZH,high(CoTblF&amp;lt;&amp;lt;1)	; from program-flash&lt;br /&gt;
	ldi	YL,low(CoTblS)	; to SRAM&lt;br /&gt;
	ldi	YH,high(CoTblS)	;&lt;br /&gt;
	ldi	tmp1,16		; count 8 * 2-Byte coefficients&lt;br /&gt;
TbLoop:&lt;br /&gt;
	lpm	tmp2,Z+		; fetch 1 byte from coefficient table&lt;br /&gt;
	st	Y+,tmp2		; copy coefficient to Sram, increment Y&lt;br /&gt;
	dec	tmp1&lt;br /&gt;
	brne	TbLoop&lt;br /&gt;
	ldi	YL,low(DatTbl1)	; load SRAM-Pointer for Interrupt routine&lt;br /&gt;
	ldi	YH,high(DatTbl1)	;&lt;br /&gt;
	sei			; enable interrupts&lt;br /&gt;
&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* Main program:&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
Endless:&lt;br /&gt;
	rjmp	Endless		; &lt;br /&gt;
&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* ADC-Interrupt routine: compute filter and update PWM output&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
ADCint:&lt;br /&gt;
	sbi	PortD,0		; just to measure INT-Time&lt;br /&gt;
	in	savsrg,SREG	; save status register&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
&lt;br /&gt;
; allpass 2&lt;br /&gt;
	load_node 	x10	;&lt;br /&gt;
	add_node 	y22	;         y22   +---+ y12 +---+&lt;br /&gt;
	mult_32		k2	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+&lt;br /&gt;
	subtr_node	x22	;          |    +---+     +---+    |&lt;br /&gt;
	limit_store 	y02	;          v                       |&lt;br /&gt;
	load_node 	x12	;   x10  +---+   +---+    +---+    | &lt;br /&gt;
	update_node 	x22	;    o--&amp;gt;| + |--&amp;gt;|*K2|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	load_node 	x10	;    |   +---+   +---+  + +---+   y02&lt;br /&gt;
	update_node 	x12	;    |                    - A&lt;br /&gt;
	lds	datal,ADCL	;    |    +---+     +---+   |&lt;br /&gt;
	lds	datah,ADCH	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o&lt;br /&gt;
	dec	datah		;    |    +---+ x12 +---+  x22&lt;br /&gt;
	dec	datah		;    |&lt;br /&gt;
	lsl	datal		;    +-----------+&lt;br /&gt;
	rol	datah		;         +---+  |&lt;br /&gt;
	lsl	datal		;  ADC &amp;gt;--|1/z|--+&lt;br /&gt;
	rol	datah		;         +---+ &lt;br /&gt;
	lsl	datal		; &lt;br /&gt;
	rol	datah		; &lt;br /&gt;
	lsl	datal		; convert 10 bit unsigned &lt;br /&gt;
	rol	datah		; to 15 Bit signed&lt;br /&gt;
	lsl	datal		; $03FF -&amp;gt; $01FF -&amp;gt; $3FE0&lt;br /&gt;
	rol	datah		; $0000 -&amp;gt; $FE00 -&amp;gt; $C000&lt;br /&gt;
	lsl	datal		;  &lt;br /&gt;
	rol	datah		; &lt;br /&gt;
	update_node 	x10	; save new sample for 2nd allpass-chain&lt;br /&gt;
	load_node 	y12	; &lt;br /&gt;
	update_node 	y22	; &lt;br /&gt;
	load_node 	y02	;&lt;br /&gt;
	update_node 	y12	;&lt;br /&gt;
&lt;br /&gt;
; allpass 4&lt;br /&gt;
	add_node 	y24	;&lt;br /&gt;
	mult_32		k4	;         y24   +---+ y14 +---+&lt;br /&gt;
	subtr_node	x24	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+&lt;br /&gt;
	limit_store 	y04	;          |    +---+     +---+    |&lt;br /&gt;
	load_node 	x14	;          v                       |&lt;br /&gt;
	update_node 	x24	;   y02  +---+   +---+    +---+    | &lt;br /&gt;
	load_node 	y02	;  -&amp;gt;o--&amp;gt;| + |--&amp;gt;|*K4|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	update_node 	x14	;    |   +---+   +---+  + +---+   y04&lt;br /&gt;
	load_node 	y14	;    |                    - A&lt;br /&gt;
	update_node 	y24	;    |    +---+     +---+   |&lt;br /&gt;
	load_node 	y04	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o&lt;br /&gt;
	update_node 	y14	;         +---+ x14 +---+  x24&lt;br /&gt;
&lt;br /&gt;
; allpass 6&lt;br /&gt;
	add_node 	y26	;&lt;br /&gt;
	mult_32		k6	;         y26   +---+ y16 +---+ &lt;br /&gt;
	subtr_node	x26	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+ &lt;br /&gt;
	limit_store 	y06	;          |    +---+     +---+    | &lt;br /&gt;
	load_node 	x16	;          v                       |&lt;br /&gt;
	update_node 	x26	;   y04  +---+   +---+    +---+    | &lt;br /&gt;
	load_node 	y04	;  -&amp;gt;o--&amp;gt;| + |--&amp;gt;|*K6|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	update_node 	x16	;    |   +---+   +---+  + +---+   y06&lt;br /&gt;
	load_node 	y16	;    |                    - A&lt;br /&gt;
	update_node 	y26	;    |    +---+     +---+   |&lt;br /&gt;
	load_node 	y06	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o&lt;br /&gt;
	update_node 	y16	;         +---+ x16 +---+  x26&lt;br /&gt;
&lt;br /&gt;
; allpass 8&lt;br /&gt;
	add_node 	y28	;&lt;br /&gt;
	mult_32		k8	;         y28   +---+ y18 +---+ &lt;br /&gt;
	subtr_node	x28	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+&lt;br /&gt;
	limit_store 	y08	;          |    +---+     +---+    |&lt;br /&gt;
	load_node 	x18	;          v                       |&lt;br /&gt;
	update_node 	x28	;   y06  +---+   +---+    +---+    | &lt;br /&gt;
	load_node 	y06	;  -&amp;gt;o--&amp;gt;| + |--&amp;gt;|*K8|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	update_node 	x18	;    |   +---+   +---+  + +---+   y08&lt;br /&gt;
	load_node 	y18	;    |                    - A&lt;br /&gt;
	update_node 	y28	;    |    +---+     +---+   |&lt;br /&gt;
	load_node 	y08	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o &lt;br /&gt;
	update_node 	y18	;         +---+ x18 +---+  x28 &lt;br /&gt;
	load_node 	x10	;&lt;br /&gt;
	ldi	YL,Low(DatTbl2)	;&lt;br /&gt;
&lt;br /&gt;
; allpass 1&lt;br /&gt;
	add_node 	y21	;&lt;br /&gt;
	mult_32		k1	;         y21   +---+ y11 +---+&lt;br /&gt;
	subtr_node	x21	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+&lt;br /&gt;
	limit_store 	y01	;          |    +---+     +---+    |&lt;br /&gt;
	load_node 	x11	;          v                       |&lt;br /&gt;
	update_node 	x21	;   x10  +---+   +---+    +---+    | &lt;br /&gt;
	load_node 	x10	;  -&amp;gt;o--&amp;gt;| + |--&amp;gt;|*K1|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	update_node 	x11	;    |   +---+   +---+  + +---+   y01&lt;br /&gt;
	load_node 	y11	;    |                    - A&lt;br /&gt;
	update_node 	y21	;    |    +---+     +---+   |&lt;br /&gt;
	load_node 	y01	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o&lt;br /&gt;
	update_node 	y11	;         +---+ x11 +---+  x21&lt;br /&gt;
&lt;br /&gt;
; allpass 3&lt;br /&gt;
	add_node 	y23	;&lt;br /&gt;
	mult_32		k3	;         y23   +---+ y13 +---+&lt;br /&gt;
	subtr_node	x23	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+&lt;br /&gt;
	limit_store 	y03	;          |    +---+     +---+    |&lt;br /&gt;
	load_node 	x13	;          v                       |&lt;br /&gt;
	update_node 	x23	;   y01  +---+   +---+    +---+    | &lt;br /&gt;
	load_node 	y01	;  -&amp;gt;o--&amp;gt;| + |--&amp;gt;|*K3|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	update_node 	x13	;    |   +---+   +---+  + +---+   y03&lt;br /&gt;
	load_node 	y13	;    |                    - A&lt;br /&gt;
	update_node 	y23	;    |    +---+     +---+   |&lt;br /&gt;
	load_node 	y03	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o&lt;br /&gt;
	update_node 	y13	;         +---+ x13 +---+  x23&lt;br /&gt;
&lt;br /&gt;
; allpass 5&lt;br /&gt;
	add_node 	y25	;&lt;br /&gt;
	mult_32		k5	;         y25   +---+ y15 +---+&lt;br /&gt;
	subtr_node	x25	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+&lt;br /&gt;
	limit_store 	y05	;          |    +---+     +---+    |&lt;br /&gt;
	load_node 	x15	;          v                       |&lt;br /&gt;
	update_node 	x25	;   y03  +---+   +---+    +---+    | &lt;br /&gt;
	load_node 	y03	;  -&amp;gt;o--&amp;gt;| + |--&amp;gt;|*K5|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	update_node 	x15	;    |   +---+   +---+  + +---+   y05&lt;br /&gt;
	load_node 	y15	;    |                    - A&lt;br /&gt;
	update_node 	y25	;    |    +---+     +---+   |&lt;br /&gt;
	load_node 	y05	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o&lt;br /&gt;
	update_node 	y15	;         +---+ x15 +---+  x25&lt;br /&gt;
&lt;br /&gt;
; allpass 7&lt;br /&gt;
	add_node 	y27	;&lt;br /&gt;
	mult_32		k7	;         y27   +---+ y17 +---+&lt;br /&gt;
	subtr_node	x27	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+&lt;br /&gt;
	limit_store 	y07	;          |    +---+     +---+    |&lt;br /&gt;
	load_node 	x17	;          v                       |&lt;br /&gt;
	update_node 	x27	;   y05  +---+   +---+    +---+    | &lt;br /&gt;
	load_node 	y05	;  -&amp;gt;o--&amp;gt;| + |--&amp;gt;|*K7|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	update_node 	x17	;    |   +---+   +---+  + +---+   y07&lt;br /&gt;
	load_node 	y17	;    |                    - A&lt;br /&gt;
	update_node 	y27	;    |    +---+     +---+   | &lt;br /&gt;
	load_node 	y07	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o &lt;br /&gt;
	update_node 	y17	;         +---+ x17 +---+  x27&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* PWM - D/A-output&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
; output y07 to PWM-DAC&lt;br /&gt;
&lt;br /&gt;
;test: output y01&lt;br /&gt;
	ldd	accu3, Y+y01+1	;&lt;br /&gt;
;&lt;br /&gt;
	subi	accu3,$80	; signed to unsigned  $8000 -&amp;gt;$0000, $7FFF -&amp;gt;$FFFF&lt;br /&gt;
	sts	OCR1AH,zero	; &lt;br /&gt;
	sts	OCR1AL,accu3	; fast PWM 8 bit y07 output to OCR1A&lt;br /&gt;
	ldi	YL,Low(DatTbl1)	; back to 1st data table&lt;br /&gt;
; output y08 to PWM-DAC&lt;br /&gt;
;	load_node 	y08	; load y08&lt;br /&gt;
&lt;br /&gt;
; test outpt y02&lt;br /&gt;
	load_node 	y02	; load y02&lt;br /&gt;
;&lt;br /&gt;
	subi	datah,$80	; signed to unsigned  $8000 -&amp;gt;$0000, $7FFF -&amp;gt;$FFFF&lt;br /&gt;
	sts	OCR1BH,zero	; &lt;br /&gt;
	sts	OCR1BL,accu3	; fast PWM 8 bit y08 output to OCR1B&lt;br /&gt;
	cbi	PortD,0		; just to measure INT-Time&lt;br /&gt;
	out	SREG,savsrg	; restore status register&lt;br /&gt;
	reti			; &lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* coefficient table in flash memory&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
CoTblF:&lt;br /&gt;
	.dw 	15709 	 	; k2 *32768 (0,4794008655888)&lt;br /&gt;
	.dw 	28712	 	; k4 *32768 (0,8762184935393)&lt;br /&gt;
	.dw 	32001		; k6 *32768 (0,9765975895082)&lt;br /&gt;
	.dw 	32686	 	; k8 *32768 (0,9974992559356)&lt;br /&gt;
	.dw 	 5301	 	; k1 *32768 (0,1617584983677)&lt;br /&gt;
	.dw 	24020		; k3 *32768 (0,7330289323415)&lt;br /&gt;
	.dw 	30977 		; k5 *32768 (0,9453497003291)&lt;br /&gt;
	.dw 	32460	 	; k7 *32768 (0,9905991566845)&lt;br /&gt;
&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* data in SRAM&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
.dseg&lt;br /&gt;
.org	$0100&lt;br /&gt;
DatTbl1:&lt;br /&gt;
	; &amp;quot;allpass&amp;quot; 0&lt;br /&gt;
	.dw 	$0000 	 	; x10&lt;br /&gt;
	; allpass 2&lt;br /&gt;
	.dw 	$0000 	 	; x12&lt;br /&gt;
	.dw 	$0000 	 	; x22&lt;br /&gt;
	.dw 	$0000 	 	; y02&lt;br /&gt;
	.dw 	$0000 	 	; y12&lt;br /&gt;
	.dw 	$0000 	 	; y22&lt;br /&gt;
	; allpass 4&lt;br /&gt;
	.dw 	$0000 	 	; x14&lt;br /&gt;
	.dw 	$0000 	 	; x24&lt;br /&gt;
	.dw 	$0000 	 	; y04&lt;br /&gt;
	.dw 	$0000 	 	; y14&lt;br /&gt;
	.dw 	$0000 	 	; y24&lt;br /&gt;
	; allpass 6&lt;br /&gt;
	.dw 	$0000 	 	; x16&lt;br /&gt;
	.dw 	$0000 	 	; x26&lt;br /&gt;
	.dw 	$0000 	 	; y06&lt;br /&gt;
	.dw 	$0000 	 	; y16&lt;br /&gt;
	.dw 	$0000 	 	; y26&lt;br /&gt;
	; allpass 8&lt;br /&gt;
	.dw 	$0000 	 	; x18&lt;br /&gt;
	.dw 	$0000 	 	; x28&lt;br /&gt;
	.dw 	$0000 	 	; y08&lt;br /&gt;
	.dw 	$0000 	 	; y18&lt;br /&gt;
	.dw 	$0000 	 	; y28&lt;br /&gt;
CoTblS:&lt;br /&gt;
	.dw 	$0000 	 	; k2&lt;br /&gt;
	.dw 	$0000 	 	; k4&lt;br /&gt;
	.dw 	$0000		; k6&lt;br /&gt;
	.dw 	$0000	 	; k8&lt;br /&gt;
DatTbl2:&lt;br /&gt;
	.dw 	$0000	 	; k1&lt;br /&gt;
	.dw 	$0000		; k3&lt;br /&gt;
	.dw 	$0000 		; k5&lt;br /&gt;
	.dw 	$0000	 	; k7&lt;br /&gt;
	; allpass 1&lt;br /&gt;
	.dw 	$0000 	 	; x11&lt;br /&gt;
	.dw 	$0000 	 	; x21&lt;br /&gt;
	.dw 	$0000 	 	; y01&lt;br /&gt;
	.dw 	$0000 	 	; y11&lt;br /&gt;
	.dw 	$0000 	 	; y21&lt;br /&gt;
	; allpass 3&lt;br /&gt;
	.dw 	$0000 	 	; x13&lt;br /&gt;
	.dw 	$0000 	 	; x23&lt;br /&gt;
	.dw 	$0000 	 	; y03&lt;br /&gt;
	.dw 	$0000 	 	; y13&lt;br /&gt;
	.dw 	$0000 	 	; y23&lt;br /&gt;
	; allpass 5&lt;br /&gt;
	.dw 	$0000 	 	; x15&lt;br /&gt;
	.dw 	$0000 	 	; x25&lt;br /&gt;
	.dw 	$0000 	 	; y05&lt;br /&gt;
	.dw 	$0000 	 	; y15&lt;br /&gt;
	.dw 	$0000 	 	; y25&lt;br /&gt;
	; allpass 7&lt;br /&gt;
	.dw 	$0000 	 	; x17&lt;br /&gt;
	.dw 	$0000 	 	; x27&lt;br /&gt;
	.dw 	$0000 	 	; y07&lt;br /&gt;
	.dw 	$0000 	 	; y17&lt;br /&gt;
	.dw 	$0000 	 	; y27&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Kategorie:AVR-Projekte]]&lt;br /&gt;
[[Category:DSP]]&lt;/div&gt;</summary>
		<author><name>Claus w</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Hilbert-Transformator_(Phasenschieber)_mit_ATmega&amp;diff=102906</id>
		<title>Hilbert-Transformator (Phasenschieber) mit ATmega</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Hilbert-Transformator_(Phasenschieber)_mit_ATmega&amp;diff=102906"/>
		<updated>2021-01-09T22:50:28Z</updated>

		<summary type="html">&lt;p&gt;Claus w: /* Hilbert Transformator nach der FIR-Methode */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Dieser Artikel ist eine Fortsetzung von [[Digitalfilter mit ATmega]] und behandelt ein spezielles Digitalfilter namens Hilbert-Transformator.&lt;br /&gt;
&lt;br /&gt;
Neben den üblichen Filtern, Tiefpass, Hochpass, Bandpass und Bandsperre, gibt es einige weitere Typen. In der Literatur findet man u.a. noch den Allpass, Phasenschieber, Integrator und Differentiator.&lt;br /&gt;
&lt;br /&gt;
===Der Hilbert-Transformator, ein Breitband-90-Grad-Phasenschieber===&lt;br /&gt;
&lt;br /&gt;
In den Lehrbüchern wird er völlig zu Unrecht eher am Rande abgehandelt. Tatsächlich findet man ihn in allen Schaltungen zur Datenübertragung, zu Modulation oder Demodulation mit I/Q-Mischern, im „Software-defined radio“.&lt;br /&gt;
&lt;br /&gt;
Auch ein Hilbert-Transformator kann mithilfe von Scilab berechnet werden. Allerdings gibt es keine fertige Software, man muss sich durch einige Literatur hindurchfressen, z.&amp;amp;nbsp;B. ISBN 0471619957 Sanjit Mitra, Handbook for DSP (1993), Kapitel „Special Filter Designs“ von [https://web.archive.org/web/20100610031102/http://faculty.cua.edu/regalia/ Phillip Regalia].&lt;br /&gt;
[https://web.itu.edu.tr/hulyayalcin/Signal_Processing_Books/DSP_Applications_Mitra.pdf Matlab-Plots dazu hier ab Seitenzahl 41]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
GNU Octave stellt die Hilbert-Transformation und den Parks-McClellan-hilbert-FIR-Filterentwurf im [http://octave.sourceforge.net/signal/function/remez.html octave-forge Paket &amp;quot;signal&amp;quot;] zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
Eine Fundgrube sind die Matlab-Texte von Prof. Schüssler, die vorab 1998 zum  zweiten Band seines Lehrbuchs auf seiner Webseite veröffentlicht wurden. Inzwischen ist der erste Band in der fünften Auflage erschienen [http://www.springer.com/engineering/signals/book/978-3-540-78250-6 ISBN 9783540782506] , der zweite Band ISBN 9783642011184 2010 erstmalig erschienen,  [http://www.lms.lnt.de/forschung/veroeffentlichungen/buecher/dsv.shtml Software-Download hier] aber die Webseite ist nach seinem Tod 2007 abgeschaltet. Zum Glück gibt es das  &lt;br /&gt;
[http://web.archive.org/web/20041206171820/www.nt.e-technik.uni-erlangen.de/~hws/dsv2programs/index.html  Webarchiv], wo die Texte noch zu finden sind.&lt;br /&gt;
&lt;br /&gt;
Zu dieser Zeit waren die Matlab-Programme noch nicht in „Toolboxen“ untergebracht, deren Funktion von außen nicht mehr sichtbar ist. Daher lassen sie sich relativ einfach in Scilab oder Octave übersetzen.&lt;br /&gt;
&lt;br /&gt;
Vier Versionen von Hilbert-Transformatoren werden hier berechnet: &lt;br /&gt;
* FIR-Hilbert, aufwendig, aber streng linearphasig, der bekannteste Typ, da schon lange mit dem Matlab-Befehl remez / firpm und Parameter &#039;hilbert&#039; berechenbar. Mit dem octave-forge Paket &amp;quot;signal&amp;quot; ist remez mit &amp;quot;hilbert&amp;quot; verfügbar. Scilab kennt diesen Parameter nicht.&lt;br /&gt;
* näherungsweise linearphasiger IIR-Hilbert, maximal flach,&lt;br /&gt;
* näherungsweise linearphasiger IIR-Hilbert, Tschebyscheff &lt;br /&gt;
* minimalphasiger IIR-Hilbert, kompakt, aber mit großen Gruppenlaufzeitschwankungen, eher für Audioanwendungen als Digitalsignale.&lt;br /&gt;
&lt;br /&gt;
Im Artikel von Schüßler/Steffen (siehe unten) sind in zwei vergleichenden Beispielen die Gruppenlaufzeitschwankungen des maximal Flachen etwa halb so groß, des Minimalphasigen etwa fünf Mal so groß wie die Tschbyscheff-Version.&lt;br /&gt;
&lt;br /&gt;
Zumindest der kompakte IIR-Hilbert lässt sich auch in einem ATmega unterbringen. Er besteht aus einer Verzögerung und zwei Allpässen, die wieder aus SOS-Teilfiltern aufgebaut sind. Pro Teilfilter gibt es nur einen Koeffizienten, sodass man mindestens acht Teilfilter verwenden kann.&lt;br /&gt;
&lt;br /&gt;
===Ein Hilbert-Kochrezept (noch unvollständig)===&lt;br /&gt;
&lt;br /&gt;
Folgen wir dem Zahlenbeispiel und Berechnungsweg im „Handbook for DSP“.&lt;br /&gt;
&lt;br /&gt;
Zuerst berechnen wir einen elliptischen &#039;&#039;Halbband&#039;&#039;-Tiefpass. Halbband besagt, dass die beiden Grenzfrequenzen symmetrisch zur halben Nyquist- Frequenz also 0,25 * Abtastfrequenz liegen, siehe Bild oben rechts. Die genauen Bedingungen lauten in der Schreibweise des Buches (&#039;&#039;p&#039;&#039;=passband, &#039;&#039;s&#039;&#039;=stopband):&lt;br /&gt;
* Omega&amp;lt;sub&amp;gt;s&amp;lt;/sub&amp;gt; + Omega&amp;lt;sub&amp;gt;p&amp;lt;/sub&amp;gt; = Pi &amp;lt;br&amp;gt; (auf Omega&amp;lt;sub&amp;gt;sample&amp;lt;/sub&amp;gt; normierte Skala: Samplerate=2*Pi)&lt;br /&gt;
* (1-Delta&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;)&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; +Delta&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;=1&lt;br /&gt;
&lt;br /&gt;
Als Zahlenwerte werden Omega&amp;lt;sub&amp;gt;s&amp;lt;/sub&amp;gt; = 0,55*Pi und Delta&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;=0,01 gewählt, und damit ein elliptischer IIR-Tiefpass 7.Ordnung berechnet.&lt;br /&gt;
Damit erhält er folgende Zahlenwerte der Pole:&lt;br /&gt;
&lt;br /&gt;
 0  0,436688  0,743707 0,927758&lt;br /&gt;
&lt;br /&gt;
===Scilab-Berechnung des Halbbandfilters===&lt;br /&gt;
&lt;br /&gt;
Mit Scilab erhalten wir nach einigem Ausprobieren praktisch dieselben Zahlenwerte, siehe Bild. Die Pole müssten für ein ideales Halbbandfilter genau auf der imaginären Achse liegen, der Realteil genau Null sein (Der Fehler kommt daher, dass die Angabe von f&amp;lt;sub&amp;gt;stop&amp;lt;/sub&amp;gt; vom Programm nicht berücksichtigt wird, das Filter wäre überbestimmt).&lt;br /&gt;
Diese Zahlen werden noch quadriert (&#039;&#039;konjugiert komplexe&#039;&#039; Pole zusammengefasst) und bilden schließlich die Koeffizienten des Hilbert-Transformators.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Halbbandfilter.png|Mit Scilab berechnetes Halbbandfilter 7.Ordnung|640px]]&lt;br /&gt;
&lt;br /&gt;
Die Übertragungsfunktion des gesuchten Hilbert-Transformators soll wie bisher H(z) heißen. Zur Unterscheidung nennen wir die bis jetzt berechnete Tiefpassfunktion G(z). &lt;br /&gt;
&lt;br /&gt;
Wieder wird sie in SOS-Teilfilter aufgeteilt. Hier allerdings in die &amp;lt;u&amp;gt;Summe&amp;lt;/u&amp;gt; von zwei &amp;lt;u&amp;gt;parallel&amp;lt;/u&amp;gt; geschalteten &#039;&#039;Allpass&#039;&#039;-Funktionen A&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; und A&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt; plus eine Verzögerung um einen Sampletakt, in der Übertragungsfunktion als „z&amp;lt;sup&amp;gt;-1&amp;lt;/sup&amp;gt;“ ausgedrückt.&lt;br /&gt;
&lt;br /&gt;
Ein Allpass läßt alle Signalfrequenzen mit unveränderter Amplitude durch, verändert nur die Phase. Seine SOS-Teilfunktion ist besonders einfach aufgebaut, zwei Koeffizienten sind Null, zwei sind gleich Eins und die beiden restlichen identisch. Damit benötigt man nur eine Multiplikation pro Teilfilter.&lt;br /&gt;
&lt;br /&gt;
Die Tiefpass-Übertragungsfunktion erhält so die Form:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;G(z) = ½ * ( A&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; (z&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;) + z&amp;lt;sup&amp;gt;-1&amp;lt;/sup&amp;gt; * A&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt; (z&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;))&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
mit&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
A_{1}(z^{2})=\frac{z^{-2}+0,190696}{1+0,190696\ast z^{-2}}\ast&lt;br /&gt;
{\frac{z^{-2}+0,860735}{1+0,860735\ast z^{-2}}}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
A_{2}(z^{2})=\frac{z^{-2}+0,553100}{1+0,553100\ast z^{-2}}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn man die beiden Ausgänge nicht addiert, sondern subtrahiert, entsteht ein Hochpass gleicher Grenzfrequenz. Beides kombiniert ergibt eine digitale &#039;&#039;Frequenzweiche&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Zum Übergang auf den Hilbert-Transformator ersetzen (&#039;&#039;substituieren&#039;&#039;) wir das z durch -jz und multiplizieren das ganze mit 2:&lt;br /&gt;
&lt;br /&gt;
H(z)= 2*G(-jz)&lt;br /&gt;
  &lt;br /&gt;
&#039;&#039;&#039;H(z) = A&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; (-z&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;) + j* z&amp;lt;sup&amp;gt;-1&amp;lt;/sup&amp;gt; * A&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt; (-z&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
mit&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
A_{1}(-z^{2})=\frac{z^{-2}-0,190696}{1-0,190696\ast z^{-2}}\ast&lt;br /&gt;
{\frac{z^{-2}-0,860735}{1-0,860735\ast z^{-2}}}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
A_{2}(-z^{2})=\frac{z^{-2}-0,553100}{1-0,553100\ast z^{-2}}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie man sieht, ändern sich nur die Vorzeichen. Die Pole liegen aber im Pol-Nullstellendiagramm auf der reellen Achse.&lt;br /&gt;
&lt;br /&gt;
Die Ausgänge der beiden Allpässe sind jetzt gegeneinander um 90 Grad phasenverschoben, und können auf einen I/Q-Modulator gegeben werden. Umgekehrt kann man auch die beiden Eingänge auftrennen, und zwei um 90 Grad versetzte Signale aus einem I/Q-Demodulator einspeisen und die Ausgangssignale addieren oder subtrahieren, je nach gewünschtem Seitenband.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Allpaesse.png]]&lt;br /&gt;
&lt;br /&gt;
Und weil das so gut funktionierte, hier noch die Berechnung des Hilbert-Transformators [http://www.mikrocontroller.net/topic/92630#new von Olli Niemitalo] mit einem Halbband-Tiefpass 17.Ordnung, was zu acht SOS-Teilfiltern führt, dazu folgt unten ein ATmega48-Programm.&lt;br /&gt;
Die originalen URL sind verwaist, aber im Webarchiv noch zu finden:&amp;lt;br&amp;gt;&lt;br /&gt;
https://web.archive.org/web/20070719141658/http://yehar.com/ViewHome.pl?page=dsp/hilbert/ &amp;lt;br&amp;gt;&lt;br /&gt;
https://web.archive.org/web/20070814013543/http://yehar.com/ViewHome.pl?page=dsp/hilbert/011729.html &amp;lt;br&amp;gt;&lt;br /&gt;
Olli ist auch heute (2019) noch aktiv:&amp;lt;br&amp;gt;&lt;br /&gt;
http://yehar.com/blog/&amp;lt;br&amp;gt;&lt;br /&gt;
speziell sein IIR-Hilbert:&amp;lt;br&amp;gt;&lt;br /&gt;
http://yehar.com/blog/?p=368&amp;lt;br&amp;gt;&lt;br /&gt;
Diskussion auch dazu:&amp;lt;br&amp;gt;&lt;br /&gt;
https://dsp.stackexchange.com/questions/37411/iir-hilbert-transformer/59157#59157&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Bild:Halbbandfilter2.png|Halbbandfilter 17.Ordnung|640px]]&lt;br /&gt;
&lt;br /&gt;
===Der näherungsweise linearphasige Hilbert-Transformator===&lt;br /&gt;
&lt;br /&gt;
Er wird im Handbook for DSP auf zwei Seiten sehr kurz abgehandelt. Statt aus zwei Allpässen besteht er aus einem einzigen, im anderen Zweig wird das Signal nur zeitverzögert, was mit einem Ringpuffer wenig Rechenzeit kostet. Eine Zeitverzögerung ist sozusagen die einfachste Form eines Allpasses, damit ist diese Bauform ein Spezialfall der oben gezeigten. Aus Schüsslers Texten erfahren wir noch, dass das Halbband-Tiefpassfilter zur Berechnung hier Tschebyscheff-Charakter haben muß.&lt;br /&gt;
&lt;br /&gt;
Das Zahlenbeispiel zitiert Regalia aus einer anderen Veröffentlichung [http://www.cs.tut.fi/~mr/MRJulk92.html (M. Renfors and T. Saramäki, A class of approximately linear phase digital filters composed of allpass subfilters 1986 ) ] Der Allpass hat neun Koeffizienten, die Zeitverzögerung beträgt 17 Sampletakte. Der Halbband-Tiefpass hat eine Sperrdämpfung von &amp;gt; 49 dB. Sein Frequenzgang und der Phasengang des berechneten Hilbert-Transformators sind als Bild gezeigt.&lt;br /&gt;
&lt;br /&gt;
Zum Allpass gibt es noch folgende Zahlenwerte:&lt;br /&gt;
&lt;br /&gt;
Pole location for A(z)&amp;lt;br&amp;gt;&lt;br /&gt;
z= 	-0.8699928078&amp;lt;br&amp;gt;&lt;br /&gt;
	 0.491194141 ± j0.183666529&amp;lt;br&amp;gt;&lt;br /&gt;
	 0.252724179 ± j0.463085544&amp;lt;br&amp;gt;&lt;br /&gt;
	-0.109950894 ± j0.548611467&amp;lt;br&amp;gt;&lt;br /&gt;
	-0.447326028 ± j0.356810323&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das könnte also ebenfalls noch in einen  ATmega passen.&lt;br /&gt;
&lt;br /&gt;
===Hilbert ohne Multiplizierer===&lt;br /&gt;
&lt;br /&gt;
Eine interessante Variante wird im Artikel [http://kondor.etf.bg.ac.yu/~lutovac/pdf/eusi98lm.pdf Design of multiplierless elliptic IIR halfband filters and Hilbert transformers] vorgestellt. Ähnlich wie im Cordic-Algorithmus für trigonometrische Funktionen werden Multiplikationen vermieden, durch geschickte Wahl der Koeffizienten als Zweierpotenzen.&lt;br /&gt;
&lt;br /&gt;
Die beiden Allpässe des Zahlenbeispiels haben folgende Übertragungsfunktionen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
A_1(z^{-2})&lt;br /&gt;
&amp;amp;=\frac{z^{-2}-0{,}12109375}{1-0{,}12109375 \cdot z^{-2}}&lt;br /&gt;
\cdot\frac{z^{-2}-0{,}6640625}{1-0{,}6640625 \cdot z^{-2}} \\&lt;br /&gt;
&amp;amp;=\frac{z^{-2}-(\frac18 - \frac1{256})}{1-(\frac18 - \frac1{256}) \cdot z^{-2}}&lt;br /&gt;
\cdot\frac{z^{-2}-(\frac12 + \frac18 + \frac1{32} + \frac1{128})}{1-(\frac12 + \frac18 + \frac1{32} + \frac1{128})\cdot z^{-2}}\\&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
A_2(z^{-2})\cdot{z^{-1}}&lt;br /&gt;
&amp;amp;=z^{-1}&lt;br /&gt;
\cdot\frac{z^{-2}-0{,}390625}{1-0{,}390625 \cdot z^{-2}}&lt;br /&gt;
\cdot\frac{z^{-2}-0{,}890625}{1-0{,}890625 \cdot z^{-2}}\\&lt;br /&gt;
&amp;amp;=z^{-1}&lt;br /&gt;
\cdot\frac{z^{-2}-(\frac14 + \frac18 + \frac1{64})}{1-(\frac14 + \frac18 + \frac1{64}) \cdot z^{-2}}&lt;br /&gt;
\cdot\frac{z^{-2}-(1 - \frac18 + \frac1{64})}{1-(1 - \frac18 + \frac1{64}) \cdot z^{-2}}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Hilbert Transformator nach der FIR-Methode ==&lt;br /&gt;
&lt;br /&gt;
Nach dem Additionstheorem ergibt sich aus dem multiplikativen Mischen (u_prod = u_1 * u_2) zweier Wechselspannungen eine Überlagerung (u_sum = u_3 + u_4) zweier anderer Wechelspannungen; die Frequenz der einen Wechselspannung ist die Summe der Frequenzen der Faktor-Spannungen - die Frequenz der anderen Wechselspannung ist die Differenz der Frequenzen der Faktorspannungen. Jeweils eine der beiden Frequenzen ist das Nutz-Signal, die andere Frequenz ist die Spiegelfrequenz.&lt;br /&gt;
&lt;br /&gt;
Der Hilbert-Tranformator ist ein Mittel um nur das Nutzsignal und nicht die Spiegelfrequenz zu mischen. Es wird nach den Regeln der Multiplikation komplexer Zahlen gemischt. Eingabesignal und Mischoszillator müssen in der Form der EULERschen Identität vorliegen: &lt;br /&gt;
&lt;br /&gt;
y = A * exp( j * phi )  = A * ( cos( phi ) + j * sin( phi )  ) ; phi = omega * t ; omega = 2 * pi * f ; f ... Frequenz ; A ... Amplitude ; t ... Zeit&lt;br /&gt;
&lt;br /&gt;
Mit der exp() - Darstellung kann man mischen, indem man den Ausdruck phi = 2 * pi * t * (f1 + f2) anwendet. Dabei addieren sich die Frequenzen ohne Spiegelfrequenz. Beide Frequenzen müssen als komplexe Zahlen vorliegen, also jede Frequenz als zwei Wechselspannungen mit (jeweils pro Frequenz) gleicher Amplitude. Liegt nur ein einfaches Sinus-Signal vor, kann man das dazugehörige Cosinus-Signal durch Phasenverschiebung um 90° mit einem Hilbert-Transformator erreichen. Danach wendet man die Multiplikation an:&lt;br /&gt;
&lt;br /&gt;
y[ re, j * im ]:= x1[ re, j * im ]* x2[ re, j * im ] = (x1.re * x2.re - x1.im * x2.im) + j * (x1.re * x2.im + x2.re * x1.im) ; re ... Realteil ; im ... Imag. Teil&lt;br /&gt;
&lt;br /&gt;
Jedes Glied des einen Faktors mit jedem Glied des anderen Faktors unter Beachtung der imaginären Einheit multiplizieren. Wendet man bei dem Signal einer der beiden Frequenzen nur einen der beiden Anteile (entweder nur realen Cosinus-Teil oder imaginären Sinusteil) so entsteht eine &amp;quot;negative&amp;quot; Frequenz (der Zeiger in der komplexen Zahlenebene dreht sich andersherum). Somit wird diese Frequenz von der anderen subtrahiert (phi = 2 * pi * t * (f1 - f2)). Das kann sowohl rechnerisch als auch durch Umpolen einer Bandfilterwicklung errreicht werden. Für Zwischenergebnisse nutzt man beide Signalteile weiter, für z.B. eine Audioausgabe genügt einer.&lt;br /&gt;
&lt;br /&gt;
Kann man zu einem Sinussignal das Cosinus-Signal auch ohne synthetisches Filter erhalten? Genau weiß ich es nicht. Für einen Oszillator braucht man mindestens zwei Energiespeicher. Beide sind (wenn es kein Drehstromoszillator ist) um 90° phasenverschoben. Hier kommt man ohne synthetisches Filter aus. Anders bei Schallwellen. Der eine Speicher besteht hier sowohl aus Schalldruck als auch aus Schallschnelle. Sind beide um 0° phasenverschoben, so bewegt sich die Welle in die eine Richtung, bei 180° entsprechend entgegengesetzt. Der andere Speicher ist die 1. Ableitung von jeweils Schalldruck und Schallschnelle. Die Ableitung ist um 90° phasenverschoben aber bei frequenzabhängiger Amplitude ( y = A * sin( omega * t ) ; y&#039; = omega * A * cos( omega * t ) ). Ohne Spiegelfrequenz kann man das nur für eine feste Frequenz mischen. Bei einem Frequenzband braucht man das synthetische Filter.&lt;br /&gt;
&lt;br /&gt;
Der Hilbert-Transformator erzeugt aus einem Sinus-Signal das um 90° verschobene Cosinus-Signal. Ein Beispiel in Python:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Begin Hilbert FIR filter.&lt;br /&gt;
import math # Math&lt;br /&gt;
import numpy as np # Math&lt;br /&gt;
import matplotlib as mlp # Plot&lt;br /&gt;
import matplotlib.pyplot as plt # Plot&lt;br /&gt;
&lt;br /&gt;
FREQUENCY = 400.0 # 1 / s&lt;br /&gt;
RATE = 48000.0 # samples / s&lt;br /&gt;
SAMPLES = 4000&lt;br /&gt;
CELLS = 501&lt;br /&gt;
STEPS = SAMPLES - CELLS&lt;br /&gt;
PREFIX = (CELLS - 1) / 2&lt;br /&gt;
SUFFIX = CELLS - PREFIX&lt;br /&gt;
POSTFIX = SAMPLES - CELLS&lt;br /&gt;
&lt;br /&gt;
samples = range(SAMPLES)&lt;br /&gt;
cells = range(CELLS)&lt;br /&gt;
steps = range(STEPS)&lt;br /&gt;
prefixes = range(PREFIX)&lt;br /&gt;
suffixes = range(SUFFIX)&lt;br /&gt;
postfixes = range(POSTFIX)&lt;br /&gt;
&lt;br /&gt;
input = []&lt;br /&gt;
re = []&lt;br /&gt;
im = []&lt;br /&gt;
coefficients = []&lt;br /&gt;
&lt;br /&gt;
def plot():&lt;br /&gt;
&lt;br /&gt;
	for sample in samples:&lt;br /&gt;
		if(SAMPLES / 2 &amp;gt; sample):&lt;br /&gt;
			_phi = FREQUENCY * sample / RATE * 2.0 * math.pi&lt;br /&gt;
		else:&lt;br /&gt;
			_phi = 5 * FREQUENCY * sample / RATE * 2.0 * math.pi&lt;br /&gt;
		input.append(math.sin(_phi))&lt;br /&gt;
&lt;br /&gt;
	for cell in cells:&lt;br /&gt;
		arg = cell - (CELLS - 1) / 2.0&lt;br /&gt;
		if(0.0 == arg):&lt;br /&gt;
			coefficients.append(0.0)&lt;br /&gt;
		else:&lt;br /&gt;
			arg *= math.pi&lt;br /&gt;
			coefficients.append((1.0 - math.cos(arg)) / arg)&lt;br /&gt;
	&lt;br /&gt;
	for postfix in postfixes:&lt;br /&gt;
		coefficients.append(0.0)&lt;br /&gt;
	&lt;br /&gt;
	for prefix in prefixes:&lt;br /&gt;
		re.append(0.0)&lt;br /&gt;
		im.append(0.0)&lt;br /&gt;
		&lt;br /&gt;
	for step in steps:&lt;br /&gt;
		re.append(input[step + PREFIX])&lt;br /&gt;
		sum = 0.0&lt;br /&gt;
		for cell in cells:&lt;br /&gt;
			sum += input[step + cell] * coefficients[cell];&lt;br /&gt;
		im.append(sum)&lt;br /&gt;
		&lt;br /&gt;
	for suffix in suffixes:&lt;br /&gt;
		re.append(0.0)&lt;br /&gt;
		im.append(0.0)&lt;br /&gt;
	&lt;br /&gt;
	# Prepare the plot.&lt;br /&gt;
	plt.ylabel(&#039;amplitude&#039;)&lt;br /&gt;
	plt.xlabel(&#039;timesteps&#039;)&lt;br /&gt;
	plt.axis([0, SAMPLES - 1, -1.5, 1.5])&lt;br /&gt;
	plt.grid(True)&lt;br /&gt;
	plt.plot(samples, re, &#039;r-&#039;)&lt;br /&gt;
	plt.plot(samples, im, &#039;b-&#039;)&lt;br /&gt;
	plt.show()&lt;br /&gt;
# End.&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
Neben ein Array aus abgetasteten Werten eines akustischen Signales (hier Sinus-Signal, künstlich berechnet) wird das Array des Transformationskerns gelegt. Das Array des Transformationskerns ist dabei viel kürzer und es wird nur der gemeinsame Bereich berechnet. Der Wert des Cosinus-Signals, das zu dem Sinus-Signal gehört, das sich auf der Position der Mitte des Transformationskerns befindet, ergibt sich aus der Summe der Werte aus dem Sinus-Signal multiplizert mit den Faktoren aus dem Transformationskern mit gleichem Index. Das folgende Cosinus-Signal wird berechnet indem man zuvor den Transformationskern um einen Index gegenüber dem Eingabe-Sinus-Signal weiterschiebt (usw. bis zum Ende des Signales). Am Anfang und am Ende des berechneten Cosinus-Signales entsteht ein Stück Verlust der jeweils halb so lang wie der Transformationskern ist. Bei sehr lang dauernden Signalen (fast immer) ist statt dessen mit einem Ringpuffer zu arbeiten.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
t ... Zeit&lt;br /&gt;
b[Länge k] ... Transformationskern&lt;br /&gt;
i[undendlich lang] ... Sinus - Signal oder Summe aus Sinus-Signalen&lt;br /&gt;
o[undendlich lang] ... um 90° verschobenes Cosinus - Signal&lt;br /&gt;
=&amp;gt;&lt;br /&gt;
o[t] := Summe { i[n+t] * b[n+t] } ; -k/2 &amp;lt;= n &amp;lt;= +k/2 ; i &amp;gt;= k/2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Der Transformationskern kann wie folgt ermittelt werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x ... natürliche Zahl &amp;gt; 0&lt;br /&gt;
k ... 4 * x + 1&lt;br /&gt;
b[] ... Transformationskern der Länge k&lt;br /&gt;
n ... Index innerhalb des Tranformationskerns&lt;br /&gt;
pi ... 3.14159...&lt;br /&gt;
b[n] := ( 1 - cos( n * pi ) ) / ( n * pi ) ; Ausnahme ist b[0] := 0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Datei:FIR_Kernel_Small.png|200px|thumb|right|Hilbert Transformationskern klein]]&lt;br /&gt;
&lt;br /&gt;
Dabei ist das Argument der cos() - Funktion immer ganzzahlig. &amp;quot;1 - cos(...)&amp;quot; ist für ungerade &amp;quot;n&amp;quot; immer NULL. Der Kern hat nahe n == 0 maximale Werte und nimmt zum Rand hin ab. Ein Kern mit zuwenig Länge (k ist zu klein) wirkt als Hochpass und verkleinert die Amplitude von Signalen kleiner Frequenz (ist unbrauchbar). Kommen hohe und tiefe Frequenzen im Signal gleichzeitig vor, dann braucht man sowohl eine hohe Abtastrate als auch einen langen Kern ( k wird groß, z.B. Größenordnung 801 bei einem Audiosignal). Ändert sich das Nutzsignal unerwartet sprungartig so erhält man im Cosinus-Signal eine Art Sprungantwort.&lt;br /&gt;
&lt;br /&gt;
* Großer Transformationskern : [[Medium:FIR_Kernel_Big.png]]&lt;br /&gt;
* Transformation zweier Signale verschiedener Frequenz : [[Medium:Hilber_FIR_OK.png]]&lt;br /&gt;
* Transformation eines Sprunges im Signal : [[Medium:Hilbert_FIR_OK_Lense.png]]&lt;br /&gt;
* Transformationsfehler bei zu kleinem Kern (k ist zu klein) :  [[Medium:Hilbert_FIR_Too_Small_Kernel.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Zusammenfassung&amp;lt;/b&amp;gt;&lt;br /&gt;
Hilbert-Transformation ermittelt zu einem Sinus-Signal das um 90° verschobene Cosinus-Signal. Das gilt auch für eine Summe von Sinussignalen unterschiedlicher Frequenzen und Amplituden. Die Amplitude des Cosinus-Signales ist gleich der Amplitude des Sinus-Signales (kann geringfügig abweichen aber korrigiert werden). Das Transformieren erfolgt meist synthetisch, z.B. in digitalen Signal Prozessoren. Die Hilbert-Transformation wird verwendet, wenn man Sinus-Signal und Cosinus-Signal benötigt aber nur das Sinus-Signal vorliegt. Beide Signale (sin(...) und cos(...)) zusammen entsprechen einer Folge komplexer Zahlen. Damit kann man multiplikativ mischen ohne Spiegelfrequenz. Liegen beide Faktoren der Mischung als komplexe Zahlen vor, kann man jedes Glied der einen Zahl mit jedem Glied der anderen Zahl multiplizieren unter Beachtung der komplexen Einheit &amp;quot;j&amp;quot;. Falls man sich dabei beide Faktoren jedoch in der exp( j * omega * t ) Schreibweise denkt, so multipliziert man statt dessen Potenzen, indem man die Exponenten addiert. Für eine Berechnung braucht man 4 Multiplikationen, was entweder digital erfolgen kann oder im analogen Fall vier Mischer (z.B. Ringmischer oder Gilbertzellen) benötigt, wenn man das ganze Ergebnis braucht. Der Transformationskern ist ein Array aus Zahlen deren Werte in der Mitte des Arrays groß sind und zum Rand hin abnehmen.&lt;br /&gt;
&lt;br /&gt;
==Weitere Literatur zu Hilbert==&lt;br /&gt;
* Schüssler / [http://www.lnt.de/LMS/staff/index.php?lang=de&amp;amp;function=1&amp;amp;person=5 Steffen] &amp;quot;Halfband Filters and Hilbert Transformers&amp;quot; &amp;lt;br&amp;gt; Irgendwo im Web hatte ich den vollständigen Artikel als PDF gefunden, leider die Adresse nicht notiert, Google findet nur [http://www.springerlink.com/content/p5480n6p8t73t633/ kostenpflichtige Downloads].&lt;br /&gt;
* Dutta / Kumar [http://eprint.iitd.ac.in/dspace/bitstream/2074/1608/1/roydig1989.pdf On Digital Differentiators, Hilbert Transformers, and Half-Band Low-Pass Filters] &amp;lt;br&amp;gt; dank Schrifterkennungsprogramm leicht lädiert&lt;br /&gt;
* Miroslav Lutovac / Ljiljana Milic [http://www.telfor.rs/telfor2000/radovi/7-10.pdf Half-band IIR Filter Design Using Matlab],  [http://kondor.etf.bg.ac.yu/~lutovac/confer.htm weitere Artikel der Autoren]&lt;br /&gt;
* Göckler / Damjanovic [http://www.dsv.rub.de/imperia/md/content/public/wsr06_goecklerdamjanovic.pdf A Family of Efficient Complex Halfband Filters]&lt;br /&gt;
&lt;br /&gt;
==ATmega-Programm Hilbert-Transformer ( fast fertig, schwingt leider)==&lt;br /&gt;
Da der Adressenbereich des ATmega nicht groß genug ist, wird die Tabelle im SRAM in zwei Hälften geteilt.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;* Hilbert transformer with ATmega48P, 90 degree broadband phase shifter   *&lt;br /&gt;
;* 15 MHz xtal, input ADC0, PWM-output OCR1a/b, test output PD0            *&lt;br /&gt;
;* Christoph Kessler 2008                         db1uq_at_t-online_dot_de *&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
.nolist&lt;br /&gt;
.include &amp;quot;m48pdef.inc&amp;quot;&lt;br /&gt;
.list&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;* register 0-15 (no &amp;quot;immediate&amp;quot;-operations possible):&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
.def	mult_l	= r0	; multiplier result&lt;br /&gt;
.def	mult_h	= r1	; multiplier result&lt;br /&gt;
.def	zero	= r2	; zero register (used to add carry flag)&lt;br /&gt;
.def	savsrg	= r3	; save status register during interrupt routine&lt;br /&gt;
.def	reg04	= r4	; free&lt;br /&gt;
.def	reg05	= r5	; free&lt;br /&gt;
.def	reg06	= r6	; free&lt;br /&gt;
.def	reg07	= r7	; free&lt;br /&gt;
.def	reg08	= r8	; free&lt;br /&gt;
.def	reg09	= r9	; free&lt;br /&gt;
.def	reg10	= r10	; free&lt;br /&gt;
.def	reg11	= r11	; free&lt;br /&gt;
.def	reg12	= r12	; free&lt;br /&gt;
.def	accu0	= r13	; Accumulator - 32bit for Interrupt routine&lt;br /&gt;
.def	accu1	= r14	; Accumulator - 32bit for Interrupt routine&lt;br /&gt;
.def	accu2	= r15	; Accumulator - 32bit for Interrupt routine&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;* register 16-23 (&amp;quot;immediate&amp;quot;-operations possible):&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
.def	accu3	= r16	; Accumulator - 32bit for Interrupt routine&lt;br /&gt;
.def	reg17	= r17	; free&lt;br /&gt;
.def	reg18	= r18	; free&lt;br /&gt;
.def	reg19	= r19	; free&lt;br /&gt;
.def	datal	= r20	; Data samples mul register&lt;br /&gt;
.def	datah	= r21	;  for Interrupt routine&lt;br /&gt;
.def	coefl	= r22	; Filter coefficient mul register&lt;br /&gt;
.def	coefh	= r23	;  for Interrupt routine&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;* register 24-31    (16Bit-registers) &lt;br /&gt;
;***************************************************************************&lt;br /&gt;
.def	tmp1	= r24	; general temporary register&lt;br /&gt;
.def	tmp2	= r25	; general temporary register&lt;br /&gt;
;	XL	= r26	; free&lt;br /&gt;
;	XH	= r27	; free&lt;br /&gt;
;	YL	= r28	; used by Interrupt routine&lt;br /&gt;
;	YH	= r29	; used by Interrupt routine&lt;br /&gt;
;	ZL	= r30	; init routine only, free for main program&lt;br /&gt;
;	ZH	= r31	; init routine only, free for main program&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* constants :&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;1st table:&lt;br /&gt;
	;&amp;quot;allpass&amp;quot;0:&lt;br /&gt;
.equ	 x10	= 0&lt;br /&gt;
	; allpass 2:&lt;br /&gt;
.equ	 x12	= 2&lt;br /&gt;
.equ	 x22	= 4&lt;br /&gt;
.equ	 y02	= 6&lt;br /&gt;
.equ	 y12	= 8&lt;br /&gt;
.equ	 y22	= 10&lt;br /&gt;
	; allpass 4:&lt;br /&gt;
.equ	 x14	= 12&lt;br /&gt;
.equ	 x24	= 14&lt;br /&gt;
.equ	 y04	= 16&lt;br /&gt;
.equ	 y14	= 18&lt;br /&gt;
.equ	 y24	= 20&lt;br /&gt;
	; allpass 6:&lt;br /&gt;
.equ	 x16	= 22&lt;br /&gt;
.equ	 x26	= 24&lt;br /&gt;
.equ	 y06	= 26&lt;br /&gt;
.equ	 y16	= 28&lt;br /&gt;
.equ	 y26	= 30&lt;br /&gt;
	; allpass 8:&lt;br /&gt;
.equ	 x18	= 32&lt;br /&gt;
.equ	 x28	= 34&lt;br /&gt;
.equ	 y08	= 36&lt;br /&gt;
.equ	 y18	= 38&lt;br /&gt;
.equ	 y28	= 40&lt;br /&gt;
&lt;br /&gt;
.equ	 k2	= 42&lt;br /&gt;
.equ	 k4	= 44&lt;br /&gt;
.equ	 k6	= 46&lt;br /&gt;
.equ	 k8	= 48&lt;br /&gt;
;2nd table:&lt;br /&gt;
.equ	 k1	= 0&lt;br /&gt;
.equ	 k3	= 2&lt;br /&gt;
.equ	 k5	= 4&lt;br /&gt;
.equ	 k7	= 6&lt;br /&gt;
	; allpass 1:&lt;br /&gt;
.equ	 x11	= 8&lt;br /&gt;
.equ	 x21	= 10&lt;br /&gt;
.equ	 y01	= 12&lt;br /&gt;
.equ	 y11	= 14&lt;br /&gt;
.equ	 y21	= 16&lt;br /&gt;
	; allpass 3:&lt;br /&gt;
.equ	 x13	= 18&lt;br /&gt;
.equ	 x23	= 20&lt;br /&gt;
.equ	 y03	= 22&lt;br /&gt;
.equ	 y13	= 24&lt;br /&gt;
.equ	 y23	= 26&lt;br /&gt;
	; allpass 5:&lt;br /&gt;
.equ	 x15	= 28&lt;br /&gt;
.equ	 x25	= 30&lt;br /&gt;
.equ	 y05	= 32&lt;br /&gt;
.equ	 y15	= 34&lt;br /&gt;
.equ	 y25	= 36&lt;br /&gt;
	; allpass 7:&lt;br /&gt;
.equ	 x17	= 38&lt;br /&gt;
.equ	 x27	= 40&lt;br /&gt;
.equ	 y07	= 42&lt;br /&gt;
.equ	 y17	= 44&lt;br /&gt;
.equ	 y27	= 46&lt;br /&gt;
;*****************************************************&lt;br /&gt;
;* Macros&lt;br /&gt;
;*****************************************************&lt;br /&gt;
.MACRO load_node&lt;br /&gt;
	ldd	datal,Y+@0	; Load low byte of node &lt;br /&gt;
	ldd	datah,Y+@0+1	; Load high byte of node&lt;br /&gt;
.ENDMACRO&lt;br /&gt;
.MACRO update_node&lt;br /&gt;
	std	Y+@0,datal	; Store low byte of node &lt;br /&gt;
	std	Y+@0+1,datah	; Store high byte of node&lt;br /&gt;
.ENDMACRO&lt;br /&gt;
.MACRO add_node&lt;br /&gt;
	ldd	coefl,Y+@0	; Load 2nd node low&lt;br /&gt;
	ldd	coefh,Y+@0+1	; Load 2nd node high&lt;br /&gt;
	add	datal,coefl	; Add low bytes&lt;br /&gt;
	adc	datah,coefh	; Add with carry high bytes&lt;br /&gt;
.ENDMACRO&lt;br /&gt;
.MACRO mult_32&lt;br /&gt;
	ldd	coefl,Y+@0	; Load low byte of coefficient&lt;br /&gt;
	ldd	coefh,Y+@0+1	; Load high byte of coefficient&lt;br /&gt;
	muls	coefh,datah	; Signed multiply, coefficient high byte and data high byte&lt;br /&gt;
	mov     accu2,mult_l	; Copy result word into accumulator byte 2:3&lt;br /&gt;
	mov     accu3,mult_h	; Copy result word into accumulator byte 2:3&lt;br /&gt;
	mul	coefl,datal	; Unsigned multiply, coefficient low byte and data low byte&lt;br /&gt;
	mov	accu0,mult_l	; Copy result word into accumulator byte 2:3&lt;br /&gt;
	mov	accu1,mult_h	; Copy result word into accumulator byte 2:3&lt;br /&gt;
	mulsu	coefh,datal	; Signed-unsigned multiply, coefficient high byte and data low byte&lt;br /&gt;
	sbc	accu3,zero	; Sign extention&lt;br /&gt;
	add	accu1,mult_l	; Add low byte of result to accumulator byte 1&lt;br /&gt;
	adc	accu2,mult_h	; Add with carry high byte of result to accumulator byte 2&lt;br /&gt;
	adc	accu3,zero	; Add carry to accumulator byte 3&lt;br /&gt;
	mulsu	datah,coefl	; Signed-unsigned multiply, data high byte and coefficient low byte&lt;br /&gt;
	sbc	accu3,zero	; Sign extention&lt;br /&gt;
	add	accu1,mult_l	; Add low byte of result to accumulator byte 1&lt;br /&gt;
	adc	accu2,mult_h	; Add with carry high byte of result to accumulator byte 2&lt;br /&gt;
	adc	accu3,zero	; Add carry to accumulator byte 3&lt;br /&gt;
.ENDMACRO&lt;br /&gt;
.MACRO subtr_node&lt;br /&gt;
	ldd	datal,Y+@0	; Load 2nd node low&lt;br /&gt;
	ldd	datah,Y+@0+1	; Load 2nd node high&lt;br /&gt;
	sub	accu0,datal	; Subtract low byte&lt;br /&gt;
	sbc	accu1,datah	; Subtract with carry high byte&lt;br /&gt;
	sbc	accu2,zero	;&lt;br /&gt;
	sbc	accu3,zero	;&lt;br /&gt;
.ENDMACRO&lt;br /&gt;
.MACRO limit_store&lt;br /&gt;
	cpi	accu3,$40	; accu &amp;lt;   $40000000 ?&lt;br /&gt;
	brlo	NoLimit1	;&lt;br /&gt;
	cpi	accu3,-$40	; accu &amp;gt;= -$40000000 ?&lt;br /&gt;
	brsh	NoLimit1	;&lt;br /&gt;
	clr	accu2		; accu2 = $00&lt;br /&gt;
	cpi	accu3,0		;&lt;br /&gt;
	brge	PosLim1		; &lt;br /&gt;
	ldi	accu3,$80	; accu3 = $80&lt;br /&gt;
	rjmp	Limit1		; &lt;br /&gt;
PosLim1:&lt;br /&gt;
	ldi	accu3,$7F	; accu3 = $7F	&lt;br /&gt;
	com	accu2		; accu2 = $FF	&lt;br /&gt;
	rjmp	Limit1		; &lt;br /&gt;
NoLimit1:&lt;br /&gt;
	lsl	accu1		; Scaling to gain factor 2^16&lt;br /&gt;
	rol	accu2		; &lt;br /&gt;
	rol	accu3		; &lt;br /&gt;
Limit1:&lt;br /&gt;
	std	Y+@0,accu2	; &lt;br /&gt;
	std	Y+@0+1,accu3	; &lt;br /&gt;
.ENDMACRO&lt;br /&gt;
.LISTMAC&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* reset/interrupt-vectors:&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
.cseg&lt;br /&gt;
	rjmp	Initial		; after RESET to main program&lt;br /&gt;
	reti			; External Interrupt Request 0&lt;br /&gt;
	reti			; External Interrupt Request 1&lt;br /&gt;
	reti			; Pin Change Interrupt Request 0&lt;br /&gt;
	reti			; Pin Change Interrupt Request 1&lt;br /&gt;
	reti			; Pin Change Interrupt Request 2&lt;br /&gt;
	reti			; Watchdog Time-out Interrupt&lt;br /&gt;
	reti			; Timer/Counter2 Compare Match A&lt;br /&gt;
	reti			; Timer/Counter2 Compare Match B&lt;br /&gt;
	reti			; Timer/Counter2 Overflow&lt;br /&gt;
	reti			; Timer/Counter1 Capture Event&lt;br /&gt;
	reti			; Timer/Counter1 Compare Match A&lt;br /&gt;
	reti			; Timer/Counter1 Compare Match B&lt;br /&gt;
	reti			; Timer/Counter1 Overflow&lt;br /&gt;
	reti			; Timer/Counter0 Compare Match A&lt;br /&gt;
	reti			; Timer/Counter0 Compare Match B&lt;br /&gt;
	reti			; Timer/Counter0 Overflow&lt;br /&gt;
	reti			; SPI Serial Transfer Complete&lt;br /&gt;
	reti			; USART0, Rx Complete&lt;br /&gt;
	reti			; USART0 Data register Empty&lt;br /&gt;
	reti			; USART0, Tx Complete&lt;br /&gt;
	rjmp	ADCint		; ADC Conversion Complete&lt;br /&gt;
	reti			; EEPROM Ready   &lt;br /&gt;
	reti			; 2-wire Serial Interface&lt;br /&gt;
	reti			; Store Program Memory Read&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* after reset: initialise stack,ports&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
Initial: &lt;br /&gt;
	ldi	tmp1,Low(RAMEND)&lt;br /&gt;
	out	SPL,tmp1	;&lt;br /&gt;
	ldi	tmp1,High(RAMEND)&lt;br /&gt;
	out	SPH,tmp1	; stack initialised&lt;br /&gt;
	clr	zero		; always zero&lt;br /&gt;
	ldi	tmp1,$FF	; &lt;br /&gt;
	out	PortB,tmp1	; PortB = % 1111 1111&lt;br /&gt;
	out	PortC,zero	; PortC = % 0000 0000&lt;br /&gt;
	out	PortD,tmp1	; PortD = % 1111 1111&lt;br /&gt;
	out	DDRB,tmp1	; PortB direction = % 1111 1111&lt;br /&gt;
	out	DDRC,zero	; PortC direction = % 0000 0000&lt;br /&gt;
	out	DDRD,tmp1	; PortD direction = % 1111 1111&lt;br /&gt;
	ldi	tmp1,$A1	; pos. outputs, fast PWM 8Bit&lt;br /&gt;
	sts	TCCR1A,tmp1	;&lt;br /&gt;
	ldi	tmp1,$09	; fast PWM 8Bit, clk/1 (no prescaling)&lt;br /&gt;
	sts	TCCR1B,tmp1	;&lt;br /&gt;
	sts	OCR1AH,zero	;&lt;br /&gt;
	sts	OCR1AL,zero	;&lt;br /&gt;
	sts	OCR1BH,zero	;&lt;br /&gt;
	sts	OCR1BL,zero	;&lt;br /&gt;
	ldi	tmp1,$40	; Ref=Vcc, right-adj, ADC0=input&lt;br /&gt;
	sts	ADMUX,tmp1	;&lt;br /&gt;
	ldi	tmp1,$EE	; Start,Auto, enable Int, Clk/64&lt;br /&gt;
;	ldi	tmp1,$EF	; Start,Auto, enable Int, Clk/128&lt;br /&gt;
	sts	ADCSRA,tmp1	;&lt;br /&gt;
	ldi	tmp1,$00	; free running&lt;br /&gt;
	sts	ADCSRB,tmp1	;&lt;br /&gt;
	ldi	tmp1,$01	; disable ADC0 dig.inp (optional)&lt;br /&gt;
	sts	DIDR0,tmp1	;&lt;br /&gt;
	ldi	ZL,low(CoTblF&amp;lt;&amp;lt;1)	; move filter coefficents&lt;br /&gt;
	ldi	ZH,high(CoTblF&amp;lt;&amp;lt;1)	; from program-flash&lt;br /&gt;
	ldi	YL,low(CoTblS)	; to SRAM&lt;br /&gt;
	ldi	YH,high(CoTblS)	;&lt;br /&gt;
	ldi	tmp1,16		; count 8 * 2-Byte coefficients&lt;br /&gt;
TbLoop:&lt;br /&gt;
	lpm	tmp2,Z+		; fetch 1 byte from coefficient table&lt;br /&gt;
	st	Y+,tmp2		; copy coefficient to Sram, increment Y&lt;br /&gt;
	dec	tmp1&lt;br /&gt;
	brne	TbLoop&lt;br /&gt;
	ldi	YL,low(DatTbl1)	; load SRAM-Pointer for Interrupt routine&lt;br /&gt;
	ldi	YH,high(DatTbl1)	;&lt;br /&gt;
	sei			; enable interrupts&lt;br /&gt;
&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* Main program:&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
Endless:&lt;br /&gt;
	rjmp	Endless		; &lt;br /&gt;
&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* ADC-Interrupt routine: compute filter and update PWM output&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
ADCint:&lt;br /&gt;
	sbi	PortD,0		; just to measure INT-Time&lt;br /&gt;
	in	savsrg,SREG	; save status register&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
&lt;br /&gt;
; allpass 2&lt;br /&gt;
	load_node 	x10	;&lt;br /&gt;
	add_node 	y22	;         y22   +---+ y12 +---+&lt;br /&gt;
	mult_32		k2	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+&lt;br /&gt;
	subtr_node	x22	;          |    +---+     +---+    |&lt;br /&gt;
	limit_store 	y02	;          v                       |&lt;br /&gt;
	load_node 	x12	;   x10  +---+   +---+    +---+    | &lt;br /&gt;
	update_node 	x22	;    o--&amp;gt;| + |--&amp;gt;|*K2|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	load_node 	x10	;    |   +---+   +---+  + +---+   y02&lt;br /&gt;
	update_node 	x12	;    |                    - A&lt;br /&gt;
	lds	datal,ADCL	;    |    +---+     +---+   |&lt;br /&gt;
	lds	datah,ADCH	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o&lt;br /&gt;
	dec	datah		;    |    +---+ x12 +---+  x22&lt;br /&gt;
	dec	datah		;    |&lt;br /&gt;
	lsl	datal		;    +-----------+&lt;br /&gt;
	rol	datah		;         +---+  |&lt;br /&gt;
	lsl	datal		;  ADC &amp;gt;--|1/z|--+&lt;br /&gt;
	rol	datah		;         +---+ &lt;br /&gt;
	lsl	datal		; &lt;br /&gt;
	rol	datah		; &lt;br /&gt;
	lsl	datal		; convert 10 bit unsigned &lt;br /&gt;
	rol	datah		; to 15 Bit signed&lt;br /&gt;
	lsl	datal		; $03FF -&amp;gt; $01FF -&amp;gt; $3FE0&lt;br /&gt;
	rol	datah		; $0000 -&amp;gt; $FE00 -&amp;gt; $C000&lt;br /&gt;
	lsl	datal		;  &lt;br /&gt;
	rol	datah		; &lt;br /&gt;
	update_node 	x10	; save new sample for 2nd allpass-chain&lt;br /&gt;
	load_node 	y12	; &lt;br /&gt;
	update_node 	y22	; &lt;br /&gt;
	load_node 	y02	;&lt;br /&gt;
	update_node 	y12	;&lt;br /&gt;
&lt;br /&gt;
; allpass 4&lt;br /&gt;
	add_node 	y24	;&lt;br /&gt;
	mult_32		k4	;         y24   +---+ y14 +---+&lt;br /&gt;
	subtr_node	x24	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+&lt;br /&gt;
	limit_store 	y04	;          |    +---+     +---+    |&lt;br /&gt;
	load_node 	x14	;          v                       |&lt;br /&gt;
	update_node 	x24	;   y02  +---+   +---+    +---+    | &lt;br /&gt;
	load_node 	y02	;  -&amp;gt;o--&amp;gt;| + |--&amp;gt;|*K4|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	update_node 	x14	;    |   +---+   +---+  + +---+   y04&lt;br /&gt;
	load_node 	y14	;    |                    - A&lt;br /&gt;
	update_node 	y24	;    |    +---+     +---+   |&lt;br /&gt;
	load_node 	y04	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o&lt;br /&gt;
	update_node 	y14	;         +---+ x14 +---+  x24&lt;br /&gt;
&lt;br /&gt;
; allpass 6&lt;br /&gt;
	add_node 	y26	;&lt;br /&gt;
	mult_32		k6	;         y26   +---+ y16 +---+ &lt;br /&gt;
	subtr_node	x26	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+ &lt;br /&gt;
	limit_store 	y06	;          |    +---+     +---+    | &lt;br /&gt;
	load_node 	x16	;          v                       |&lt;br /&gt;
	update_node 	x26	;   y04  +---+   +---+    +---+    | &lt;br /&gt;
	load_node 	y04	;  -&amp;gt;o--&amp;gt;| + |--&amp;gt;|*K6|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	update_node 	x16	;    |   +---+   +---+  + +---+   y06&lt;br /&gt;
	load_node 	y16	;    |                    - A&lt;br /&gt;
	update_node 	y26	;    |    +---+     +---+   |&lt;br /&gt;
	load_node 	y06	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o&lt;br /&gt;
	update_node 	y16	;         +---+ x16 +---+  x26&lt;br /&gt;
&lt;br /&gt;
; allpass 8&lt;br /&gt;
	add_node 	y28	;&lt;br /&gt;
	mult_32		k8	;         y28   +---+ y18 +---+ &lt;br /&gt;
	subtr_node	x28	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+&lt;br /&gt;
	limit_store 	y08	;          |    +---+     +---+    |&lt;br /&gt;
	load_node 	x18	;          v                       |&lt;br /&gt;
	update_node 	x28	;   y06  +---+   +---+    +---+    | &lt;br /&gt;
	load_node 	y06	;  -&amp;gt;o--&amp;gt;| + |--&amp;gt;|*K8|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	update_node 	x18	;    |   +---+   +---+  + +---+   y08&lt;br /&gt;
	load_node 	y18	;    |                    - A&lt;br /&gt;
	update_node 	y28	;    |    +---+     +---+   |&lt;br /&gt;
	load_node 	y08	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o &lt;br /&gt;
	update_node 	y18	;         +---+ x18 +---+  x28 &lt;br /&gt;
	load_node 	x10	;&lt;br /&gt;
	ldi	YL,Low(DatTbl2)	;&lt;br /&gt;
&lt;br /&gt;
; allpass 1&lt;br /&gt;
	add_node 	y21	;&lt;br /&gt;
	mult_32		k1	;         y21   +---+ y11 +---+&lt;br /&gt;
	subtr_node	x21	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+&lt;br /&gt;
	limit_store 	y01	;          |    +---+     +---+    |&lt;br /&gt;
	load_node 	x11	;          v                       |&lt;br /&gt;
	update_node 	x21	;   x10  +---+   +---+    +---+    | &lt;br /&gt;
	load_node 	x10	;  -&amp;gt;o--&amp;gt;| + |--&amp;gt;|*K1|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	update_node 	x11	;    |   +---+   +---+  + +---+   y01&lt;br /&gt;
	load_node 	y11	;    |                    - A&lt;br /&gt;
	update_node 	y21	;    |    +---+     +---+   |&lt;br /&gt;
	load_node 	y01	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o&lt;br /&gt;
	update_node 	y11	;         +---+ x11 +---+  x21&lt;br /&gt;
&lt;br /&gt;
; allpass 3&lt;br /&gt;
	add_node 	y23	;&lt;br /&gt;
	mult_32		k3	;         y23   +---+ y13 +---+&lt;br /&gt;
	subtr_node	x23	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+&lt;br /&gt;
	limit_store 	y03	;          |    +---+     +---+    |&lt;br /&gt;
	load_node 	x13	;          v                       |&lt;br /&gt;
	update_node 	x23	;   y01  +---+   +---+    +---+    | &lt;br /&gt;
	load_node 	y01	;  -&amp;gt;o--&amp;gt;| + |--&amp;gt;|*K3|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	update_node 	x13	;    |   +---+   +---+  + +---+   y03&lt;br /&gt;
	load_node 	y13	;    |                    - A&lt;br /&gt;
	update_node 	y23	;    |    +---+     +---+   |&lt;br /&gt;
	load_node 	y03	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o&lt;br /&gt;
	update_node 	y13	;         +---+ x13 +---+  x23&lt;br /&gt;
&lt;br /&gt;
; allpass 5&lt;br /&gt;
	add_node 	y25	;&lt;br /&gt;
	mult_32		k5	;         y25   +---+ y15 +---+&lt;br /&gt;
	subtr_node	x25	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+&lt;br /&gt;
	limit_store 	y05	;          |    +---+     +---+    |&lt;br /&gt;
	load_node 	x15	;          v                       |&lt;br /&gt;
	update_node 	x25	;   y03  +---+   +---+    +---+    | &lt;br /&gt;
	load_node 	y03	;  -&amp;gt;o--&amp;gt;| + |--&amp;gt;|*K5|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	update_node 	x15	;    |   +---+   +---+  + +---+   y05&lt;br /&gt;
	load_node 	y15	;    |                    - A&lt;br /&gt;
	update_node 	y25	;    |    +---+     +---+   |&lt;br /&gt;
	load_node 	y05	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o&lt;br /&gt;
	update_node 	y15	;         +---+ x15 +---+  x25&lt;br /&gt;
&lt;br /&gt;
; allpass 7&lt;br /&gt;
	add_node 	y27	;&lt;br /&gt;
	mult_32		k7	;         y27   +---+ y17 +---+&lt;br /&gt;
	subtr_node	x27	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+&lt;br /&gt;
	limit_store 	y07	;          |    +---+     +---+    |&lt;br /&gt;
	load_node 	x17	;          v                       |&lt;br /&gt;
	update_node 	x27	;   y05  +---+   +---+    +---+    | &lt;br /&gt;
	load_node 	y05	;  -&amp;gt;o--&amp;gt;| + |--&amp;gt;|*K7|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	update_node 	x17	;    |   +---+   +---+  + +---+   y07&lt;br /&gt;
	load_node 	y17	;    |                    - A&lt;br /&gt;
	update_node 	y27	;    |    +---+     +---+   | &lt;br /&gt;
	load_node 	y07	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o &lt;br /&gt;
	update_node 	y17	;         +---+ x17 +---+  x27&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* PWM - D/A-output&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
; output y07 to PWM-DAC&lt;br /&gt;
&lt;br /&gt;
;test: output y01&lt;br /&gt;
	ldd	accu3, Y+y01+1	;&lt;br /&gt;
;&lt;br /&gt;
	subi	accu3,$80	; signed to unsigned  $8000 -&amp;gt;$0000, $7FFF -&amp;gt;$FFFF&lt;br /&gt;
	sts	OCR1AH,zero	; &lt;br /&gt;
	sts	OCR1AL,accu3	; fast PWM 8 bit y07 output to OCR1A&lt;br /&gt;
	ldi	YL,Low(DatTbl1)	; back to 1st data table&lt;br /&gt;
; output y08 to PWM-DAC&lt;br /&gt;
;	load_node 	y08	; load y08&lt;br /&gt;
&lt;br /&gt;
; test outpt y02&lt;br /&gt;
	load_node 	y02	; load y02&lt;br /&gt;
;&lt;br /&gt;
	subi	datah,$80	; signed to unsigned  $8000 -&amp;gt;$0000, $7FFF -&amp;gt;$FFFF&lt;br /&gt;
	sts	OCR1BH,zero	; &lt;br /&gt;
	sts	OCR1BL,accu3	; fast PWM 8 bit y08 output to OCR1B&lt;br /&gt;
	cbi	PortD,0		; just to measure INT-Time&lt;br /&gt;
	out	SREG,savsrg	; restore status register&lt;br /&gt;
	reti			; &lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* coefficient table in flash memory&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
CoTblF:&lt;br /&gt;
	.dw 	15709 	 	; k2 *32768 (0,4794008655888)&lt;br /&gt;
	.dw 	28712	 	; k4 *32768 (0,8762184935393)&lt;br /&gt;
	.dw 	32001		; k6 *32768 (0,9765975895082)&lt;br /&gt;
	.dw 	32686	 	; k8 *32768 (0,9974992559356)&lt;br /&gt;
	.dw 	 5301	 	; k1 *32768 (0,1617584983677)&lt;br /&gt;
	.dw 	24020		; k3 *32768 (0,7330289323415)&lt;br /&gt;
	.dw 	30977 		; k5 *32768 (0,9453497003291)&lt;br /&gt;
	.dw 	32460	 	; k7 *32768 (0,9905991566845)&lt;br /&gt;
&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* data in SRAM&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
.dseg&lt;br /&gt;
.org	$0100&lt;br /&gt;
DatTbl1:&lt;br /&gt;
	; &amp;quot;allpass&amp;quot; 0&lt;br /&gt;
	.dw 	$0000 	 	; x10&lt;br /&gt;
	; allpass 2&lt;br /&gt;
	.dw 	$0000 	 	; x12&lt;br /&gt;
	.dw 	$0000 	 	; x22&lt;br /&gt;
	.dw 	$0000 	 	; y02&lt;br /&gt;
	.dw 	$0000 	 	; y12&lt;br /&gt;
	.dw 	$0000 	 	; y22&lt;br /&gt;
	; allpass 4&lt;br /&gt;
	.dw 	$0000 	 	; x14&lt;br /&gt;
	.dw 	$0000 	 	; x24&lt;br /&gt;
	.dw 	$0000 	 	; y04&lt;br /&gt;
	.dw 	$0000 	 	; y14&lt;br /&gt;
	.dw 	$0000 	 	; y24&lt;br /&gt;
	; allpass 6&lt;br /&gt;
	.dw 	$0000 	 	; x16&lt;br /&gt;
	.dw 	$0000 	 	; x26&lt;br /&gt;
	.dw 	$0000 	 	; y06&lt;br /&gt;
	.dw 	$0000 	 	; y16&lt;br /&gt;
	.dw 	$0000 	 	; y26&lt;br /&gt;
	; allpass 8&lt;br /&gt;
	.dw 	$0000 	 	; x18&lt;br /&gt;
	.dw 	$0000 	 	; x28&lt;br /&gt;
	.dw 	$0000 	 	; y08&lt;br /&gt;
	.dw 	$0000 	 	; y18&lt;br /&gt;
	.dw 	$0000 	 	; y28&lt;br /&gt;
CoTblS:&lt;br /&gt;
	.dw 	$0000 	 	; k2&lt;br /&gt;
	.dw 	$0000 	 	; k4&lt;br /&gt;
	.dw 	$0000		; k6&lt;br /&gt;
	.dw 	$0000	 	; k8&lt;br /&gt;
DatTbl2:&lt;br /&gt;
	.dw 	$0000	 	; k1&lt;br /&gt;
	.dw 	$0000		; k3&lt;br /&gt;
	.dw 	$0000 		; k5&lt;br /&gt;
	.dw 	$0000	 	; k7&lt;br /&gt;
	; allpass 1&lt;br /&gt;
	.dw 	$0000 	 	; x11&lt;br /&gt;
	.dw 	$0000 	 	; x21&lt;br /&gt;
	.dw 	$0000 	 	; y01&lt;br /&gt;
	.dw 	$0000 	 	; y11&lt;br /&gt;
	.dw 	$0000 	 	; y21&lt;br /&gt;
	; allpass 3&lt;br /&gt;
	.dw 	$0000 	 	; x13&lt;br /&gt;
	.dw 	$0000 	 	; x23&lt;br /&gt;
	.dw 	$0000 	 	; y03&lt;br /&gt;
	.dw 	$0000 	 	; y13&lt;br /&gt;
	.dw 	$0000 	 	; y23&lt;br /&gt;
	; allpass 5&lt;br /&gt;
	.dw 	$0000 	 	; x15&lt;br /&gt;
	.dw 	$0000 	 	; x25&lt;br /&gt;
	.dw 	$0000 	 	; y05&lt;br /&gt;
	.dw 	$0000 	 	; y15&lt;br /&gt;
	.dw 	$0000 	 	; y25&lt;br /&gt;
	; allpass 7&lt;br /&gt;
	.dw 	$0000 	 	; x17&lt;br /&gt;
	.dw 	$0000 	 	; x27&lt;br /&gt;
	.dw 	$0000 	 	; y07&lt;br /&gt;
	.dw 	$0000 	 	; y17&lt;br /&gt;
	.dw 	$0000 	 	; y27&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Kategorie:AVR-Projekte]]&lt;br /&gt;
[[Category:DSP]]&lt;/div&gt;</summary>
		<author><name>Claus w</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Hilbert-Transformator_(Phasenschieber)_mit_ATmega&amp;diff=102905</id>
		<title>Hilbert-Transformator (Phasenschieber) mit ATmega</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Hilbert-Transformator_(Phasenschieber)_mit_ATmega&amp;diff=102905"/>
		<updated>2021-01-09T22:49:57Z</updated>

		<summary type="html">&lt;p&gt;Claus w: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Dieser Artikel ist eine Fortsetzung von [[Digitalfilter mit ATmega]] und behandelt ein spezielles Digitalfilter namens Hilbert-Transformator.&lt;br /&gt;
&lt;br /&gt;
Neben den üblichen Filtern, Tiefpass, Hochpass, Bandpass und Bandsperre, gibt es einige weitere Typen. In der Literatur findet man u.a. noch den Allpass, Phasenschieber, Integrator und Differentiator.&lt;br /&gt;
&lt;br /&gt;
===Der Hilbert-Transformator, ein Breitband-90-Grad-Phasenschieber===&lt;br /&gt;
&lt;br /&gt;
In den Lehrbüchern wird er völlig zu Unrecht eher am Rande abgehandelt. Tatsächlich findet man ihn in allen Schaltungen zur Datenübertragung, zu Modulation oder Demodulation mit I/Q-Mischern, im „Software-defined radio“.&lt;br /&gt;
&lt;br /&gt;
Auch ein Hilbert-Transformator kann mithilfe von Scilab berechnet werden. Allerdings gibt es keine fertige Software, man muss sich durch einige Literatur hindurchfressen, z.&amp;amp;nbsp;B. ISBN 0471619957 Sanjit Mitra, Handbook for DSP (1993), Kapitel „Special Filter Designs“ von [https://web.archive.org/web/20100610031102/http://faculty.cua.edu/regalia/ Phillip Regalia].&lt;br /&gt;
[https://web.itu.edu.tr/hulyayalcin/Signal_Processing_Books/DSP_Applications_Mitra.pdf Matlab-Plots dazu hier ab Seitenzahl 41]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
GNU Octave stellt die Hilbert-Transformation und den Parks-McClellan-hilbert-FIR-Filterentwurf im [http://octave.sourceforge.net/signal/function/remez.html octave-forge Paket &amp;quot;signal&amp;quot;] zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
Eine Fundgrube sind die Matlab-Texte von Prof. Schüssler, die vorab 1998 zum  zweiten Band seines Lehrbuchs auf seiner Webseite veröffentlicht wurden. Inzwischen ist der erste Band in der fünften Auflage erschienen [http://www.springer.com/engineering/signals/book/978-3-540-78250-6 ISBN 9783540782506] , der zweite Band ISBN 9783642011184 2010 erstmalig erschienen,  [http://www.lms.lnt.de/forschung/veroeffentlichungen/buecher/dsv.shtml Software-Download hier] aber die Webseite ist nach seinem Tod 2007 abgeschaltet. Zum Glück gibt es das  &lt;br /&gt;
[http://web.archive.org/web/20041206171820/www.nt.e-technik.uni-erlangen.de/~hws/dsv2programs/index.html  Webarchiv], wo die Texte noch zu finden sind.&lt;br /&gt;
&lt;br /&gt;
Zu dieser Zeit waren die Matlab-Programme noch nicht in „Toolboxen“ untergebracht, deren Funktion von außen nicht mehr sichtbar ist. Daher lassen sie sich relativ einfach in Scilab oder Octave übersetzen.&lt;br /&gt;
&lt;br /&gt;
Vier Versionen von Hilbert-Transformatoren werden hier berechnet: &lt;br /&gt;
* FIR-Hilbert, aufwendig, aber streng linearphasig, der bekannteste Typ, da schon lange mit dem Matlab-Befehl remez / firpm und Parameter &#039;hilbert&#039; berechenbar. Mit dem octave-forge Paket &amp;quot;signal&amp;quot; ist remez mit &amp;quot;hilbert&amp;quot; verfügbar. Scilab kennt diesen Parameter nicht.&lt;br /&gt;
* näherungsweise linearphasiger IIR-Hilbert, maximal flach,&lt;br /&gt;
* näherungsweise linearphasiger IIR-Hilbert, Tschebyscheff &lt;br /&gt;
* minimalphasiger IIR-Hilbert, kompakt, aber mit großen Gruppenlaufzeitschwankungen, eher für Audioanwendungen als Digitalsignale.&lt;br /&gt;
&lt;br /&gt;
Im Artikel von Schüßler/Steffen (siehe unten) sind in zwei vergleichenden Beispielen die Gruppenlaufzeitschwankungen des maximal Flachen etwa halb so groß, des Minimalphasigen etwa fünf Mal so groß wie die Tschbyscheff-Version.&lt;br /&gt;
&lt;br /&gt;
Zumindest der kompakte IIR-Hilbert lässt sich auch in einem ATmega unterbringen. Er besteht aus einer Verzögerung und zwei Allpässen, die wieder aus SOS-Teilfiltern aufgebaut sind. Pro Teilfilter gibt es nur einen Koeffizienten, sodass man mindestens acht Teilfilter verwenden kann.&lt;br /&gt;
&lt;br /&gt;
===Ein Hilbert-Kochrezept (noch unvollständig)===&lt;br /&gt;
&lt;br /&gt;
Folgen wir dem Zahlenbeispiel und Berechnungsweg im „Handbook for DSP“.&lt;br /&gt;
&lt;br /&gt;
Zuerst berechnen wir einen elliptischen &#039;&#039;Halbband&#039;&#039;-Tiefpass. Halbband besagt, dass die beiden Grenzfrequenzen symmetrisch zur halben Nyquist- Frequenz also 0,25 * Abtastfrequenz liegen, siehe Bild oben rechts. Die genauen Bedingungen lauten in der Schreibweise des Buches (&#039;&#039;p&#039;&#039;=passband, &#039;&#039;s&#039;&#039;=stopband):&lt;br /&gt;
* Omega&amp;lt;sub&amp;gt;s&amp;lt;/sub&amp;gt; + Omega&amp;lt;sub&amp;gt;p&amp;lt;/sub&amp;gt; = Pi &amp;lt;br&amp;gt; (auf Omega&amp;lt;sub&amp;gt;sample&amp;lt;/sub&amp;gt; normierte Skala: Samplerate=2*Pi)&lt;br /&gt;
* (1-Delta&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;)&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; +Delta&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;=1&lt;br /&gt;
&lt;br /&gt;
Als Zahlenwerte werden Omega&amp;lt;sub&amp;gt;s&amp;lt;/sub&amp;gt; = 0,55*Pi und Delta&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;=0,01 gewählt, und damit ein elliptischer IIR-Tiefpass 7.Ordnung berechnet.&lt;br /&gt;
Damit erhält er folgende Zahlenwerte der Pole:&lt;br /&gt;
&lt;br /&gt;
 0  0,436688  0,743707 0,927758&lt;br /&gt;
&lt;br /&gt;
===Scilab-Berechnung des Halbbandfilters===&lt;br /&gt;
&lt;br /&gt;
Mit Scilab erhalten wir nach einigem Ausprobieren praktisch dieselben Zahlenwerte, siehe Bild. Die Pole müssten für ein ideales Halbbandfilter genau auf der imaginären Achse liegen, der Realteil genau Null sein (Der Fehler kommt daher, dass die Angabe von f&amp;lt;sub&amp;gt;stop&amp;lt;/sub&amp;gt; vom Programm nicht berücksichtigt wird, das Filter wäre überbestimmt).&lt;br /&gt;
Diese Zahlen werden noch quadriert (&#039;&#039;konjugiert komplexe&#039;&#039; Pole zusammengefasst) und bilden schließlich die Koeffizienten des Hilbert-Transformators.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Halbbandfilter.png|Mit Scilab berechnetes Halbbandfilter 7.Ordnung|640px]]&lt;br /&gt;
&lt;br /&gt;
Die Übertragungsfunktion des gesuchten Hilbert-Transformators soll wie bisher H(z) heißen. Zur Unterscheidung nennen wir die bis jetzt berechnete Tiefpassfunktion G(z). &lt;br /&gt;
&lt;br /&gt;
Wieder wird sie in SOS-Teilfilter aufgeteilt. Hier allerdings in die &amp;lt;u&amp;gt;Summe&amp;lt;/u&amp;gt; von zwei &amp;lt;u&amp;gt;parallel&amp;lt;/u&amp;gt; geschalteten &#039;&#039;Allpass&#039;&#039;-Funktionen A&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; und A&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt; plus eine Verzögerung um einen Sampletakt, in der Übertragungsfunktion als „z&amp;lt;sup&amp;gt;-1&amp;lt;/sup&amp;gt;“ ausgedrückt.&lt;br /&gt;
&lt;br /&gt;
Ein Allpass läßt alle Signalfrequenzen mit unveränderter Amplitude durch, verändert nur die Phase. Seine SOS-Teilfunktion ist besonders einfach aufgebaut, zwei Koeffizienten sind Null, zwei sind gleich Eins und die beiden restlichen identisch. Damit benötigt man nur eine Multiplikation pro Teilfilter.&lt;br /&gt;
&lt;br /&gt;
Die Tiefpass-Übertragungsfunktion erhält so die Form:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;G(z) = ½ * ( A&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; (z&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;) + z&amp;lt;sup&amp;gt;-1&amp;lt;/sup&amp;gt; * A&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt; (z&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;))&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
mit&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
A_{1}(z^{2})=\frac{z^{-2}+0,190696}{1+0,190696\ast z^{-2}}\ast&lt;br /&gt;
{\frac{z^{-2}+0,860735}{1+0,860735\ast z^{-2}}}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
A_{2}(z^{2})=\frac{z^{-2}+0,553100}{1+0,553100\ast z^{-2}}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn man die beiden Ausgänge nicht addiert, sondern subtrahiert, entsteht ein Hochpass gleicher Grenzfrequenz. Beides kombiniert ergibt eine digitale &#039;&#039;Frequenzweiche&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Zum Übergang auf den Hilbert-Transformator ersetzen (&#039;&#039;substituieren&#039;&#039;) wir das z durch -jz und multiplizieren das ganze mit 2:&lt;br /&gt;
&lt;br /&gt;
H(z)= 2*G(-jz)&lt;br /&gt;
  &lt;br /&gt;
&#039;&#039;&#039;H(z) = A&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; (-z&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;) + j* z&amp;lt;sup&amp;gt;-1&amp;lt;/sup&amp;gt; * A&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt; (-z&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
mit&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
A_{1}(-z^{2})=\frac{z^{-2}-0,190696}{1-0,190696\ast z^{-2}}\ast&lt;br /&gt;
{\frac{z^{-2}-0,860735}{1-0,860735\ast z^{-2}}}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
A_{2}(-z^{2})=\frac{z^{-2}-0,553100}{1-0,553100\ast z^{-2}}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie man sieht, ändern sich nur die Vorzeichen. Die Pole liegen aber im Pol-Nullstellendiagramm auf der reellen Achse.&lt;br /&gt;
&lt;br /&gt;
Die Ausgänge der beiden Allpässe sind jetzt gegeneinander um 90 Grad phasenverschoben, und können auf einen I/Q-Modulator gegeben werden. Umgekehrt kann man auch die beiden Eingänge auftrennen, und zwei um 90 Grad versetzte Signale aus einem I/Q-Demodulator einspeisen und die Ausgangssignale addieren oder subtrahieren, je nach gewünschtem Seitenband.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Allpaesse.png]]&lt;br /&gt;
&lt;br /&gt;
Und weil das so gut funktionierte, hier noch die Berechnung des Hilbert-Transformators [http://www.mikrocontroller.net/topic/92630#new von Olli Niemitalo] mit einem Halbband-Tiefpass 17.Ordnung, was zu acht SOS-Teilfiltern führt, dazu folgt unten ein ATmega48-Programm.&lt;br /&gt;
Die originalen URL sind verwaist, aber im Webarchiv noch zu finden:&amp;lt;br&amp;gt;&lt;br /&gt;
https://web.archive.org/web/20070719141658/http://yehar.com/ViewHome.pl?page=dsp/hilbert/ &amp;lt;br&amp;gt;&lt;br /&gt;
https://web.archive.org/web/20070814013543/http://yehar.com/ViewHome.pl?page=dsp/hilbert/011729.html &amp;lt;br&amp;gt;&lt;br /&gt;
Olli ist auch heute (2019) noch aktiv:&amp;lt;br&amp;gt;&lt;br /&gt;
http://yehar.com/blog/&amp;lt;br&amp;gt;&lt;br /&gt;
speziell sein IIR-Hilbert:&amp;lt;br&amp;gt;&lt;br /&gt;
http://yehar.com/blog/?p=368&amp;lt;br&amp;gt;&lt;br /&gt;
Diskussion auch dazu:&amp;lt;br&amp;gt;&lt;br /&gt;
https://dsp.stackexchange.com/questions/37411/iir-hilbert-transformer/59157#59157&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Bild:Halbbandfilter2.png|Halbbandfilter 17.Ordnung|640px]]&lt;br /&gt;
&lt;br /&gt;
===Der näherungsweise linearphasige Hilbert-Transformator===&lt;br /&gt;
&lt;br /&gt;
Er wird im Handbook for DSP auf zwei Seiten sehr kurz abgehandelt. Statt aus zwei Allpässen besteht er aus einem einzigen, im anderen Zweig wird das Signal nur zeitverzögert, was mit einem Ringpuffer wenig Rechenzeit kostet. Eine Zeitverzögerung ist sozusagen die einfachste Form eines Allpasses, damit ist diese Bauform ein Spezialfall der oben gezeigten. Aus Schüsslers Texten erfahren wir noch, dass das Halbband-Tiefpassfilter zur Berechnung hier Tschebyscheff-Charakter haben muß.&lt;br /&gt;
&lt;br /&gt;
Das Zahlenbeispiel zitiert Regalia aus einer anderen Veröffentlichung [http://www.cs.tut.fi/~mr/MRJulk92.html (M. Renfors and T. Saramäki, A class of approximately linear phase digital filters composed of allpass subfilters 1986 ) ] Der Allpass hat neun Koeffizienten, die Zeitverzögerung beträgt 17 Sampletakte. Der Halbband-Tiefpass hat eine Sperrdämpfung von &amp;gt; 49 dB. Sein Frequenzgang und der Phasengang des berechneten Hilbert-Transformators sind als Bild gezeigt.&lt;br /&gt;
&lt;br /&gt;
Zum Allpass gibt es noch folgende Zahlenwerte:&lt;br /&gt;
&lt;br /&gt;
Pole location for A(z)&amp;lt;br&amp;gt;&lt;br /&gt;
z= 	-0.8699928078&amp;lt;br&amp;gt;&lt;br /&gt;
	 0.491194141 ± j0.183666529&amp;lt;br&amp;gt;&lt;br /&gt;
	 0.252724179 ± j0.463085544&amp;lt;br&amp;gt;&lt;br /&gt;
	-0.109950894 ± j0.548611467&amp;lt;br&amp;gt;&lt;br /&gt;
	-0.447326028 ± j0.356810323&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das könnte also ebenfalls noch in einen  ATmega passen.&lt;br /&gt;
&lt;br /&gt;
===Hilbert ohne Multiplizierer===&lt;br /&gt;
&lt;br /&gt;
Eine interessante Variante wird im Artikel [http://kondor.etf.bg.ac.yu/~lutovac/pdf/eusi98lm.pdf Design of multiplierless elliptic IIR halfband filters and Hilbert transformers] vorgestellt. Ähnlich wie im Cordic-Algorithmus für trigonometrische Funktionen werden Multiplikationen vermieden, durch geschickte Wahl der Koeffizienten als Zweierpotenzen.&lt;br /&gt;
&lt;br /&gt;
Die beiden Allpässe des Zahlenbeispiels haben folgende Übertragungsfunktionen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
A_1(z^{-2})&lt;br /&gt;
&amp;amp;=\frac{z^{-2}-0{,}12109375}{1-0{,}12109375 \cdot z^{-2}}&lt;br /&gt;
\cdot\frac{z^{-2}-0{,}6640625}{1-0{,}6640625 \cdot z^{-2}} \\&lt;br /&gt;
&amp;amp;=\frac{z^{-2}-(\frac18 - \frac1{256})}{1-(\frac18 - \frac1{256}) \cdot z^{-2}}&lt;br /&gt;
\cdot\frac{z^{-2}-(\frac12 + \frac18 + \frac1{32} + \frac1{128})}{1-(\frac12 + \frac18 + \frac1{32} + \frac1{128})\cdot z^{-2}}\\&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
A_2(z^{-2})\cdot{z^{-1}}&lt;br /&gt;
&amp;amp;=z^{-1}&lt;br /&gt;
\cdot\frac{z^{-2}-0{,}390625}{1-0{,}390625 \cdot z^{-2}}&lt;br /&gt;
\cdot\frac{z^{-2}-0{,}890625}{1-0{,}890625 \cdot z^{-2}}\\&lt;br /&gt;
&amp;amp;=z^{-1}&lt;br /&gt;
\cdot\frac{z^{-2}-(\frac14 + \frac18 + \frac1{64})}{1-(\frac14 + \frac18 + \frac1{64}) \cdot z^{-2}}&lt;br /&gt;
\cdot\frac{z^{-2}-(1 - \frac18 + \frac1{64})}{1-(1 - \frac18 + \frac1{64}) \cdot z^{-2}}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Hilbert Transformator nach der FIR-Methode ==&lt;br /&gt;
&lt;br /&gt;
Nach dem Additionstheorem ergibt sich aus dem multiplikativen Mischen (u_prod = u_1 * u_2) zweier Wechselspannungen eine Überlagerung (u_sum = u_3 + u_4) zweier anderer Wechelspannungen; die Freqenz der einen Wechselspannung ist die Summe der Frequenzen der Faktor-Spannungen - die Frequenz der anderen Wechselspannung ist die Differenz der Frequenzen der Faktorspannungen. Jeweils eine der beiden Frequenzen ist das Nutz-Signal, die andere Frequenz ist die Spiegelfrequenz.&lt;br /&gt;
&lt;br /&gt;
Der Hilbert-Tranformator ist ein Mittel um nur das Nutzsignal und nicht die Spiegelfrequenz zu mischen. Es wird nach den Regeln der Multiplikation komplexer Zahlen gemischt. Eingabesignal und Mischoszillator müssen in der Form der EULERschen Identität vorliegen: &lt;br /&gt;
&lt;br /&gt;
y = A * exp( j * phi )  = A * ( cos( phi ) + j * sin( phi )  ) ; phi = omega * t ; omega = 2 * pi * f ; f ... Frequenz ; A ... Amplitude ; t ... Zeit&lt;br /&gt;
&lt;br /&gt;
Mit der exp() - Darstellung kann man mischen, indem man den Ausdruck phi = 2 * pi * t * (f1 + f2) anwendet. Dabei addieren sich die Frequenzen ohne Spiegelfrequenz. Beide Frequenzen müssen als komplexe Zahlen vorliegen, also jede Frequenz als zwei Wechselspannungen mit (jeweils pro Frequenz) gleicher Amplitude. Liegt nur ein einfaches Sinus-Signal vor, kann man das dazugehörige Cosinus-Signal durch Phasenverschiebung um 90° mit einem Hilbert-Transformator erreichen. Danach wendet man die Multiplikation an:&lt;br /&gt;
&lt;br /&gt;
y[ re, j * im ]:= x1[ re, j * im ]* x2[ re, j * im ] = (x1.re * x2.re - x1.im * x2.im) + j * (x1.re * x2.im + x2.re * x1.im) ; re ... Realteil ; im ... Imag. Teil&lt;br /&gt;
&lt;br /&gt;
Jedes Glied des einen Faktors mit jedem Glied des anderen Faktors unter Beachtung der imaginären Einheit multiplizieren. Wendet man bei dem Signal einer der beiden Frequenzen nur einen der beiden Anteile (entweder nur realen Cosinus-Teil oder imaginären Sinusteil) so entsteht eine &amp;quot;negative&amp;quot; Frequenz (der Zeiger in der komplexen Zahlenebene dreht sich andersherum). Somit wird diese Frequenz von der anderen subtrahiert (phi = 2 * pi * t * (f1 - f2)). Das kann sowohl rechnerisch als auch durch Umpolen einer Bandfilterwicklung errreicht werden. Für Zwischenergebnisse nutzt man beide Signalteile weiter, für z.B. eine Audioausgabe genügt einer.&lt;br /&gt;
&lt;br /&gt;
Kann man zu einem Sinussignal das Cosinus-Signal auch ohne synthetisches Filter erhalten? Genau weiß ich es nicht. Für einen Oszillator braucht man mindestens zwei Energiespeicher. Beide sind (wenn es kein Drehstromoszillator ist) um 90° phasenverschoben. Hier kommt man ohne synthetisches Filter aus. Anders bei Schallwellen. Der eine Speicher besteht hier sowohl aus Schalldruck als auch aus Schallschnelle. Sind beide um 0° phasenverschoben, so bewegt sich die Welle in die eine Richtung, bei 180° entsprechend entgegengesetzt. Der andere Speicher ist die 1. Ableitung von jeweils Schalldruck und Schallschnelle. Die Ableitung ist um 90° phasenverschoben aber bei frequenzabhängiger Amplitude ( y = A * sin( omega * t ) ; y&#039; = omega * A * cos( omega * t ) ). Ohne Spiegelfrequenz kann man das nur für eine feste Frequenz mischen. Bei einem Frequenzband braucht man das synthetische Filter.&lt;br /&gt;
&lt;br /&gt;
Der Hilbert-Transformator erzeugt aus einem Sinus-Signal das um 90° verschobene Cosinus-Signal. Ein Beispiel in Python:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Begin Hilbert FIR filter.&lt;br /&gt;
import math # Math&lt;br /&gt;
import numpy as np # Math&lt;br /&gt;
import matplotlib as mlp # Plot&lt;br /&gt;
import matplotlib.pyplot as plt # Plot&lt;br /&gt;
&lt;br /&gt;
FREQUENCY = 400.0 # 1 / s&lt;br /&gt;
RATE = 48000.0 # samples / s&lt;br /&gt;
SAMPLES = 4000&lt;br /&gt;
CELLS = 501&lt;br /&gt;
STEPS = SAMPLES - CELLS&lt;br /&gt;
PREFIX = (CELLS - 1) / 2&lt;br /&gt;
SUFFIX = CELLS - PREFIX&lt;br /&gt;
POSTFIX = SAMPLES - CELLS&lt;br /&gt;
&lt;br /&gt;
samples = range(SAMPLES)&lt;br /&gt;
cells = range(CELLS)&lt;br /&gt;
steps = range(STEPS)&lt;br /&gt;
prefixes = range(PREFIX)&lt;br /&gt;
suffixes = range(SUFFIX)&lt;br /&gt;
postfixes = range(POSTFIX)&lt;br /&gt;
&lt;br /&gt;
input = []&lt;br /&gt;
re = []&lt;br /&gt;
im = []&lt;br /&gt;
coefficients = []&lt;br /&gt;
&lt;br /&gt;
def plot():&lt;br /&gt;
&lt;br /&gt;
	for sample in samples:&lt;br /&gt;
		if(SAMPLES / 2 &amp;gt; sample):&lt;br /&gt;
			_phi = FREQUENCY * sample / RATE * 2.0 * math.pi&lt;br /&gt;
		else:&lt;br /&gt;
			_phi = 5 * FREQUENCY * sample / RATE * 2.0 * math.pi&lt;br /&gt;
		input.append(math.sin(_phi))&lt;br /&gt;
&lt;br /&gt;
	for cell in cells:&lt;br /&gt;
		arg = cell - (CELLS - 1) / 2.0&lt;br /&gt;
		if(0.0 == arg):&lt;br /&gt;
			coefficients.append(0.0)&lt;br /&gt;
		else:&lt;br /&gt;
			arg *= math.pi&lt;br /&gt;
			coefficients.append((1.0 - math.cos(arg)) / arg)&lt;br /&gt;
	&lt;br /&gt;
	for postfix in postfixes:&lt;br /&gt;
		coefficients.append(0.0)&lt;br /&gt;
	&lt;br /&gt;
	for prefix in prefixes:&lt;br /&gt;
		re.append(0.0)&lt;br /&gt;
		im.append(0.0)&lt;br /&gt;
		&lt;br /&gt;
	for step in steps:&lt;br /&gt;
		re.append(input[step + PREFIX])&lt;br /&gt;
		sum = 0.0&lt;br /&gt;
		for cell in cells:&lt;br /&gt;
			sum += input[step + cell] * coefficients[cell];&lt;br /&gt;
		im.append(sum)&lt;br /&gt;
		&lt;br /&gt;
	for suffix in suffixes:&lt;br /&gt;
		re.append(0.0)&lt;br /&gt;
		im.append(0.0)&lt;br /&gt;
	&lt;br /&gt;
	# Prepare the plot.&lt;br /&gt;
	plt.ylabel(&#039;amplitude&#039;)&lt;br /&gt;
	plt.xlabel(&#039;timesteps&#039;)&lt;br /&gt;
	plt.axis([0, SAMPLES - 1, -1.5, 1.5])&lt;br /&gt;
	plt.grid(True)&lt;br /&gt;
	plt.plot(samples, re, &#039;r-&#039;)&lt;br /&gt;
	plt.plot(samples, im, &#039;b-&#039;)&lt;br /&gt;
	plt.show()&lt;br /&gt;
# End.&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
Neben ein Array aus abgetasteten Werten eines akustischen Signales (hier Sinus-Signal, künstlich berechnet) wird das Array des Transformationskerns gelegt. Das Array des Transformationskerns ist dabei viel kürzer und es wird nur der gemeinsame Bereich berechnet. Der Wert des Cosinus-Signals, das zu dem Sinus-Signal gehört, das sich auf der Position der Mitte des Transformationskerns befindet, ergibt sich aus der Summe der Werte aus dem Sinus-Signal multiplizert mit den Faktoren aus dem Transformationskern mit gleichem Index. Das folgende Cosinus-Signal wird berechnet indem man zuvor den Transformationskern um einen Index gegenüber dem Eingabe-Sinus-Signal weiterschiebt (usw. bis zum Ende des Signales). Am Anfang und am Ende des berechneten Cosinus-Signales entsteht ein Stück Verlust der jeweils halb so lang wie der Transformationskern ist. Bei sehr lang dauernden Signalen (fast immer) ist statt dessen mit einem Ringpuffer zu arbeiten.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
t ... Zeit&lt;br /&gt;
b[Länge k] ... Transformationskern&lt;br /&gt;
i[undendlich lang] ... Sinus - Signal oder Summe aus Sinus-Signalen&lt;br /&gt;
o[undendlich lang] ... um 90° verschobenes Cosinus - Signal&lt;br /&gt;
=&amp;gt;&lt;br /&gt;
o[t] := Summe { i[n+t] * b[n+t] } ; -k/2 &amp;lt;= n &amp;lt;= +k/2 ; i &amp;gt;= k/2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Der Transformationskern kann wie folgt ermittelt werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x ... natürliche Zahl &amp;gt; 0&lt;br /&gt;
k ... 4 * x + 1&lt;br /&gt;
b[] ... Transformationskern der Länge k&lt;br /&gt;
n ... Index innerhalb des Tranformationskerns&lt;br /&gt;
pi ... 3.14159...&lt;br /&gt;
b[n] := ( 1 - cos( n * pi ) ) / ( n * pi ) ; Ausnahme ist b[0] := 0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Datei:FIR_Kernel_Small.png|200px|thumb|right|Hilbert Transformationskern klein]]&lt;br /&gt;
&lt;br /&gt;
Dabei ist das Argument der cos() - Funktion immer ganzzahlig. &amp;quot;1 - cos(...)&amp;quot; ist für ungerade &amp;quot;n&amp;quot; immer NULL. Der Kern hat nahe n == 0 maximale Werte und nimmt zum Rand hin ab. Ein Kern mit zuwenig Länge (k ist zu klein) wirkt als Hochpass und verkleinert die Amplitude von Signalen kleiner Frequenz (ist unbrauchbar). Kommen hohe und tiefe Frequenzen im Signal gleichzeitig vor, dann braucht man sowohl eine hohe Abtastrate als auch einen langen Kern ( k wird groß, z.B. Größenordnung 801 bei einem Audiosignal). Ändert sich das Nutzsignal unerwartet sprungartig so erhält man im Cosinus-Signal eine Art Sprungantwort.&lt;br /&gt;
&lt;br /&gt;
* Großer Transformationskern : [[Medium:FIR_Kernel_Big.png]]&lt;br /&gt;
* Transformation zweier Signale verschiedener Frequenz : [[Medium:Hilber_FIR_OK.png]]&lt;br /&gt;
* Transformation eines Sprunges im Signal : [[Medium:Hilbert_FIR_OK_Lense.png]]&lt;br /&gt;
* Transformationsfehler bei zu kleinem Kern (k ist zu klein) :  [[Medium:Hilbert_FIR_Too_Small_Kernel.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Zusammenfassung&amp;lt;/b&amp;gt;&lt;br /&gt;
Hilbert-Transformation ermittelt zu einem Sinus-Signal das um 90° verschobene Cosinus-Signal. Das gilt auch für eine Summe von Sinussignalen unterschiedlicher Frequenzen und Amplituden. Die Amplitude des Cosinus-Signales ist gleich der Amplitude des Sinus-Signales (kann geringfügig abweichen aber korrigiert werden). Das Transformieren erfolgt meist synthetisch, z.B. in digitalen Signal Prozessoren. Die Hilbert-Transformation wird verwendet, wenn man Sinus-Signal und Cosinus-Signal benötigt aber nur das Sinus-Signal vorliegt. Beide Signale (sin(...) und cos(...)) zusammen entsprechen einer Folge komplexer Zahlen. Damit kann man multiplikativ mischen ohne Spiegelfrequenz. Liegen beide Faktoren der Mischung als komplexe Zahlen vor, kann man jedes Glied der einen Zahl mit jedem Glied der anderen Zahl multiplizieren unter Beachtung der komplexen Einheit &amp;quot;j&amp;quot;. Falls man sich dabei beide Faktoren jedoch in der exp( j * omega * t ) Schreibweise denkt, so multipliziert man statt dessen Potenzen, indem man die Exponenten addiert. Für eine Berechnung braucht man 4 Multiplikationen, was entweder digital erfolgen kann oder im analogen Fall vier Mischer (z.B. Ringmischer oder Gilbertzellen) benötigt, wenn man das ganze Ergebnis braucht. Der Transformationskern ist ein Array aus Zahlen deren Werte in der Mitte des Arrays groß sind und zum Rand hin abnehmen. &lt;br /&gt;
&lt;br /&gt;
==Weitere Literatur zu Hilbert==&lt;br /&gt;
* Schüssler / [http://www.lnt.de/LMS/staff/index.php?lang=de&amp;amp;function=1&amp;amp;person=5 Steffen] &amp;quot;Halfband Filters and Hilbert Transformers&amp;quot; &amp;lt;br&amp;gt; Irgendwo im Web hatte ich den vollständigen Artikel als PDF gefunden, leider die Adresse nicht notiert, Google findet nur [http://www.springerlink.com/content/p5480n6p8t73t633/ kostenpflichtige Downloads].&lt;br /&gt;
* Dutta / Kumar [http://eprint.iitd.ac.in/dspace/bitstream/2074/1608/1/roydig1989.pdf On Digital Differentiators, Hilbert Transformers, and Half-Band Low-Pass Filters] &amp;lt;br&amp;gt; dank Schrifterkennungsprogramm leicht lädiert&lt;br /&gt;
* Miroslav Lutovac / Ljiljana Milic [http://www.telfor.rs/telfor2000/radovi/7-10.pdf Half-band IIR Filter Design Using Matlab],  [http://kondor.etf.bg.ac.yu/~lutovac/confer.htm weitere Artikel der Autoren]&lt;br /&gt;
* Göckler / Damjanovic [http://www.dsv.rub.de/imperia/md/content/public/wsr06_goecklerdamjanovic.pdf A Family of Efficient Complex Halfband Filters]&lt;br /&gt;
&lt;br /&gt;
==ATmega-Programm Hilbert-Transformer ( fast fertig, schwingt leider)==&lt;br /&gt;
Da der Adressenbereich des ATmega nicht groß genug ist, wird die Tabelle im SRAM in zwei Hälften geteilt.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;* Hilbert transformer with ATmega48P, 90 degree broadband phase shifter   *&lt;br /&gt;
;* 15 MHz xtal, input ADC0, PWM-output OCR1a/b, test output PD0            *&lt;br /&gt;
;* Christoph Kessler 2008                         db1uq_at_t-online_dot_de *&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
.nolist&lt;br /&gt;
.include &amp;quot;m48pdef.inc&amp;quot;&lt;br /&gt;
.list&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;* register 0-15 (no &amp;quot;immediate&amp;quot;-operations possible):&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
.def	mult_l	= r0	; multiplier result&lt;br /&gt;
.def	mult_h	= r1	; multiplier result&lt;br /&gt;
.def	zero	= r2	; zero register (used to add carry flag)&lt;br /&gt;
.def	savsrg	= r3	; save status register during interrupt routine&lt;br /&gt;
.def	reg04	= r4	; free&lt;br /&gt;
.def	reg05	= r5	; free&lt;br /&gt;
.def	reg06	= r6	; free&lt;br /&gt;
.def	reg07	= r7	; free&lt;br /&gt;
.def	reg08	= r8	; free&lt;br /&gt;
.def	reg09	= r9	; free&lt;br /&gt;
.def	reg10	= r10	; free&lt;br /&gt;
.def	reg11	= r11	; free&lt;br /&gt;
.def	reg12	= r12	; free&lt;br /&gt;
.def	accu0	= r13	; Accumulator - 32bit for Interrupt routine&lt;br /&gt;
.def	accu1	= r14	; Accumulator - 32bit for Interrupt routine&lt;br /&gt;
.def	accu2	= r15	; Accumulator - 32bit for Interrupt routine&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;* register 16-23 (&amp;quot;immediate&amp;quot;-operations possible):&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
.def	accu3	= r16	; Accumulator - 32bit for Interrupt routine&lt;br /&gt;
.def	reg17	= r17	; free&lt;br /&gt;
.def	reg18	= r18	; free&lt;br /&gt;
.def	reg19	= r19	; free&lt;br /&gt;
.def	datal	= r20	; Data samples mul register&lt;br /&gt;
.def	datah	= r21	;  for Interrupt routine&lt;br /&gt;
.def	coefl	= r22	; Filter coefficient mul register&lt;br /&gt;
.def	coefh	= r23	;  for Interrupt routine&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;* register 24-31    (16Bit-registers) &lt;br /&gt;
;***************************************************************************&lt;br /&gt;
.def	tmp1	= r24	; general temporary register&lt;br /&gt;
.def	tmp2	= r25	; general temporary register&lt;br /&gt;
;	XL	= r26	; free&lt;br /&gt;
;	XH	= r27	; free&lt;br /&gt;
;	YL	= r28	; used by Interrupt routine&lt;br /&gt;
;	YH	= r29	; used by Interrupt routine&lt;br /&gt;
;	ZL	= r30	; init routine only, free for main program&lt;br /&gt;
;	ZH	= r31	; init routine only, free for main program&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* constants :&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;1st table:&lt;br /&gt;
	;&amp;quot;allpass&amp;quot;0:&lt;br /&gt;
.equ	 x10	= 0&lt;br /&gt;
	; allpass 2:&lt;br /&gt;
.equ	 x12	= 2&lt;br /&gt;
.equ	 x22	= 4&lt;br /&gt;
.equ	 y02	= 6&lt;br /&gt;
.equ	 y12	= 8&lt;br /&gt;
.equ	 y22	= 10&lt;br /&gt;
	; allpass 4:&lt;br /&gt;
.equ	 x14	= 12&lt;br /&gt;
.equ	 x24	= 14&lt;br /&gt;
.equ	 y04	= 16&lt;br /&gt;
.equ	 y14	= 18&lt;br /&gt;
.equ	 y24	= 20&lt;br /&gt;
	; allpass 6:&lt;br /&gt;
.equ	 x16	= 22&lt;br /&gt;
.equ	 x26	= 24&lt;br /&gt;
.equ	 y06	= 26&lt;br /&gt;
.equ	 y16	= 28&lt;br /&gt;
.equ	 y26	= 30&lt;br /&gt;
	; allpass 8:&lt;br /&gt;
.equ	 x18	= 32&lt;br /&gt;
.equ	 x28	= 34&lt;br /&gt;
.equ	 y08	= 36&lt;br /&gt;
.equ	 y18	= 38&lt;br /&gt;
.equ	 y28	= 40&lt;br /&gt;
&lt;br /&gt;
.equ	 k2	= 42&lt;br /&gt;
.equ	 k4	= 44&lt;br /&gt;
.equ	 k6	= 46&lt;br /&gt;
.equ	 k8	= 48&lt;br /&gt;
;2nd table:&lt;br /&gt;
.equ	 k1	= 0&lt;br /&gt;
.equ	 k3	= 2&lt;br /&gt;
.equ	 k5	= 4&lt;br /&gt;
.equ	 k7	= 6&lt;br /&gt;
	; allpass 1:&lt;br /&gt;
.equ	 x11	= 8&lt;br /&gt;
.equ	 x21	= 10&lt;br /&gt;
.equ	 y01	= 12&lt;br /&gt;
.equ	 y11	= 14&lt;br /&gt;
.equ	 y21	= 16&lt;br /&gt;
	; allpass 3:&lt;br /&gt;
.equ	 x13	= 18&lt;br /&gt;
.equ	 x23	= 20&lt;br /&gt;
.equ	 y03	= 22&lt;br /&gt;
.equ	 y13	= 24&lt;br /&gt;
.equ	 y23	= 26&lt;br /&gt;
	; allpass 5:&lt;br /&gt;
.equ	 x15	= 28&lt;br /&gt;
.equ	 x25	= 30&lt;br /&gt;
.equ	 y05	= 32&lt;br /&gt;
.equ	 y15	= 34&lt;br /&gt;
.equ	 y25	= 36&lt;br /&gt;
	; allpass 7:&lt;br /&gt;
.equ	 x17	= 38&lt;br /&gt;
.equ	 x27	= 40&lt;br /&gt;
.equ	 y07	= 42&lt;br /&gt;
.equ	 y17	= 44&lt;br /&gt;
.equ	 y27	= 46&lt;br /&gt;
;*****************************************************&lt;br /&gt;
;* Macros&lt;br /&gt;
;*****************************************************&lt;br /&gt;
.MACRO load_node&lt;br /&gt;
	ldd	datal,Y+@0	; Load low byte of node &lt;br /&gt;
	ldd	datah,Y+@0+1	; Load high byte of node&lt;br /&gt;
.ENDMACRO&lt;br /&gt;
.MACRO update_node&lt;br /&gt;
	std	Y+@0,datal	; Store low byte of node &lt;br /&gt;
	std	Y+@0+1,datah	; Store high byte of node&lt;br /&gt;
.ENDMACRO&lt;br /&gt;
.MACRO add_node&lt;br /&gt;
	ldd	coefl,Y+@0	; Load 2nd node low&lt;br /&gt;
	ldd	coefh,Y+@0+1	; Load 2nd node high&lt;br /&gt;
	add	datal,coefl	; Add low bytes&lt;br /&gt;
	adc	datah,coefh	; Add with carry high bytes&lt;br /&gt;
.ENDMACRO&lt;br /&gt;
.MACRO mult_32&lt;br /&gt;
	ldd	coefl,Y+@0	; Load low byte of coefficient&lt;br /&gt;
	ldd	coefh,Y+@0+1	; Load high byte of coefficient&lt;br /&gt;
	muls	coefh,datah	; Signed multiply, coefficient high byte and data high byte&lt;br /&gt;
	mov     accu2,mult_l	; Copy result word into accumulator byte 2:3&lt;br /&gt;
	mov     accu3,mult_h	; Copy result word into accumulator byte 2:3&lt;br /&gt;
	mul	coefl,datal	; Unsigned multiply, coefficient low byte and data low byte&lt;br /&gt;
	mov	accu0,mult_l	; Copy result word into accumulator byte 2:3&lt;br /&gt;
	mov	accu1,mult_h	; Copy result word into accumulator byte 2:3&lt;br /&gt;
	mulsu	coefh,datal	; Signed-unsigned multiply, coefficient high byte and data low byte&lt;br /&gt;
	sbc	accu3,zero	; Sign extention&lt;br /&gt;
	add	accu1,mult_l	; Add low byte of result to accumulator byte 1&lt;br /&gt;
	adc	accu2,mult_h	; Add with carry high byte of result to accumulator byte 2&lt;br /&gt;
	adc	accu3,zero	; Add carry to accumulator byte 3&lt;br /&gt;
	mulsu	datah,coefl	; Signed-unsigned multiply, data high byte and coefficient low byte&lt;br /&gt;
	sbc	accu3,zero	; Sign extention&lt;br /&gt;
	add	accu1,mult_l	; Add low byte of result to accumulator byte 1&lt;br /&gt;
	adc	accu2,mult_h	; Add with carry high byte of result to accumulator byte 2&lt;br /&gt;
	adc	accu3,zero	; Add carry to accumulator byte 3&lt;br /&gt;
.ENDMACRO&lt;br /&gt;
.MACRO subtr_node&lt;br /&gt;
	ldd	datal,Y+@0	; Load 2nd node low&lt;br /&gt;
	ldd	datah,Y+@0+1	; Load 2nd node high&lt;br /&gt;
	sub	accu0,datal	; Subtract low byte&lt;br /&gt;
	sbc	accu1,datah	; Subtract with carry high byte&lt;br /&gt;
	sbc	accu2,zero	;&lt;br /&gt;
	sbc	accu3,zero	;&lt;br /&gt;
.ENDMACRO&lt;br /&gt;
.MACRO limit_store&lt;br /&gt;
	cpi	accu3,$40	; accu &amp;lt;   $40000000 ?&lt;br /&gt;
	brlo	NoLimit1	;&lt;br /&gt;
	cpi	accu3,-$40	; accu &amp;gt;= -$40000000 ?&lt;br /&gt;
	brsh	NoLimit1	;&lt;br /&gt;
	clr	accu2		; accu2 = $00&lt;br /&gt;
	cpi	accu3,0		;&lt;br /&gt;
	brge	PosLim1		; &lt;br /&gt;
	ldi	accu3,$80	; accu3 = $80&lt;br /&gt;
	rjmp	Limit1		; &lt;br /&gt;
PosLim1:&lt;br /&gt;
	ldi	accu3,$7F	; accu3 = $7F	&lt;br /&gt;
	com	accu2		; accu2 = $FF	&lt;br /&gt;
	rjmp	Limit1		; &lt;br /&gt;
NoLimit1:&lt;br /&gt;
	lsl	accu1		; Scaling to gain factor 2^16&lt;br /&gt;
	rol	accu2		; &lt;br /&gt;
	rol	accu3		; &lt;br /&gt;
Limit1:&lt;br /&gt;
	std	Y+@0,accu2	; &lt;br /&gt;
	std	Y+@0+1,accu3	; &lt;br /&gt;
.ENDMACRO&lt;br /&gt;
.LISTMAC&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* reset/interrupt-vectors:&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
.cseg&lt;br /&gt;
	rjmp	Initial		; after RESET to main program&lt;br /&gt;
	reti			; External Interrupt Request 0&lt;br /&gt;
	reti			; External Interrupt Request 1&lt;br /&gt;
	reti			; Pin Change Interrupt Request 0&lt;br /&gt;
	reti			; Pin Change Interrupt Request 1&lt;br /&gt;
	reti			; Pin Change Interrupt Request 2&lt;br /&gt;
	reti			; Watchdog Time-out Interrupt&lt;br /&gt;
	reti			; Timer/Counter2 Compare Match A&lt;br /&gt;
	reti			; Timer/Counter2 Compare Match B&lt;br /&gt;
	reti			; Timer/Counter2 Overflow&lt;br /&gt;
	reti			; Timer/Counter1 Capture Event&lt;br /&gt;
	reti			; Timer/Counter1 Compare Match A&lt;br /&gt;
	reti			; Timer/Counter1 Compare Match B&lt;br /&gt;
	reti			; Timer/Counter1 Overflow&lt;br /&gt;
	reti			; Timer/Counter0 Compare Match A&lt;br /&gt;
	reti			; Timer/Counter0 Compare Match B&lt;br /&gt;
	reti			; Timer/Counter0 Overflow&lt;br /&gt;
	reti			; SPI Serial Transfer Complete&lt;br /&gt;
	reti			; USART0, Rx Complete&lt;br /&gt;
	reti			; USART0 Data register Empty&lt;br /&gt;
	reti			; USART0, Tx Complete&lt;br /&gt;
	rjmp	ADCint		; ADC Conversion Complete&lt;br /&gt;
	reti			; EEPROM Ready   &lt;br /&gt;
	reti			; 2-wire Serial Interface&lt;br /&gt;
	reti			; Store Program Memory Read&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* after reset: initialise stack,ports&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
Initial: &lt;br /&gt;
	ldi	tmp1,Low(RAMEND)&lt;br /&gt;
	out	SPL,tmp1	;&lt;br /&gt;
	ldi	tmp1,High(RAMEND)&lt;br /&gt;
	out	SPH,tmp1	; stack initialised&lt;br /&gt;
	clr	zero		; always zero&lt;br /&gt;
	ldi	tmp1,$FF	; &lt;br /&gt;
	out	PortB,tmp1	; PortB = % 1111 1111&lt;br /&gt;
	out	PortC,zero	; PortC = % 0000 0000&lt;br /&gt;
	out	PortD,tmp1	; PortD = % 1111 1111&lt;br /&gt;
	out	DDRB,tmp1	; PortB direction = % 1111 1111&lt;br /&gt;
	out	DDRC,zero	; PortC direction = % 0000 0000&lt;br /&gt;
	out	DDRD,tmp1	; PortD direction = % 1111 1111&lt;br /&gt;
	ldi	tmp1,$A1	; pos. outputs, fast PWM 8Bit&lt;br /&gt;
	sts	TCCR1A,tmp1	;&lt;br /&gt;
	ldi	tmp1,$09	; fast PWM 8Bit, clk/1 (no prescaling)&lt;br /&gt;
	sts	TCCR1B,tmp1	;&lt;br /&gt;
	sts	OCR1AH,zero	;&lt;br /&gt;
	sts	OCR1AL,zero	;&lt;br /&gt;
	sts	OCR1BH,zero	;&lt;br /&gt;
	sts	OCR1BL,zero	;&lt;br /&gt;
	ldi	tmp1,$40	; Ref=Vcc, right-adj, ADC0=input&lt;br /&gt;
	sts	ADMUX,tmp1	;&lt;br /&gt;
	ldi	tmp1,$EE	; Start,Auto, enable Int, Clk/64&lt;br /&gt;
;	ldi	tmp1,$EF	; Start,Auto, enable Int, Clk/128&lt;br /&gt;
	sts	ADCSRA,tmp1	;&lt;br /&gt;
	ldi	tmp1,$00	; free running&lt;br /&gt;
	sts	ADCSRB,tmp1	;&lt;br /&gt;
	ldi	tmp1,$01	; disable ADC0 dig.inp (optional)&lt;br /&gt;
	sts	DIDR0,tmp1	;&lt;br /&gt;
	ldi	ZL,low(CoTblF&amp;lt;&amp;lt;1)	; move filter coefficents&lt;br /&gt;
	ldi	ZH,high(CoTblF&amp;lt;&amp;lt;1)	; from program-flash&lt;br /&gt;
	ldi	YL,low(CoTblS)	; to SRAM&lt;br /&gt;
	ldi	YH,high(CoTblS)	;&lt;br /&gt;
	ldi	tmp1,16		; count 8 * 2-Byte coefficients&lt;br /&gt;
TbLoop:&lt;br /&gt;
	lpm	tmp2,Z+		; fetch 1 byte from coefficient table&lt;br /&gt;
	st	Y+,tmp2		; copy coefficient to Sram, increment Y&lt;br /&gt;
	dec	tmp1&lt;br /&gt;
	brne	TbLoop&lt;br /&gt;
	ldi	YL,low(DatTbl1)	; load SRAM-Pointer for Interrupt routine&lt;br /&gt;
	ldi	YH,high(DatTbl1)	;&lt;br /&gt;
	sei			; enable interrupts&lt;br /&gt;
&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* Main program:&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
Endless:&lt;br /&gt;
	rjmp	Endless		; &lt;br /&gt;
&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* ADC-Interrupt routine: compute filter and update PWM output&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
ADCint:&lt;br /&gt;
	sbi	PortD,0		; just to measure INT-Time&lt;br /&gt;
	in	savsrg,SREG	; save status register&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
&lt;br /&gt;
; allpass 2&lt;br /&gt;
	load_node 	x10	;&lt;br /&gt;
	add_node 	y22	;         y22   +---+ y12 +---+&lt;br /&gt;
	mult_32		k2	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+&lt;br /&gt;
	subtr_node	x22	;          |    +---+     +---+    |&lt;br /&gt;
	limit_store 	y02	;          v                       |&lt;br /&gt;
	load_node 	x12	;   x10  +---+   +---+    +---+    | &lt;br /&gt;
	update_node 	x22	;    o--&amp;gt;| + |--&amp;gt;|*K2|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	load_node 	x10	;    |   +---+   +---+  + +---+   y02&lt;br /&gt;
	update_node 	x12	;    |                    - A&lt;br /&gt;
	lds	datal,ADCL	;    |    +---+     +---+   |&lt;br /&gt;
	lds	datah,ADCH	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o&lt;br /&gt;
	dec	datah		;    |    +---+ x12 +---+  x22&lt;br /&gt;
	dec	datah		;    |&lt;br /&gt;
	lsl	datal		;    +-----------+&lt;br /&gt;
	rol	datah		;         +---+  |&lt;br /&gt;
	lsl	datal		;  ADC &amp;gt;--|1/z|--+&lt;br /&gt;
	rol	datah		;         +---+ &lt;br /&gt;
	lsl	datal		; &lt;br /&gt;
	rol	datah		; &lt;br /&gt;
	lsl	datal		; convert 10 bit unsigned &lt;br /&gt;
	rol	datah		; to 15 Bit signed&lt;br /&gt;
	lsl	datal		; $03FF -&amp;gt; $01FF -&amp;gt; $3FE0&lt;br /&gt;
	rol	datah		; $0000 -&amp;gt; $FE00 -&amp;gt; $C000&lt;br /&gt;
	lsl	datal		;  &lt;br /&gt;
	rol	datah		; &lt;br /&gt;
	update_node 	x10	; save new sample for 2nd allpass-chain&lt;br /&gt;
	load_node 	y12	; &lt;br /&gt;
	update_node 	y22	; &lt;br /&gt;
	load_node 	y02	;&lt;br /&gt;
	update_node 	y12	;&lt;br /&gt;
&lt;br /&gt;
; allpass 4&lt;br /&gt;
	add_node 	y24	;&lt;br /&gt;
	mult_32		k4	;         y24   +---+ y14 +---+&lt;br /&gt;
	subtr_node	x24	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+&lt;br /&gt;
	limit_store 	y04	;          |    +---+     +---+    |&lt;br /&gt;
	load_node 	x14	;          v                       |&lt;br /&gt;
	update_node 	x24	;   y02  +---+   +---+    +---+    | &lt;br /&gt;
	load_node 	y02	;  -&amp;gt;o--&amp;gt;| + |--&amp;gt;|*K4|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	update_node 	x14	;    |   +---+   +---+  + +---+   y04&lt;br /&gt;
	load_node 	y14	;    |                    - A&lt;br /&gt;
	update_node 	y24	;    |    +---+     +---+   |&lt;br /&gt;
	load_node 	y04	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o&lt;br /&gt;
	update_node 	y14	;         +---+ x14 +---+  x24&lt;br /&gt;
&lt;br /&gt;
; allpass 6&lt;br /&gt;
	add_node 	y26	;&lt;br /&gt;
	mult_32		k6	;         y26   +---+ y16 +---+ &lt;br /&gt;
	subtr_node	x26	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+ &lt;br /&gt;
	limit_store 	y06	;          |    +---+     +---+    | &lt;br /&gt;
	load_node 	x16	;          v                       |&lt;br /&gt;
	update_node 	x26	;   y04  +---+   +---+    +---+    | &lt;br /&gt;
	load_node 	y04	;  -&amp;gt;o--&amp;gt;| + |--&amp;gt;|*K6|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	update_node 	x16	;    |   +---+   +---+  + +---+   y06&lt;br /&gt;
	load_node 	y16	;    |                    - A&lt;br /&gt;
	update_node 	y26	;    |    +---+     +---+   |&lt;br /&gt;
	load_node 	y06	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o&lt;br /&gt;
	update_node 	y16	;         +---+ x16 +---+  x26&lt;br /&gt;
&lt;br /&gt;
; allpass 8&lt;br /&gt;
	add_node 	y28	;&lt;br /&gt;
	mult_32		k8	;         y28   +---+ y18 +---+ &lt;br /&gt;
	subtr_node	x28	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+&lt;br /&gt;
	limit_store 	y08	;          |    +---+     +---+    |&lt;br /&gt;
	load_node 	x18	;          v                       |&lt;br /&gt;
	update_node 	x28	;   y06  +---+   +---+    +---+    | &lt;br /&gt;
	load_node 	y06	;  -&amp;gt;o--&amp;gt;| + |--&amp;gt;|*K8|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	update_node 	x18	;    |   +---+   +---+  + +---+   y08&lt;br /&gt;
	load_node 	y18	;    |                    - A&lt;br /&gt;
	update_node 	y28	;    |    +---+     +---+   |&lt;br /&gt;
	load_node 	y08	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o &lt;br /&gt;
	update_node 	y18	;         +---+ x18 +---+  x28 &lt;br /&gt;
	load_node 	x10	;&lt;br /&gt;
	ldi	YL,Low(DatTbl2)	;&lt;br /&gt;
&lt;br /&gt;
; allpass 1&lt;br /&gt;
	add_node 	y21	;&lt;br /&gt;
	mult_32		k1	;         y21   +---+ y11 +---+&lt;br /&gt;
	subtr_node	x21	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+&lt;br /&gt;
	limit_store 	y01	;          |    +---+     +---+    |&lt;br /&gt;
	load_node 	x11	;          v                       |&lt;br /&gt;
	update_node 	x21	;   x10  +---+   +---+    +---+    | &lt;br /&gt;
	load_node 	x10	;  -&amp;gt;o--&amp;gt;| + |--&amp;gt;|*K1|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	update_node 	x11	;    |   +---+   +---+  + +---+   y01&lt;br /&gt;
	load_node 	y11	;    |                    - A&lt;br /&gt;
	update_node 	y21	;    |    +---+     +---+   |&lt;br /&gt;
	load_node 	y01	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o&lt;br /&gt;
	update_node 	y11	;         +---+ x11 +---+  x21&lt;br /&gt;
&lt;br /&gt;
; allpass 3&lt;br /&gt;
	add_node 	y23	;&lt;br /&gt;
	mult_32		k3	;         y23   +---+ y13 +---+&lt;br /&gt;
	subtr_node	x23	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+&lt;br /&gt;
	limit_store 	y03	;          |    +---+     +---+    |&lt;br /&gt;
	load_node 	x13	;          v                       |&lt;br /&gt;
	update_node 	x23	;   y01  +---+   +---+    +---+    | &lt;br /&gt;
	load_node 	y01	;  -&amp;gt;o--&amp;gt;| + |--&amp;gt;|*K3|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	update_node 	x13	;    |   +---+   +---+  + +---+   y03&lt;br /&gt;
	load_node 	y13	;    |                    - A&lt;br /&gt;
	update_node 	y23	;    |    +---+     +---+   |&lt;br /&gt;
	load_node 	y03	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o&lt;br /&gt;
	update_node 	y13	;         +---+ x13 +---+  x23&lt;br /&gt;
&lt;br /&gt;
; allpass 5&lt;br /&gt;
	add_node 	y25	;&lt;br /&gt;
	mult_32		k5	;         y25   +---+ y15 +---+&lt;br /&gt;
	subtr_node	x25	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+&lt;br /&gt;
	limit_store 	y05	;          |    +---+     +---+    |&lt;br /&gt;
	load_node 	x15	;          v                       |&lt;br /&gt;
	update_node 	x25	;   y03  +---+   +---+    +---+    | &lt;br /&gt;
	load_node 	y03	;  -&amp;gt;o--&amp;gt;| + |--&amp;gt;|*K5|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	update_node 	x15	;    |   +---+   +---+  + +---+   y05&lt;br /&gt;
	load_node 	y15	;    |                    - A&lt;br /&gt;
	update_node 	y25	;    |    +---+     +---+   |&lt;br /&gt;
	load_node 	y05	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o&lt;br /&gt;
	update_node 	y15	;         +---+ x15 +---+  x25&lt;br /&gt;
&lt;br /&gt;
; allpass 7&lt;br /&gt;
	add_node 	y27	;&lt;br /&gt;
	mult_32		k7	;         y27   +---+ y17 +---+&lt;br /&gt;
	subtr_node	x27	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+&lt;br /&gt;
	limit_store 	y07	;          |    +---+     +---+    |&lt;br /&gt;
	load_node 	x17	;          v                       |&lt;br /&gt;
	update_node 	x27	;   y05  +---+   +---+    +---+    | &lt;br /&gt;
	load_node 	y05	;  -&amp;gt;o--&amp;gt;| + |--&amp;gt;|*K7|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	update_node 	x17	;    |   +---+   +---+  + +---+   y07&lt;br /&gt;
	load_node 	y17	;    |                    - A&lt;br /&gt;
	update_node 	y27	;    |    +---+     +---+   | &lt;br /&gt;
	load_node 	y07	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o &lt;br /&gt;
	update_node 	y17	;         +---+ x17 +---+  x27&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* PWM - D/A-output&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
; output y07 to PWM-DAC&lt;br /&gt;
&lt;br /&gt;
;test: output y01&lt;br /&gt;
	ldd	accu3, Y+y01+1	;&lt;br /&gt;
;&lt;br /&gt;
	subi	accu3,$80	; signed to unsigned  $8000 -&amp;gt;$0000, $7FFF -&amp;gt;$FFFF&lt;br /&gt;
	sts	OCR1AH,zero	; &lt;br /&gt;
	sts	OCR1AL,accu3	; fast PWM 8 bit y07 output to OCR1A&lt;br /&gt;
	ldi	YL,Low(DatTbl1)	; back to 1st data table&lt;br /&gt;
; output y08 to PWM-DAC&lt;br /&gt;
;	load_node 	y08	; load y08&lt;br /&gt;
&lt;br /&gt;
; test outpt y02&lt;br /&gt;
	load_node 	y02	; load y02&lt;br /&gt;
;&lt;br /&gt;
	subi	datah,$80	; signed to unsigned  $8000 -&amp;gt;$0000, $7FFF -&amp;gt;$FFFF&lt;br /&gt;
	sts	OCR1BH,zero	; &lt;br /&gt;
	sts	OCR1BL,accu3	; fast PWM 8 bit y08 output to OCR1B&lt;br /&gt;
	cbi	PortD,0		; just to measure INT-Time&lt;br /&gt;
	out	SREG,savsrg	; restore status register&lt;br /&gt;
	reti			; &lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* coefficient table in flash memory&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
CoTblF:&lt;br /&gt;
	.dw 	15709 	 	; k2 *32768 (0,4794008655888)&lt;br /&gt;
	.dw 	28712	 	; k4 *32768 (0,8762184935393)&lt;br /&gt;
	.dw 	32001		; k6 *32768 (0,9765975895082)&lt;br /&gt;
	.dw 	32686	 	; k8 *32768 (0,9974992559356)&lt;br /&gt;
	.dw 	 5301	 	; k1 *32768 (0,1617584983677)&lt;br /&gt;
	.dw 	24020		; k3 *32768 (0,7330289323415)&lt;br /&gt;
	.dw 	30977 		; k5 *32768 (0,9453497003291)&lt;br /&gt;
	.dw 	32460	 	; k7 *32768 (0,9905991566845)&lt;br /&gt;
&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* data in SRAM&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
.dseg&lt;br /&gt;
.org	$0100&lt;br /&gt;
DatTbl1:&lt;br /&gt;
	; &amp;quot;allpass&amp;quot; 0&lt;br /&gt;
	.dw 	$0000 	 	; x10&lt;br /&gt;
	; allpass 2&lt;br /&gt;
	.dw 	$0000 	 	; x12&lt;br /&gt;
	.dw 	$0000 	 	; x22&lt;br /&gt;
	.dw 	$0000 	 	; y02&lt;br /&gt;
	.dw 	$0000 	 	; y12&lt;br /&gt;
	.dw 	$0000 	 	; y22&lt;br /&gt;
	; allpass 4&lt;br /&gt;
	.dw 	$0000 	 	; x14&lt;br /&gt;
	.dw 	$0000 	 	; x24&lt;br /&gt;
	.dw 	$0000 	 	; y04&lt;br /&gt;
	.dw 	$0000 	 	; y14&lt;br /&gt;
	.dw 	$0000 	 	; y24&lt;br /&gt;
	; allpass 6&lt;br /&gt;
	.dw 	$0000 	 	; x16&lt;br /&gt;
	.dw 	$0000 	 	; x26&lt;br /&gt;
	.dw 	$0000 	 	; y06&lt;br /&gt;
	.dw 	$0000 	 	; y16&lt;br /&gt;
	.dw 	$0000 	 	; y26&lt;br /&gt;
	; allpass 8&lt;br /&gt;
	.dw 	$0000 	 	; x18&lt;br /&gt;
	.dw 	$0000 	 	; x28&lt;br /&gt;
	.dw 	$0000 	 	; y08&lt;br /&gt;
	.dw 	$0000 	 	; y18&lt;br /&gt;
	.dw 	$0000 	 	; y28&lt;br /&gt;
CoTblS:&lt;br /&gt;
	.dw 	$0000 	 	; k2&lt;br /&gt;
	.dw 	$0000 	 	; k4&lt;br /&gt;
	.dw 	$0000		; k6&lt;br /&gt;
	.dw 	$0000	 	; k8&lt;br /&gt;
DatTbl2:&lt;br /&gt;
	.dw 	$0000	 	; k1&lt;br /&gt;
	.dw 	$0000		; k3&lt;br /&gt;
	.dw 	$0000 		; k5&lt;br /&gt;
	.dw 	$0000	 	; k7&lt;br /&gt;
	; allpass 1&lt;br /&gt;
	.dw 	$0000 	 	; x11&lt;br /&gt;
	.dw 	$0000 	 	; x21&lt;br /&gt;
	.dw 	$0000 	 	; y01&lt;br /&gt;
	.dw 	$0000 	 	; y11&lt;br /&gt;
	.dw 	$0000 	 	; y21&lt;br /&gt;
	; allpass 3&lt;br /&gt;
	.dw 	$0000 	 	; x13&lt;br /&gt;
	.dw 	$0000 	 	; x23&lt;br /&gt;
	.dw 	$0000 	 	; y03&lt;br /&gt;
	.dw 	$0000 	 	; y13&lt;br /&gt;
	.dw 	$0000 	 	; y23&lt;br /&gt;
	; allpass 5&lt;br /&gt;
	.dw 	$0000 	 	; x15&lt;br /&gt;
	.dw 	$0000 	 	; x25&lt;br /&gt;
	.dw 	$0000 	 	; y05&lt;br /&gt;
	.dw 	$0000 	 	; y15&lt;br /&gt;
	.dw 	$0000 	 	; y25&lt;br /&gt;
	; allpass 7&lt;br /&gt;
	.dw 	$0000 	 	; x17&lt;br /&gt;
	.dw 	$0000 	 	; x27&lt;br /&gt;
	.dw 	$0000 	 	; y07&lt;br /&gt;
	.dw 	$0000 	 	; y17&lt;br /&gt;
	.dw 	$0000 	 	; y27&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Kategorie:AVR-Projekte]]&lt;br /&gt;
[[Category:DSP]]&lt;/div&gt;</summary>
		<author><name>Claus w</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Hilbert-Transformator_(Phasenschieber)_mit_ATmega&amp;diff=102904</id>
		<title>Hilbert-Transformator (Phasenschieber) mit ATmega</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Hilbert-Transformator_(Phasenschieber)_mit_ATmega&amp;diff=102904"/>
		<updated>2021-01-09T22:49:14Z</updated>

		<summary type="html">&lt;p&gt;Claus w: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Dieser Artikel ist eine Fortsetzung von [[Digitalfilter mit ATmega]] und behandelt ein spezielles Digitalfilter namens Hilbert-Transformator.&lt;br /&gt;
&lt;br /&gt;
Neben den üblichen Filtern, Tiefpass, Hochpass, Bandpass und Bandsperre, gibt es einige weitere Typen. In der Literatur findet man u.a. noch den Allpass, Phasenschieber, Integrator und Differentiator.&lt;br /&gt;
&lt;br /&gt;
===Der Hilbert-Transformator, ein Breitband-90-Grad-Phasenschieber===&lt;br /&gt;
&lt;br /&gt;
In den Lehrbüchern wird er völlig zu Unrecht eher am Rande abgehandelt. Tatsächlich findet man ihn in allen Schaltungen zur Datenübertragung, zu Modulation oder Demodulation mit I/Q-Mischern, im „Software-defined radio“.&lt;br /&gt;
&lt;br /&gt;
Auch ein Hilbert-Transformator kann mithilfe von Scilab berechnet werden. Allerdings gibt es keine fertige Software, man muss sich durch einige Literatur hindurchfressen, z.&amp;amp;nbsp;B. ISBN 0471619957 Sanjit Mitra, Handbook for DSP (1993), Kapitel „Special Filter Designs“ von [https://web.archive.org/web/20100610031102/http://faculty.cua.edu/regalia/ Phillip Regalia].&lt;br /&gt;
[https://web.itu.edu.tr/hulyayalcin/Signal_Processing_Books/DSP_Applications_Mitra.pdf Matlab-Plots dazu hier ab Seitenzahl 41]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
GNU Octave stellt die Hilbert-Transformation und den Parks-McClellan-hilbert-FIR-Filterentwurf im [http://octave.sourceforge.net/signal/function/remez.html octave-forge Paket &amp;quot;signal&amp;quot;] zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
Eine Fundgrube sind die Matlab-Texte von Prof. Schüssler, die vorab 1998 zum  zweiten Band seines Lehrbuchs auf seiner Webseite veröffentlicht wurden. Inzwischen ist der erste Band in der fünften Auflage erschienen [http://www.springer.com/engineering/signals/book/978-3-540-78250-6 ISBN 9783540782506] , der zweite Band ISBN 9783642011184 2010 erstmalig erschienen,  [http://www.lms.lnt.de/forschung/veroeffentlichungen/buecher/dsv.shtml Software-Download hier] aber die Webseite ist nach seinem Tod 2007 abgeschaltet. Zum Glück gibt es das  &lt;br /&gt;
[http://web.archive.org/web/20041206171820/www.nt.e-technik.uni-erlangen.de/~hws/dsv2programs/index.html  Webarchiv], wo die Texte noch zu finden sind.&lt;br /&gt;
&lt;br /&gt;
Zu dieser Zeit waren die Matlab-Programme noch nicht in „Toolboxen“ untergebracht, deren Funktion von außen nicht mehr sichtbar ist. Daher lassen sie sich relativ einfach in Scilab oder Octave übersetzen.&lt;br /&gt;
&lt;br /&gt;
Vier Versionen von Hilbert-Transformatoren werden hier berechnet: &lt;br /&gt;
* FIR-Hilbert, aufwendig, aber streng linearphasig, der bekannteste Typ, da schon lange mit dem Matlab-Befehl remez / firpm und Parameter &#039;hilbert&#039; berechenbar. Mit dem octave-forge Paket &amp;quot;signal&amp;quot; ist remez mit &amp;quot;hilbert&amp;quot; verfügbar. Scilab kennt diesen Parameter nicht.&lt;br /&gt;
* näherungsweise linearphasiger IIR-Hilbert, maximal flach,&lt;br /&gt;
* näherungsweise linearphasiger IIR-Hilbert, Tschebyscheff &lt;br /&gt;
* minimalphasiger IIR-Hilbert, kompakt, aber mit großen Gruppenlaufzeitschwankungen, eher für Audioanwendungen als Digitalsignale.&lt;br /&gt;
&lt;br /&gt;
Im Artikel von Schüßler/Steffen (siehe unten) sind in zwei vergleichenden Beispielen die Gruppenlaufzeitschwankungen des maximal Flachen etwa halb so groß, des Minimalphasigen etwa fünf Mal so groß wie die Tschbyscheff-Version.&lt;br /&gt;
&lt;br /&gt;
Zumindest der kompakte IIR-Hilbert lässt sich auch in einem ATmega unterbringen. Er besteht aus einer Verzögerung und zwei Allpässen, die wieder aus SOS-Teilfiltern aufgebaut sind. Pro Teilfilter gibt es nur einen Koeffizienten, sodass man mindestens acht Teilfilter verwenden kann.&lt;br /&gt;
&lt;br /&gt;
===Ein Hilbert-Kochrezept (noch unvollständig)===&lt;br /&gt;
&lt;br /&gt;
Folgen wir dem Zahlenbeispiel und Berechnungsweg im „Handbook for DSP“.&lt;br /&gt;
&lt;br /&gt;
Zuerst berechnen wir einen elliptischen &#039;&#039;Halbband&#039;&#039;-Tiefpass. Halbband besagt, dass die beiden Grenzfrequenzen symmetrisch zur halben Nyquist- Frequenz also 0,25 * Abtastfrequenz liegen, siehe Bild oben rechts. Die genauen Bedingungen lauten in der Schreibweise des Buches (&#039;&#039;p&#039;&#039;=passband, &#039;&#039;s&#039;&#039;=stopband):&lt;br /&gt;
* Omega&amp;lt;sub&amp;gt;s&amp;lt;/sub&amp;gt; + Omega&amp;lt;sub&amp;gt;p&amp;lt;/sub&amp;gt; = Pi &amp;lt;br&amp;gt; (auf Omega&amp;lt;sub&amp;gt;sample&amp;lt;/sub&amp;gt; normierte Skala: Samplerate=2*Pi)&lt;br /&gt;
* (1-Delta&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;)&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; +Delta&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;=1&lt;br /&gt;
&lt;br /&gt;
Als Zahlenwerte werden Omega&amp;lt;sub&amp;gt;s&amp;lt;/sub&amp;gt; = 0,55*Pi und Delta&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;=0,01 gewählt, und damit ein elliptischer IIR-Tiefpass 7.Ordnung berechnet.&lt;br /&gt;
Damit erhält er folgende Zahlenwerte der Pole:&lt;br /&gt;
&lt;br /&gt;
 0  0,436688  0,743707 0,927758&lt;br /&gt;
&lt;br /&gt;
===Scilab-Berechnung des Halbbandfilters===&lt;br /&gt;
&lt;br /&gt;
Mit Scilab erhalten wir nach einigem Ausprobieren praktisch dieselben Zahlenwerte, siehe Bild. Die Pole müssten für ein ideales Halbbandfilter genau auf der imaginären Achse liegen, der Realteil genau Null sein (Der Fehler kommt daher, dass die Angabe von f&amp;lt;sub&amp;gt;stop&amp;lt;/sub&amp;gt; vom Programm nicht berücksichtigt wird, das Filter wäre überbestimmt).&lt;br /&gt;
Diese Zahlen werden noch quadriert (&#039;&#039;konjugiert komplexe&#039;&#039; Pole zusammengefasst) und bilden schließlich die Koeffizienten des Hilbert-Transformators.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Halbbandfilter.png|Mit Scilab berechnetes Halbbandfilter 7.Ordnung|640px]]&lt;br /&gt;
&lt;br /&gt;
Die Übertragungsfunktion des gesuchten Hilbert-Transformators soll wie bisher H(z) heißen. Zur Unterscheidung nennen wir die bis jetzt berechnete Tiefpassfunktion G(z). &lt;br /&gt;
&lt;br /&gt;
Wieder wird sie in SOS-Teilfilter aufgeteilt. Hier allerdings in die &amp;lt;u&amp;gt;Summe&amp;lt;/u&amp;gt; von zwei &amp;lt;u&amp;gt;parallel&amp;lt;/u&amp;gt; geschalteten &#039;&#039;Allpass&#039;&#039;-Funktionen A&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; und A&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt; plus eine Verzögerung um einen Sampletakt, in der Übertragungsfunktion als „z&amp;lt;sup&amp;gt;-1&amp;lt;/sup&amp;gt;“ ausgedrückt.&lt;br /&gt;
&lt;br /&gt;
Ein Allpass läßt alle Signalfrequenzen mit unveränderter Amplitude durch, verändert nur die Phase. Seine SOS-Teilfunktion ist besonders einfach aufgebaut, zwei Koeffizienten sind Null, zwei sind gleich Eins und die beiden restlichen identisch. Damit benötigt man nur eine Multiplikation pro Teilfilter.&lt;br /&gt;
&lt;br /&gt;
Die Tiefpass-Übertragungsfunktion erhält so die Form:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;G(z) = ½ * ( A&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; (z&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;) + z&amp;lt;sup&amp;gt;-1&amp;lt;/sup&amp;gt; * A&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt; (z&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;))&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
mit&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
A_{1}(z^{2})=\frac{z^{-2}+0,190696}{1+0,190696\ast z^{-2}}\ast&lt;br /&gt;
{\frac{z^{-2}+0,860735}{1+0,860735\ast z^{-2}}}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
A_{2}(z^{2})=\frac{z^{-2}+0,553100}{1+0,553100\ast z^{-2}}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn man die beiden Ausgänge nicht addiert, sondern subtrahiert, entsteht ein Hochpass gleicher Grenzfrequenz. Beides kombiniert ergibt eine digitale &#039;&#039;Frequenzweiche&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Zum Übergang auf den Hilbert-Transformator ersetzen (&#039;&#039;substituieren&#039;&#039;) wir das z durch -jz und multiplizieren das ganze mit 2:&lt;br /&gt;
&lt;br /&gt;
H(z)= 2*G(-jz)&lt;br /&gt;
  &lt;br /&gt;
&#039;&#039;&#039;H(z) = A&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; (-z&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;) + j* z&amp;lt;sup&amp;gt;-1&amp;lt;/sup&amp;gt; * A&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt; (-z&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
mit&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
A_{1}(-z^{2})=\frac{z^{-2}-0,190696}{1-0,190696\ast z^{-2}}\ast&lt;br /&gt;
{\frac{z^{-2}-0,860735}{1-0,860735\ast z^{-2}}}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
A_{2}(-z^{2})=\frac{z^{-2}-0,553100}{1-0,553100\ast z^{-2}}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie man sieht, ändern sich nur die Vorzeichen. Die Pole liegen aber im Pol-Nullstellendiagramm auf der reellen Achse.&lt;br /&gt;
&lt;br /&gt;
Die Ausgänge der beiden Allpässe sind jetzt gegeneinander um 90 Grad phasenverschoben, und können auf einen I/Q-Modulator gegeben werden. Umgekehrt kann man auch die beiden Eingänge auftrennen, und zwei um 90 Grad versetzte Signale aus einem I/Q-Demodulator einspeisen und die Ausgangssignale addieren oder subtrahieren, je nach gewünschtem Seitenband.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Allpaesse.png]]&lt;br /&gt;
&lt;br /&gt;
Und weil das so gut funktionierte, hier noch die Berechnung des Hilbert-Transformators [http://www.mikrocontroller.net/topic/92630#new von Olli Niemitalo] mit einem Halbband-Tiefpass 17.Ordnung, was zu acht SOS-Teilfiltern führt, dazu folgt unten ein ATmega48-Programm.&lt;br /&gt;
Die originalen URL sind verwaist, aber im Webarchiv noch zu finden:&amp;lt;br&amp;gt;&lt;br /&gt;
https://web.archive.org/web/20070719141658/http://yehar.com/ViewHome.pl?page=dsp/hilbert/ &amp;lt;br&amp;gt;&lt;br /&gt;
https://web.archive.org/web/20070814013543/http://yehar.com/ViewHome.pl?page=dsp/hilbert/011729.html &amp;lt;br&amp;gt;&lt;br /&gt;
Olli ist auch heute (2019) noch aktiv:&amp;lt;br&amp;gt;&lt;br /&gt;
http://yehar.com/blog/&amp;lt;br&amp;gt;&lt;br /&gt;
speziell sein IIR-Hilbert:&amp;lt;br&amp;gt;&lt;br /&gt;
http://yehar.com/blog/?p=368&amp;lt;br&amp;gt;&lt;br /&gt;
Diskussion auch dazu:&amp;lt;br&amp;gt;&lt;br /&gt;
https://dsp.stackexchange.com/questions/37411/iir-hilbert-transformer/59157#59157&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Bild:Halbbandfilter2.png|Halbbandfilter 17.Ordnung|640px]]&lt;br /&gt;
&lt;br /&gt;
===Der näherungsweise linearphasige Hilbert-Transformator===&lt;br /&gt;
&lt;br /&gt;
Er wird im Handbook for DSP auf zwei Seiten sehr kurz abgehandelt. Statt aus zwei Allpässen besteht er aus einem einzigen, im anderen Zweig wird das Signal nur zeitverzögert, was mit einem Ringpuffer wenig Rechenzeit kostet. Eine Zeitverzögerung ist sozusagen die einfachste Form eines Allpasses, damit ist diese Bauform ein Spezialfall der oben gezeigten. Aus Schüsslers Texten erfahren wir noch, dass das Halbband-Tiefpassfilter zur Berechnung hier Tschebyscheff-Charakter haben muß.&lt;br /&gt;
&lt;br /&gt;
Das Zahlenbeispiel zitiert Regalia aus einer anderen Veröffentlichung [http://www.cs.tut.fi/~mr/MRJulk92.html (M. Renfors and T. Saramäki, A class of approximately linear phase digital filters composed of allpass subfilters 1986 ) ] Der Allpass hat neun Koeffizienten, die Zeitverzögerung beträgt 17 Sampletakte. Der Halbband-Tiefpass hat eine Sperrdämpfung von &amp;gt; 49 dB. Sein Frequenzgang und der Phasengang des berechneten Hilbert-Transformators sind als Bild gezeigt.&lt;br /&gt;
&lt;br /&gt;
Zum Allpass gibt es noch folgende Zahlenwerte:&lt;br /&gt;
&lt;br /&gt;
Pole location for A(z)&amp;lt;br&amp;gt;&lt;br /&gt;
z= 	-0.8699928078&amp;lt;br&amp;gt;&lt;br /&gt;
	 0.491194141 ± j0.183666529&amp;lt;br&amp;gt;&lt;br /&gt;
	 0.252724179 ± j0.463085544&amp;lt;br&amp;gt;&lt;br /&gt;
	-0.109950894 ± j0.548611467&amp;lt;br&amp;gt;&lt;br /&gt;
	-0.447326028 ± j0.356810323&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das könnte also ebenfalls noch in einen  ATmega passen.&lt;br /&gt;
&lt;br /&gt;
===Hilbert ohne Multiplizierer===&lt;br /&gt;
&lt;br /&gt;
Eine interessante Variante wird im Artikel [http://kondor.etf.bg.ac.yu/~lutovac/pdf/eusi98lm.pdf Design of multiplierless elliptic IIR halfband filters and Hilbert transformers] vorgestellt. Ähnlich wie im Cordic-Algorithmus für trigonometrische Funktionen werden Multiplikationen vermieden, durch geschickte Wahl der Koeffizienten als Zweierpotenzen.&lt;br /&gt;
&lt;br /&gt;
Die beiden Allpässe des Zahlenbeispiels haben folgende Übertragungsfunktionen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
A_1(z^{-2})&lt;br /&gt;
&amp;amp;=\frac{z^{-2}-0{,}12109375}{1-0{,}12109375 \cdot z^{-2}}&lt;br /&gt;
\cdot\frac{z^{-2}-0{,}6640625}{1-0{,}6640625 \cdot z^{-2}} \\&lt;br /&gt;
&amp;amp;=\frac{z^{-2}-(\frac18 - \frac1{256})}{1-(\frac18 - \frac1{256}) \cdot z^{-2}}&lt;br /&gt;
\cdot\frac{z^{-2}-(\frac12 + \frac18 + \frac1{32} + \frac1{128})}{1-(\frac12 + \frac18 + \frac1{32} + \frac1{128})\cdot z^{-2}}\\&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
A_2(z^{-2})\cdot{z^{-1}}&lt;br /&gt;
&amp;amp;=z^{-1}&lt;br /&gt;
\cdot\frac{z^{-2}-0{,}390625}{1-0{,}390625 \cdot z^{-2}}&lt;br /&gt;
\cdot\frac{z^{-2}-0{,}890625}{1-0{,}890625 \cdot z^{-2}}\\&lt;br /&gt;
&amp;amp;=z^{-1}&lt;br /&gt;
\cdot\frac{z^{-2}-(\frac14 + \frac18 + \frac1{64})}{1-(\frac14 + \frac18 + \frac1{64}) \cdot z^{-2}}&lt;br /&gt;
\cdot\frac{z^{-2}-(1 - \frac18 + \frac1{64})}{1-(1 - \frac18 + \frac1{64}) \cdot z^{-2}}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Hilbert Transormator nach der FIR-Methode ==&lt;br /&gt;
&lt;br /&gt;
Nach dem Additionstheorem ergibt sich aus dem multiplikativen Mischen (u_prod = u_1 * u_2) zweier Wechselspannungen eine Überlagerung (u_sum = u_3 + u_4) zweier anderer Wechelspannungen; die Freqenz der einen Wechselspannung ist die Summe der Frequenzen der Faktor-Spannungen - die Frequenz der anderen Wechselspannung ist die Differenz der Frequenzen der Faktorspannungen. Jeweils eine der beiden Frequenzen ist das Nutz-Signal, die andere Frequenz ist die Spiegelfrequenz.&lt;br /&gt;
&lt;br /&gt;
Der Hilbert-Tranformator ist ein Mittel um nur das Nutzsignal und nicht die Spiegelfrequenz zu mischen. Es wird nach den Regeln der Multiplikation komplexer Zahlen gemischt. Eingabesignal und Mischoszillator müssen in der Form der EULERschen Identität vorliegen: &lt;br /&gt;
&lt;br /&gt;
y = A * exp( j * phi )  = A * ( cos( phi ) + j * sin( phi )  ) ; phi = omega * t ; omega = 2 * pi * f ; f ... Frequenz ; A ... Amplitude ; t ... Zeit&lt;br /&gt;
&lt;br /&gt;
Mit der exp() - Darstellung kann man mischen, indem man den Ausdruck phi = 2 * pi * t * (f1 + f2) anwendet. Dabei addieren sich die Frequenzen ohne Spiegelfrequenz. Beide Frequenzen müssen als komplexe Zahlen vorliegen, also jede Frequenz als zwei Wechselspannungen mit (jeweils pro Frequenz) gleicher Amplitude. Liegt nur ein einfaches Sinus-Signal vor, kann man das dazugehörige Cosinus-Signal durch Phasenverschiebung um 90° mit einem Hilbert-Transformator erreichen. Danach wendet man die Multiplikation an:&lt;br /&gt;
&lt;br /&gt;
y[ re, j * im ]:= x1[ re, j * im ]* x2[ re, j * im ] = (x1.re * x2.re - x1.im * x2.im) + j * (x1.re * x2.im + x2.re * x1.im) ; re ... Realteil ; im ... Imag. Teil&lt;br /&gt;
&lt;br /&gt;
Jedes Glied des einen Faktors mit jedem Glied des anderen Faktors unter Beachtung der imaginären Einheit multiplizieren. Wendet man bei dem Signal einer der beiden Frequenzen nur einen der beiden Anteile (entweder nur realen Cosinus-Teil oder imaginären Sinusteil) so entsteht eine &amp;quot;negative&amp;quot; Frequenz (der Zeiger in der komplexen Zahlenebene dreht sich andersherum). Somit wird diese Frequenz von der anderen subtrahiert (phi = 2 * pi * t * (f1 - f2)). Das kann sowohl rechnerisch als auch durch Umpolen einer Bandfilterwicklung errreicht werden. Für Zwischenergebnisse nutzt man beide Signalteile weiter, für z.B. eine Audioausgabe genügt einer.&lt;br /&gt;
&lt;br /&gt;
Kann man zu einem Sinussignal das Cosinus-Signal auch ohne synthetisches Filter erhalten? Genau weiß ich es nicht. Für einen Oszillator braucht man mindestens zwei Energiespeicher. Beide sind (wenn es kein Drehstromoszillator ist) um 90° phasenverschoben. Hier kommt man ohne synthetisches Filter aus. Anders bei Schallwellen. Der eine Speicher besteht hier sowohl aus Schalldruck als auch aus Schallschnelle. Sind beide um 0° phasenverschoben, so bewegt sich die Welle in die eine Richtung, bei 180° entsprechend entgegengesetzt. Der andere Speicher ist die 1. Ableitung von jeweils Schalldruck und Schallschnelle. Die Ableitung ist um 90° phasenverschoben aber bei frequenzabhängiger Amplitude ( y = A * sin( omega * t ) ; y&#039; = omega * A * cos( omega * t ) ). Ohne Spiegelfrequenz kann man das nur für eine feste Frequenz mischen. Bei einem Frequenzband braucht man das synthetische Filter.&lt;br /&gt;
&lt;br /&gt;
Der Hilbert-Transformator erzeugt aus einem Sinus-Signal das um 90° verschobene Cosinus-Signal. Ein Beispiel in Python:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Begin Hilbert FIR filter.&lt;br /&gt;
import math # Math&lt;br /&gt;
import numpy as np # Math&lt;br /&gt;
import matplotlib as mlp # Plot&lt;br /&gt;
import matplotlib.pyplot as plt # Plot&lt;br /&gt;
&lt;br /&gt;
FREQUENCY = 400.0 # 1 / s&lt;br /&gt;
RATE = 48000.0 # samples / s&lt;br /&gt;
SAMPLES = 4000&lt;br /&gt;
CELLS = 501&lt;br /&gt;
STEPS = SAMPLES - CELLS&lt;br /&gt;
PREFIX = (CELLS - 1) / 2&lt;br /&gt;
SUFFIX = CELLS - PREFIX&lt;br /&gt;
POSTFIX = SAMPLES - CELLS&lt;br /&gt;
&lt;br /&gt;
samples = range(SAMPLES)&lt;br /&gt;
cells = range(CELLS)&lt;br /&gt;
steps = range(STEPS)&lt;br /&gt;
prefixes = range(PREFIX)&lt;br /&gt;
suffixes = range(SUFFIX)&lt;br /&gt;
postfixes = range(POSTFIX)&lt;br /&gt;
&lt;br /&gt;
input = []&lt;br /&gt;
re = []&lt;br /&gt;
im = []&lt;br /&gt;
coefficients = []&lt;br /&gt;
&lt;br /&gt;
def plot():&lt;br /&gt;
&lt;br /&gt;
	for sample in samples:&lt;br /&gt;
		if(SAMPLES / 2 &amp;gt; sample):&lt;br /&gt;
			_phi = FREQUENCY * sample / RATE * 2.0 * math.pi&lt;br /&gt;
		else:&lt;br /&gt;
			_phi = 5 * FREQUENCY * sample / RATE * 2.0 * math.pi&lt;br /&gt;
		input.append(math.sin(_phi))&lt;br /&gt;
&lt;br /&gt;
	for cell in cells:&lt;br /&gt;
		arg = cell - (CELLS - 1) / 2.0&lt;br /&gt;
		if(0.0 == arg):&lt;br /&gt;
			coefficients.append(0.0)&lt;br /&gt;
		else:&lt;br /&gt;
			arg *= math.pi&lt;br /&gt;
			coefficients.append((1.0 - math.cos(arg)) / arg)&lt;br /&gt;
	&lt;br /&gt;
	for postfix in postfixes:&lt;br /&gt;
		coefficients.append(0.0)&lt;br /&gt;
	&lt;br /&gt;
	for prefix in prefixes:&lt;br /&gt;
		re.append(0.0)&lt;br /&gt;
		im.append(0.0)&lt;br /&gt;
		&lt;br /&gt;
	for step in steps:&lt;br /&gt;
		re.append(input[step + PREFIX])&lt;br /&gt;
		sum = 0.0&lt;br /&gt;
		for cell in cells:&lt;br /&gt;
			sum += input[step + cell] * coefficients[cell];&lt;br /&gt;
		im.append(sum)&lt;br /&gt;
		&lt;br /&gt;
	for suffix in suffixes:&lt;br /&gt;
		re.append(0.0)&lt;br /&gt;
		im.append(0.0)&lt;br /&gt;
	&lt;br /&gt;
	# Prepare the plot.&lt;br /&gt;
	plt.ylabel(&#039;amplitude&#039;)&lt;br /&gt;
	plt.xlabel(&#039;timesteps&#039;)&lt;br /&gt;
	plt.axis([0, SAMPLES - 1, -1.5, 1.5])&lt;br /&gt;
	plt.grid(True)&lt;br /&gt;
	plt.plot(samples, re, &#039;r-&#039;)&lt;br /&gt;
	plt.plot(samples, im, &#039;b-&#039;)&lt;br /&gt;
	plt.show()&lt;br /&gt;
# End.&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
Neben ein Array aus abgetasteten Werten eines akustischen Signales (hier Sinus-Signal, künstlich berechnet) wird das Array des Transformationskerns gelegt. Das Array des Transformationskerns ist dabei viel kürzer und es wird nur der gemeinsame Bereich berechnet. Der Wert des Cosinus-Signals, das zu dem Sinus-Signal gehört, das sich auf der Position der Mitte des Transformationskerns befindet, ergibt sich aus der Summe der Werte aus dem Sinus-Signal multiplizert mit den Faktoren aus dem Transformationskern mit gleichem Index. Das folgende Cosinus-Signal wird berechnet indem man zuvor den Transformationskern um einen Index gegenüber dem Eingabe-Sinus-Signal weiterschiebt (usw. bis zum Ende des Signales). Am Anfang und am Ende des berechneten Cosinus-Signales entsteht ein Stück Verlust der jeweils halb so lang wie der Transformationskern ist. Bei sehr lang dauernden Signalen (fast immer) ist statt dessen mit einem Ringpuffer zu arbeiten.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
t ... Zeit&lt;br /&gt;
b[Länge k] ... Transformationskern&lt;br /&gt;
i[undendlich lang] ... Sinus - Signal oder Summe aus Sinus-Signalen&lt;br /&gt;
o[undendlich lang] ... um 90° verschobenes Cosinus - Signal&lt;br /&gt;
=&amp;gt;&lt;br /&gt;
o[t] := Summe { i[n+t] * b[n+t] } ; -k/2 &amp;lt;= n &amp;lt;= +k/2 ; i &amp;gt;= k/2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Der Transformationskern kann wie folgt ermittelt werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x ... natürliche Zahl &amp;gt; 0&lt;br /&gt;
k ... 4 * x + 1&lt;br /&gt;
b[] ... Transformationskern der Länge k&lt;br /&gt;
n ... Index innerhalb des Tranformationskerns&lt;br /&gt;
pi ... 3.14159...&lt;br /&gt;
b[n] := ( 1 - cos( n * pi ) ) / ( n * pi ) ; Ausnahme ist b[0] := 0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Datei:FIR_Kernel_Small.png|200px|thumb|right|Hilbert Transformationskern klein]]&lt;br /&gt;
&lt;br /&gt;
Dabei ist das Argument der cos() - Funktion immer ganzzahlig. &amp;quot;1 - cos(...)&amp;quot; ist für ungerade &amp;quot;n&amp;quot; immer NULL. Der Kern hat nahe n == 0 maximale Werte und nimmt zum Rand hin ab. Ein Kern mit zuwenig Länge (k ist zu klein) wirkt als Hochpass und verkleinert die Amplitude von Signalen kleiner Frequenz (ist unbrauchbar). Kommen hohe und tiefe Frequenzen im Signal gleichzeitig vor, dann braucht man sowohl eine hohe Abtastrate als auch einen langen Kern ( k wird groß, z.B. Größenordnung 801 bei einem Audiosignal). Ändert sich das Nutzsignal unerwartet sprungartig so erhält man im Cosinus-Signal eine Art Sprungantwort.&lt;br /&gt;
&lt;br /&gt;
* Großer Transformationskern : [[Medium:FIR_Kernel_Big.png]]&lt;br /&gt;
* Transformation zweier Signale verschiedener Frequenz : [[Medium:Hilber_FIR_OK.png]]&lt;br /&gt;
* Transformation eines Sprunges im Signal : [[Medium:Hilbert_FIR_OK_Lense.png]]&lt;br /&gt;
* Transformationsfehler bei zu kleinem Kern (k ist zu klein) :  [[Medium:Hilbert_FIR_Too_Small_Kernel.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Zusammenfassung&amp;lt;/b&amp;gt;&lt;br /&gt;
Hilbert-Transformation ermittelt zu einem Sinus-Signal das um 90° verschobene Cosinus-Signal. Das gilt auch für eine Summe von Sinussignalen unterschiedlicher Frequenzen und Amplituden. Die Amplitude des Cosinus-Signales ist gleich der Amplitude des Sinus-Signales (kann geringfügig abweichen aber korrigiert werden). Das Transformieren erfolgt meist synthetisch, z.B. in digitalen Signal Prozessoren. Die Hilbert-Transformation wird verwendet, wenn man Sinus-Signal und Cosinus-Signal benötigt aber nur das Sinus-Signal vorliegt. Beide Signale (sin(...) und cos(...)) zusammen entsprechen einer Folge komplexer Zahlen. Damit kann man multiplikativ mischen ohne Spiegelfrequenz. Liegen beide Faktoren der Mischung als komplexe Zahlen vor, kann man jedes Glied der einen Zahl mit jedem Glied der anderen Zahl multiplizieren unter Beachtung der komplexen Einheit &amp;quot;j&amp;quot;. Falls man sich dabei beide Faktoren jedoch in der exp( j * omega * t ) Schreibweise denkt, so multipliziert man statt dessen Potenzen, indem man die Exponenten addiert. Für eine Berechnung braucht man 4 Multiplikationen, was entweder digital erfolgen kann oder im analogen Fall vier Mischer (z.B. Ringmischer oder Gilbertzellen) benötigt, wenn man das ganze Ergebnis braucht. Der Transformationskern ist ein Array aus Zahlen deren Werte in der Mitte des Arrays groß sind und zum Rand hin abnehmen. &lt;br /&gt;
&lt;br /&gt;
==Weitere Literatur zu Hilbert==&lt;br /&gt;
* Schüssler / [http://www.lnt.de/LMS/staff/index.php?lang=de&amp;amp;function=1&amp;amp;person=5 Steffen] &amp;quot;Halfband Filters and Hilbert Transformers&amp;quot; &amp;lt;br&amp;gt; Irgendwo im Web hatte ich den vollständigen Artikel als PDF gefunden, leider die Adresse nicht notiert, Google findet nur [http://www.springerlink.com/content/p5480n6p8t73t633/ kostenpflichtige Downloads].&lt;br /&gt;
* Dutta / Kumar [http://eprint.iitd.ac.in/dspace/bitstream/2074/1608/1/roydig1989.pdf On Digital Differentiators, Hilbert Transformers, and Half-Band Low-Pass Filters] &amp;lt;br&amp;gt; dank Schrifterkennungsprogramm leicht lädiert&lt;br /&gt;
* Miroslav Lutovac / Ljiljana Milic [http://www.telfor.rs/telfor2000/radovi/7-10.pdf Half-band IIR Filter Design Using Matlab],  [http://kondor.etf.bg.ac.yu/~lutovac/confer.htm weitere Artikel der Autoren]&lt;br /&gt;
* Göckler / Damjanovic [http://www.dsv.rub.de/imperia/md/content/public/wsr06_goecklerdamjanovic.pdf A Family of Efficient Complex Halfband Filters]&lt;br /&gt;
&lt;br /&gt;
==ATmega-Programm Hilbert-Transformer ( fast fertig, schwingt leider)==&lt;br /&gt;
Da der Adressenbereich des ATmega nicht groß genug ist, wird die Tabelle im SRAM in zwei Hälften geteilt.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;* Hilbert transformer with ATmega48P, 90 degree broadband phase shifter   *&lt;br /&gt;
;* 15 MHz xtal, input ADC0, PWM-output OCR1a/b, test output PD0            *&lt;br /&gt;
;* Christoph Kessler 2008                         db1uq_at_t-online_dot_de *&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
.nolist&lt;br /&gt;
.include &amp;quot;m48pdef.inc&amp;quot;&lt;br /&gt;
.list&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;* register 0-15 (no &amp;quot;immediate&amp;quot;-operations possible):&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
.def	mult_l	= r0	; multiplier result&lt;br /&gt;
.def	mult_h	= r1	; multiplier result&lt;br /&gt;
.def	zero	= r2	; zero register (used to add carry flag)&lt;br /&gt;
.def	savsrg	= r3	; save status register during interrupt routine&lt;br /&gt;
.def	reg04	= r4	; free&lt;br /&gt;
.def	reg05	= r5	; free&lt;br /&gt;
.def	reg06	= r6	; free&lt;br /&gt;
.def	reg07	= r7	; free&lt;br /&gt;
.def	reg08	= r8	; free&lt;br /&gt;
.def	reg09	= r9	; free&lt;br /&gt;
.def	reg10	= r10	; free&lt;br /&gt;
.def	reg11	= r11	; free&lt;br /&gt;
.def	reg12	= r12	; free&lt;br /&gt;
.def	accu0	= r13	; Accumulator - 32bit for Interrupt routine&lt;br /&gt;
.def	accu1	= r14	; Accumulator - 32bit for Interrupt routine&lt;br /&gt;
.def	accu2	= r15	; Accumulator - 32bit for Interrupt routine&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;* register 16-23 (&amp;quot;immediate&amp;quot;-operations possible):&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
.def	accu3	= r16	; Accumulator - 32bit for Interrupt routine&lt;br /&gt;
.def	reg17	= r17	; free&lt;br /&gt;
.def	reg18	= r18	; free&lt;br /&gt;
.def	reg19	= r19	; free&lt;br /&gt;
.def	datal	= r20	; Data samples mul register&lt;br /&gt;
.def	datah	= r21	;  for Interrupt routine&lt;br /&gt;
.def	coefl	= r22	; Filter coefficient mul register&lt;br /&gt;
.def	coefh	= r23	;  for Interrupt routine&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;* register 24-31    (16Bit-registers) &lt;br /&gt;
;***************************************************************************&lt;br /&gt;
.def	tmp1	= r24	; general temporary register&lt;br /&gt;
.def	tmp2	= r25	; general temporary register&lt;br /&gt;
;	XL	= r26	; free&lt;br /&gt;
;	XH	= r27	; free&lt;br /&gt;
;	YL	= r28	; used by Interrupt routine&lt;br /&gt;
;	YH	= r29	; used by Interrupt routine&lt;br /&gt;
;	ZL	= r30	; init routine only, free for main program&lt;br /&gt;
;	ZH	= r31	; init routine only, free for main program&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* constants :&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;1st table:&lt;br /&gt;
	;&amp;quot;allpass&amp;quot;0:&lt;br /&gt;
.equ	 x10	= 0&lt;br /&gt;
	; allpass 2:&lt;br /&gt;
.equ	 x12	= 2&lt;br /&gt;
.equ	 x22	= 4&lt;br /&gt;
.equ	 y02	= 6&lt;br /&gt;
.equ	 y12	= 8&lt;br /&gt;
.equ	 y22	= 10&lt;br /&gt;
	; allpass 4:&lt;br /&gt;
.equ	 x14	= 12&lt;br /&gt;
.equ	 x24	= 14&lt;br /&gt;
.equ	 y04	= 16&lt;br /&gt;
.equ	 y14	= 18&lt;br /&gt;
.equ	 y24	= 20&lt;br /&gt;
	; allpass 6:&lt;br /&gt;
.equ	 x16	= 22&lt;br /&gt;
.equ	 x26	= 24&lt;br /&gt;
.equ	 y06	= 26&lt;br /&gt;
.equ	 y16	= 28&lt;br /&gt;
.equ	 y26	= 30&lt;br /&gt;
	; allpass 8:&lt;br /&gt;
.equ	 x18	= 32&lt;br /&gt;
.equ	 x28	= 34&lt;br /&gt;
.equ	 y08	= 36&lt;br /&gt;
.equ	 y18	= 38&lt;br /&gt;
.equ	 y28	= 40&lt;br /&gt;
&lt;br /&gt;
.equ	 k2	= 42&lt;br /&gt;
.equ	 k4	= 44&lt;br /&gt;
.equ	 k6	= 46&lt;br /&gt;
.equ	 k8	= 48&lt;br /&gt;
;2nd table:&lt;br /&gt;
.equ	 k1	= 0&lt;br /&gt;
.equ	 k3	= 2&lt;br /&gt;
.equ	 k5	= 4&lt;br /&gt;
.equ	 k7	= 6&lt;br /&gt;
	; allpass 1:&lt;br /&gt;
.equ	 x11	= 8&lt;br /&gt;
.equ	 x21	= 10&lt;br /&gt;
.equ	 y01	= 12&lt;br /&gt;
.equ	 y11	= 14&lt;br /&gt;
.equ	 y21	= 16&lt;br /&gt;
	; allpass 3:&lt;br /&gt;
.equ	 x13	= 18&lt;br /&gt;
.equ	 x23	= 20&lt;br /&gt;
.equ	 y03	= 22&lt;br /&gt;
.equ	 y13	= 24&lt;br /&gt;
.equ	 y23	= 26&lt;br /&gt;
	; allpass 5:&lt;br /&gt;
.equ	 x15	= 28&lt;br /&gt;
.equ	 x25	= 30&lt;br /&gt;
.equ	 y05	= 32&lt;br /&gt;
.equ	 y15	= 34&lt;br /&gt;
.equ	 y25	= 36&lt;br /&gt;
	; allpass 7:&lt;br /&gt;
.equ	 x17	= 38&lt;br /&gt;
.equ	 x27	= 40&lt;br /&gt;
.equ	 y07	= 42&lt;br /&gt;
.equ	 y17	= 44&lt;br /&gt;
.equ	 y27	= 46&lt;br /&gt;
;*****************************************************&lt;br /&gt;
;* Macros&lt;br /&gt;
;*****************************************************&lt;br /&gt;
.MACRO load_node&lt;br /&gt;
	ldd	datal,Y+@0	; Load low byte of node &lt;br /&gt;
	ldd	datah,Y+@0+1	; Load high byte of node&lt;br /&gt;
.ENDMACRO&lt;br /&gt;
.MACRO update_node&lt;br /&gt;
	std	Y+@0,datal	; Store low byte of node &lt;br /&gt;
	std	Y+@0+1,datah	; Store high byte of node&lt;br /&gt;
.ENDMACRO&lt;br /&gt;
.MACRO add_node&lt;br /&gt;
	ldd	coefl,Y+@0	; Load 2nd node low&lt;br /&gt;
	ldd	coefh,Y+@0+1	; Load 2nd node high&lt;br /&gt;
	add	datal,coefl	; Add low bytes&lt;br /&gt;
	adc	datah,coefh	; Add with carry high bytes&lt;br /&gt;
.ENDMACRO&lt;br /&gt;
.MACRO mult_32&lt;br /&gt;
	ldd	coefl,Y+@0	; Load low byte of coefficient&lt;br /&gt;
	ldd	coefh,Y+@0+1	; Load high byte of coefficient&lt;br /&gt;
	muls	coefh,datah	; Signed multiply, coefficient high byte and data high byte&lt;br /&gt;
	mov     accu2,mult_l	; Copy result word into accumulator byte 2:3&lt;br /&gt;
	mov     accu3,mult_h	; Copy result word into accumulator byte 2:3&lt;br /&gt;
	mul	coefl,datal	; Unsigned multiply, coefficient low byte and data low byte&lt;br /&gt;
	mov	accu0,mult_l	; Copy result word into accumulator byte 2:3&lt;br /&gt;
	mov	accu1,mult_h	; Copy result word into accumulator byte 2:3&lt;br /&gt;
	mulsu	coefh,datal	; Signed-unsigned multiply, coefficient high byte and data low byte&lt;br /&gt;
	sbc	accu3,zero	; Sign extention&lt;br /&gt;
	add	accu1,mult_l	; Add low byte of result to accumulator byte 1&lt;br /&gt;
	adc	accu2,mult_h	; Add with carry high byte of result to accumulator byte 2&lt;br /&gt;
	adc	accu3,zero	; Add carry to accumulator byte 3&lt;br /&gt;
	mulsu	datah,coefl	; Signed-unsigned multiply, data high byte and coefficient low byte&lt;br /&gt;
	sbc	accu3,zero	; Sign extention&lt;br /&gt;
	add	accu1,mult_l	; Add low byte of result to accumulator byte 1&lt;br /&gt;
	adc	accu2,mult_h	; Add with carry high byte of result to accumulator byte 2&lt;br /&gt;
	adc	accu3,zero	; Add carry to accumulator byte 3&lt;br /&gt;
.ENDMACRO&lt;br /&gt;
.MACRO subtr_node&lt;br /&gt;
	ldd	datal,Y+@0	; Load 2nd node low&lt;br /&gt;
	ldd	datah,Y+@0+1	; Load 2nd node high&lt;br /&gt;
	sub	accu0,datal	; Subtract low byte&lt;br /&gt;
	sbc	accu1,datah	; Subtract with carry high byte&lt;br /&gt;
	sbc	accu2,zero	;&lt;br /&gt;
	sbc	accu3,zero	;&lt;br /&gt;
.ENDMACRO&lt;br /&gt;
.MACRO limit_store&lt;br /&gt;
	cpi	accu3,$40	; accu &amp;lt;   $40000000 ?&lt;br /&gt;
	brlo	NoLimit1	;&lt;br /&gt;
	cpi	accu3,-$40	; accu &amp;gt;= -$40000000 ?&lt;br /&gt;
	brsh	NoLimit1	;&lt;br /&gt;
	clr	accu2		; accu2 = $00&lt;br /&gt;
	cpi	accu3,0		;&lt;br /&gt;
	brge	PosLim1		; &lt;br /&gt;
	ldi	accu3,$80	; accu3 = $80&lt;br /&gt;
	rjmp	Limit1		; &lt;br /&gt;
PosLim1:&lt;br /&gt;
	ldi	accu3,$7F	; accu3 = $7F	&lt;br /&gt;
	com	accu2		; accu2 = $FF	&lt;br /&gt;
	rjmp	Limit1		; &lt;br /&gt;
NoLimit1:&lt;br /&gt;
	lsl	accu1		; Scaling to gain factor 2^16&lt;br /&gt;
	rol	accu2		; &lt;br /&gt;
	rol	accu3		; &lt;br /&gt;
Limit1:&lt;br /&gt;
	std	Y+@0,accu2	; &lt;br /&gt;
	std	Y+@0+1,accu3	; &lt;br /&gt;
.ENDMACRO&lt;br /&gt;
.LISTMAC&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* reset/interrupt-vectors:&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
.cseg&lt;br /&gt;
	rjmp	Initial		; after RESET to main program&lt;br /&gt;
	reti			; External Interrupt Request 0&lt;br /&gt;
	reti			; External Interrupt Request 1&lt;br /&gt;
	reti			; Pin Change Interrupt Request 0&lt;br /&gt;
	reti			; Pin Change Interrupt Request 1&lt;br /&gt;
	reti			; Pin Change Interrupt Request 2&lt;br /&gt;
	reti			; Watchdog Time-out Interrupt&lt;br /&gt;
	reti			; Timer/Counter2 Compare Match A&lt;br /&gt;
	reti			; Timer/Counter2 Compare Match B&lt;br /&gt;
	reti			; Timer/Counter2 Overflow&lt;br /&gt;
	reti			; Timer/Counter1 Capture Event&lt;br /&gt;
	reti			; Timer/Counter1 Compare Match A&lt;br /&gt;
	reti			; Timer/Counter1 Compare Match B&lt;br /&gt;
	reti			; Timer/Counter1 Overflow&lt;br /&gt;
	reti			; Timer/Counter0 Compare Match A&lt;br /&gt;
	reti			; Timer/Counter0 Compare Match B&lt;br /&gt;
	reti			; Timer/Counter0 Overflow&lt;br /&gt;
	reti			; SPI Serial Transfer Complete&lt;br /&gt;
	reti			; USART0, Rx Complete&lt;br /&gt;
	reti			; USART0 Data register Empty&lt;br /&gt;
	reti			; USART0, Tx Complete&lt;br /&gt;
	rjmp	ADCint		; ADC Conversion Complete&lt;br /&gt;
	reti			; EEPROM Ready   &lt;br /&gt;
	reti			; 2-wire Serial Interface&lt;br /&gt;
	reti			; Store Program Memory Read&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* after reset: initialise stack,ports&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
Initial: &lt;br /&gt;
	ldi	tmp1,Low(RAMEND)&lt;br /&gt;
	out	SPL,tmp1	;&lt;br /&gt;
	ldi	tmp1,High(RAMEND)&lt;br /&gt;
	out	SPH,tmp1	; stack initialised&lt;br /&gt;
	clr	zero		; always zero&lt;br /&gt;
	ldi	tmp1,$FF	; &lt;br /&gt;
	out	PortB,tmp1	; PortB = % 1111 1111&lt;br /&gt;
	out	PortC,zero	; PortC = % 0000 0000&lt;br /&gt;
	out	PortD,tmp1	; PortD = % 1111 1111&lt;br /&gt;
	out	DDRB,tmp1	; PortB direction = % 1111 1111&lt;br /&gt;
	out	DDRC,zero	; PortC direction = % 0000 0000&lt;br /&gt;
	out	DDRD,tmp1	; PortD direction = % 1111 1111&lt;br /&gt;
	ldi	tmp1,$A1	; pos. outputs, fast PWM 8Bit&lt;br /&gt;
	sts	TCCR1A,tmp1	;&lt;br /&gt;
	ldi	tmp1,$09	; fast PWM 8Bit, clk/1 (no prescaling)&lt;br /&gt;
	sts	TCCR1B,tmp1	;&lt;br /&gt;
	sts	OCR1AH,zero	;&lt;br /&gt;
	sts	OCR1AL,zero	;&lt;br /&gt;
	sts	OCR1BH,zero	;&lt;br /&gt;
	sts	OCR1BL,zero	;&lt;br /&gt;
	ldi	tmp1,$40	; Ref=Vcc, right-adj, ADC0=input&lt;br /&gt;
	sts	ADMUX,tmp1	;&lt;br /&gt;
	ldi	tmp1,$EE	; Start,Auto, enable Int, Clk/64&lt;br /&gt;
;	ldi	tmp1,$EF	; Start,Auto, enable Int, Clk/128&lt;br /&gt;
	sts	ADCSRA,tmp1	;&lt;br /&gt;
	ldi	tmp1,$00	; free running&lt;br /&gt;
	sts	ADCSRB,tmp1	;&lt;br /&gt;
	ldi	tmp1,$01	; disable ADC0 dig.inp (optional)&lt;br /&gt;
	sts	DIDR0,tmp1	;&lt;br /&gt;
	ldi	ZL,low(CoTblF&amp;lt;&amp;lt;1)	; move filter coefficents&lt;br /&gt;
	ldi	ZH,high(CoTblF&amp;lt;&amp;lt;1)	; from program-flash&lt;br /&gt;
	ldi	YL,low(CoTblS)	; to SRAM&lt;br /&gt;
	ldi	YH,high(CoTblS)	;&lt;br /&gt;
	ldi	tmp1,16		; count 8 * 2-Byte coefficients&lt;br /&gt;
TbLoop:&lt;br /&gt;
	lpm	tmp2,Z+		; fetch 1 byte from coefficient table&lt;br /&gt;
	st	Y+,tmp2		; copy coefficient to Sram, increment Y&lt;br /&gt;
	dec	tmp1&lt;br /&gt;
	brne	TbLoop&lt;br /&gt;
	ldi	YL,low(DatTbl1)	; load SRAM-Pointer for Interrupt routine&lt;br /&gt;
	ldi	YH,high(DatTbl1)	;&lt;br /&gt;
	sei			; enable interrupts&lt;br /&gt;
&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* Main program:&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
Endless:&lt;br /&gt;
	rjmp	Endless		; &lt;br /&gt;
&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* ADC-Interrupt routine: compute filter and update PWM output&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
ADCint:&lt;br /&gt;
	sbi	PortD,0		; just to measure INT-Time&lt;br /&gt;
	in	savsrg,SREG	; save status register&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
&lt;br /&gt;
; allpass 2&lt;br /&gt;
	load_node 	x10	;&lt;br /&gt;
	add_node 	y22	;         y22   +---+ y12 +---+&lt;br /&gt;
	mult_32		k2	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+&lt;br /&gt;
	subtr_node	x22	;          |    +---+     +---+    |&lt;br /&gt;
	limit_store 	y02	;          v                       |&lt;br /&gt;
	load_node 	x12	;   x10  +---+   +---+    +---+    | &lt;br /&gt;
	update_node 	x22	;    o--&amp;gt;| + |--&amp;gt;|*K2|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	load_node 	x10	;    |   +---+   +---+  + +---+   y02&lt;br /&gt;
	update_node 	x12	;    |                    - A&lt;br /&gt;
	lds	datal,ADCL	;    |    +---+     +---+   |&lt;br /&gt;
	lds	datah,ADCH	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o&lt;br /&gt;
	dec	datah		;    |    +---+ x12 +---+  x22&lt;br /&gt;
	dec	datah		;    |&lt;br /&gt;
	lsl	datal		;    +-----------+&lt;br /&gt;
	rol	datah		;         +---+  |&lt;br /&gt;
	lsl	datal		;  ADC &amp;gt;--|1/z|--+&lt;br /&gt;
	rol	datah		;         +---+ &lt;br /&gt;
	lsl	datal		; &lt;br /&gt;
	rol	datah		; &lt;br /&gt;
	lsl	datal		; convert 10 bit unsigned &lt;br /&gt;
	rol	datah		; to 15 Bit signed&lt;br /&gt;
	lsl	datal		; $03FF -&amp;gt; $01FF -&amp;gt; $3FE0&lt;br /&gt;
	rol	datah		; $0000 -&amp;gt; $FE00 -&amp;gt; $C000&lt;br /&gt;
	lsl	datal		;  &lt;br /&gt;
	rol	datah		; &lt;br /&gt;
	update_node 	x10	; save new sample for 2nd allpass-chain&lt;br /&gt;
	load_node 	y12	; &lt;br /&gt;
	update_node 	y22	; &lt;br /&gt;
	load_node 	y02	;&lt;br /&gt;
	update_node 	y12	;&lt;br /&gt;
&lt;br /&gt;
; allpass 4&lt;br /&gt;
	add_node 	y24	;&lt;br /&gt;
	mult_32		k4	;         y24   +---+ y14 +---+&lt;br /&gt;
	subtr_node	x24	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+&lt;br /&gt;
	limit_store 	y04	;          |    +---+     +---+    |&lt;br /&gt;
	load_node 	x14	;          v                       |&lt;br /&gt;
	update_node 	x24	;   y02  +---+   +---+    +---+    | &lt;br /&gt;
	load_node 	y02	;  -&amp;gt;o--&amp;gt;| + |--&amp;gt;|*K4|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	update_node 	x14	;    |   +---+   +---+  + +---+   y04&lt;br /&gt;
	load_node 	y14	;    |                    - A&lt;br /&gt;
	update_node 	y24	;    |    +---+     +---+   |&lt;br /&gt;
	load_node 	y04	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o&lt;br /&gt;
	update_node 	y14	;         +---+ x14 +---+  x24&lt;br /&gt;
&lt;br /&gt;
; allpass 6&lt;br /&gt;
	add_node 	y26	;&lt;br /&gt;
	mult_32		k6	;         y26   +---+ y16 +---+ &lt;br /&gt;
	subtr_node	x26	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+ &lt;br /&gt;
	limit_store 	y06	;          |    +---+     +---+    | &lt;br /&gt;
	load_node 	x16	;          v                       |&lt;br /&gt;
	update_node 	x26	;   y04  +---+   +---+    +---+    | &lt;br /&gt;
	load_node 	y04	;  -&amp;gt;o--&amp;gt;| + |--&amp;gt;|*K6|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	update_node 	x16	;    |   +---+   +---+  + +---+   y06&lt;br /&gt;
	load_node 	y16	;    |                    - A&lt;br /&gt;
	update_node 	y26	;    |    +---+     +---+   |&lt;br /&gt;
	load_node 	y06	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o&lt;br /&gt;
	update_node 	y16	;         +---+ x16 +---+  x26&lt;br /&gt;
&lt;br /&gt;
; allpass 8&lt;br /&gt;
	add_node 	y28	;&lt;br /&gt;
	mult_32		k8	;         y28   +---+ y18 +---+ &lt;br /&gt;
	subtr_node	x28	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+&lt;br /&gt;
	limit_store 	y08	;          |    +---+     +---+    |&lt;br /&gt;
	load_node 	x18	;          v                       |&lt;br /&gt;
	update_node 	x28	;   y06  +---+   +---+    +---+    | &lt;br /&gt;
	load_node 	y06	;  -&amp;gt;o--&amp;gt;| + |--&amp;gt;|*K8|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	update_node 	x18	;    |   +---+   +---+  + +---+   y08&lt;br /&gt;
	load_node 	y18	;    |                    - A&lt;br /&gt;
	update_node 	y28	;    |    +---+     +---+   |&lt;br /&gt;
	load_node 	y08	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o &lt;br /&gt;
	update_node 	y18	;         +---+ x18 +---+  x28 &lt;br /&gt;
	load_node 	x10	;&lt;br /&gt;
	ldi	YL,Low(DatTbl2)	;&lt;br /&gt;
&lt;br /&gt;
; allpass 1&lt;br /&gt;
	add_node 	y21	;&lt;br /&gt;
	mult_32		k1	;         y21   +---+ y11 +---+&lt;br /&gt;
	subtr_node	x21	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+&lt;br /&gt;
	limit_store 	y01	;          |    +---+     +---+    |&lt;br /&gt;
	load_node 	x11	;          v                       |&lt;br /&gt;
	update_node 	x21	;   x10  +---+   +---+    +---+    | &lt;br /&gt;
	load_node 	x10	;  -&amp;gt;o--&amp;gt;| + |--&amp;gt;|*K1|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	update_node 	x11	;    |   +---+   +---+  + +---+   y01&lt;br /&gt;
	load_node 	y11	;    |                    - A&lt;br /&gt;
	update_node 	y21	;    |    +---+     +---+   |&lt;br /&gt;
	load_node 	y01	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o&lt;br /&gt;
	update_node 	y11	;         +---+ x11 +---+  x21&lt;br /&gt;
&lt;br /&gt;
; allpass 3&lt;br /&gt;
	add_node 	y23	;&lt;br /&gt;
	mult_32		k3	;         y23   +---+ y13 +---+&lt;br /&gt;
	subtr_node	x23	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+&lt;br /&gt;
	limit_store 	y03	;          |    +---+     +---+    |&lt;br /&gt;
	load_node 	x13	;          v                       |&lt;br /&gt;
	update_node 	x23	;   y01  +---+   +---+    +---+    | &lt;br /&gt;
	load_node 	y01	;  -&amp;gt;o--&amp;gt;| + |--&amp;gt;|*K3|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	update_node 	x13	;    |   +---+   +---+  + +---+   y03&lt;br /&gt;
	load_node 	y13	;    |                    - A&lt;br /&gt;
	update_node 	y23	;    |    +---+     +---+   |&lt;br /&gt;
	load_node 	y03	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o&lt;br /&gt;
	update_node 	y13	;         +---+ x13 +---+  x23&lt;br /&gt;
&lt;br /&gt;
; allpass 5&lt;br /&gt;
	add_node 	y25	;&lt;br /&gt;
	mult_32		k5	;         y25   +---+ y15 +---+&lt;br /&gt;
	subtr_node	x25	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+&lt;br /&gt;
	limit_store 	y05	;          |    +---+     +---+    |&lt;br /&gt;
	load_node 	x15	;          v                       |&lt;br /&gt;
	update_node 	x25	;   y03  +---+   +---+    +---+    | &lt;br /&gt;
	load_node 	y03	;  -&amp;gt;o--&amp;gt;| + |--&amp;gt;|*K5|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	update_node 	x15	;    |   +---+   +---+  + +---+   y05&lt;br /&gt;
	load_node 	y15	;    |                    - A&lt;br /&gt;
	update_node 	y25	;    |    +---+     +---+   |&lt;br /&gt;
	load_node 	y05	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o&lt;br /&gt;
	update_node 	y15	;         +---+ x15 +---+  x25&lt;br /&gt;
&lt;br /&gt;
; allpass 7&lt;br /&gt;
	add_node 	y27	;&lt;br /&gt;
	mult_32		k7	;         y27   +---+ y17 +---+&lt;br /&gt;
	subtr_node	x27	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+&lt;br /&gt;
	limit_store 	y07	;          |    +---+     +---+    |&lt;br /&gt;
	load_node 	x17	;          v                       |&lt;br /&gt;
	update_node 	x27	;   y05  +---+   +---+    +---+    | &lt;br /&gt;
	load_node 	y05	;  -&amp;gt;o--&amp;gt;| + |--&amp;gt;|*K7|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	update_node 	x17	;    |   +---+   +---+  + +---+   y07&lt;br /&gt;
	load_node 	y17	;    |                    - A&lt;br /&gt;
	update_node 	y27	;    |    +---+     +---+   | &lt;br /&gt;
	load_node 	y07	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o &lt;br /&gt;
	update_node 	y17	;         +---+ x17 +---+  x27&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* PWM - D/A-output&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
; output y07 to PWM-DAC&lt;br /&gt;
&lt;br /&gt;
;test: output y01&lt;br /&gt;
	ldd	accu3, Y+y01+1	;&lt;br /&gt;
;&lt;br /&gt;
	subi	accu3,$80	; signed to unsigned  $8000 -&amp;gt;$0000, $7FFF -&amp;gt;$FFFF&lt;br /&gt;
	sts	OCR1AH,zero	; &lt;br /&gt;
	sts	OCR1AL,accu3	; fast PWM 8 bit y07 output to OCR1A&lt;br /&gt;
	ldi	YL,Low(DatTbl1)	; back to 1st data table&lt;br /&gt;
; output y08 to PWM-DAC&lt;br /&gt;
;	load_node 	y08	; load y08&lt;br /&gt;
&lt;br /&gt;
; test outpt y02&lt;br /&gt;
	load_node 	y02	; load y02&lt;br /&gt;
;&lt;br /&gt;
	subi	datah,$80	; signed to unsigned  $8000 -&amp;gt;$0000, $7FFF -&amp;gt;$FFFF&lt;br /&gt;
	sts	OCR1BH,zero	; &lt;br /&gt;
	sts	OCR1BL,accu3	; fast PWM 8 bit y08 output to OCR1B&lt;br /&gt;
	cbi	PortD,0		; just to measure INT-Time&lt;br /&gt;
	out	SREG,savsrg	; restore status register&lt;br /&gt;
	reti			; &lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* coefficient table in flash memory&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
CoTblF:&lt;br /&gt;
	.dw 	15709 	 	; k2 *32768 (0,4794008655888)&lt;br /&gt;
	.dw 	28712	 	; k4 *32768 (0,8762184935393)&lt;br /&gt;
	.dw 	32001		; k6 *32768 (0,9765975895082)&lt;br /&gt;
	.dw 	32686	 	; k8 *32768 (0,9974992559356)&lt;br /&gt;
	.dw 	 5301	 	; k1 *32768 (0,1617584983677)&lt;br /&gt;
	.dw 	24020		; k3 *32768 (0,7330289323415)&lt;br /&gt;
	.dw 	30977 		; k5 *32768 (0,9453497003291)&lt;br /&gt;
	.dw 	32460	 	; k7 *32768 (0,9905991566845)&lt;br /&gt;
&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* data in SRAM&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
.dseg&lt;br /&gt;
.org	$0100&lt;br /&gt;
DatTbl1:&lt;br /&gt;
	; &amp;quot;allpass&amp;quot; 0&lt;br /&gt;
	.dw 	$0000 	 	; x10&lt;br /&gt;
	; allpass 2&lt;br /&gt;
	.dw 	$0000 	 	; x12&lt;br /&gt;
	.dw 	$0000 	 	; x22&lt;br /&gt;
	.dw 	$0000 	 	; y02&lt;br /&gt;
	.dw 	$0000 	 	; y12&lt;br /&gt;
	.dw 	$0000 	 	; y22&lt;br /&gt;
	; allpass 4&lt;br /&gt;
	.dw 	$0000 	 	; x14&lt;br /&gt;
	.dw 	$0000 	 	; x24&lt;br /&gt;
	.dw 	$0000 	 	; y04&lt;br /&gt;
	.dw 	$0000 	 	; y14&lt;br /&gt;
	.dw 	$0000 	 	; y24&lt;br /&gt;
	; allpass 6&lt;br /&gt;
	.dw 	$0000 	 	; x16&lt;br /&gt;
	.dw 	$0000 	 	; x26&lt;br /&gt;
	.dw 	$0000 	 	; y06&lt;br /&gt;
	.dw 	$0000 	 	; y16&lt;br /&gt;
	.dw 	$0000 	 	; y26&lt;br /&gt;
	; allpass 8&lt;br /&gt;
	.dw 	$0000 	 	; x18&lt;br /&gt;
	.dw 	$0000 	 	; x28&lt;br /&gt;
	.dw 	$0000 	 	; y08&lt;br /&gt;
	.dw 	$0000 	 	; y18&lt;br /&gt;
	.dw 	$0000 	 	; y28&lt;br /&gt;
CoTblS:&lt;br /&gt;
	.dw 	$0000 	 	; k2&lt;br /&gt;
	.dw 	$0000 	 	; k4&lt;br /&gt;
	.dw 	$0000		; k6&lt;br /&gt;
	.dw 	$0000	 	; k8&lt;br /&gt;
DatTbl2:&lt;br /&gt;
	.dw 	$0000	 	; k1&lt;br /&gt;
	.dw 	$0000		; k3&lt;br /&gt;
	.dw 	$0000 		; k5&lt;br /&gt;
	.dw 	$0000	 	; k7&lt;br /&gt;
	; allpass 1&lt;br /&gt;
	.dw 	$0000 	 	; x11&lt;br /&gt;
	.dw 	$0000 	 	; x21&lt;br /&gt;
	.dw 	$0000 	 	; y01&lt;br /&gt;
	.dw 	$0000 	 	; y11&lt;br /&gt;
	.dw 	$0000 	 	; y21&lt;br /&gt;
	; allpass 3&lt;br /&gt;
	.dw 	$0000 	 	; x13&lt;br /&gt;
	.dw 	$0000 	 	; x23&lt;br /&gt;
	.dw 	$0000 	 	; y03&lt;br /&gt;
	.dw 	$0000 	 	; y13&lt;br /&gt;
	.dw 	$0000 	 	; y23&lt;br /&gt;
	; allpass 5&lt;br /&gt;
	.dw 	$0000 	 	; x15&lt;br /&gt;
	.dw 	$0000 	 	; x25&lt;br /&gt;
	.dw 	$0000 	 	; y05&lt;br /&gt;
	.dw 	$0000 	 	; y15&lt;br /&gt;
	.dw 	$0000 	 	; y25&lt;br /&gt;
	; allpass 7&lt;br /&gt;
	.dw 	$0000 	 	; x17&lt;br /&gt;
	.dw 	$0000 	 	; x27&lt;br /&gt;
	.dw 	$0000 	 	; y07&lt;br /&gt;
	.dw 	$0000 	 	; y17&lt;br /&gt;
	.dw 	$0000 	 	; y27&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Kategorie:AVR-Projekte]]&lt;br /&gt;
[[Category:DSP]]&lt;/div&gt;</summary>
		<author><name>Claus w</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Hilbert-Transformator_(Phasenschieber)_mit_ATmega&amp;diff=102903</id>
		<title>Hilbert-Transformator (Phasenschieber) mit ATmega</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Hilbert-Transformator_(Phasenschieber)_mit_ATmega&amp;diff=102903"/>
		<updated>2021-01-09T22:47:25Z</updated>

		<summary type="html">&lt;p&gt;Claus w: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Dieser Artikel ist eine Fortsetzung von [[Digitalfilter mit ATmega]] und behandelt ein spezielles Digitalfilter namens Hilbert-Transformator.&lt;br /&gt;
&lt;br /&gt;
Neben den üblichen Filtern, Tiefpass, Hochpass, Bandpass und Bandsperre, gibt es einige weitere Typen. In der Literatur findet man u.a. noch den Allpass, Phasenschieber, Integrator und Differentiator.&lt;br /&gt;
&lt;br /&gt;
===Der Hilbert-Transformator, ein Breitband-90-Grad-Phasenschieber===&lt;br /&gt;
&lt;br /&gt;
In den Lehrbüchern wird er völlig zu Unrecht eher am Rande abgehandelt. Tatsächlich findet man ihn in allen Schaltungen zur Datenübertragung, zu Modulation oder Demodulation mit I/Q-Mischern, im „Software-defined radio“.&lt;br /&gt;
&lt;br /&gt;
Auch ein Hilbert-Transformator kann mithilfe von Scilab berechnet werden. Allerdings gibt es keine fertige Software, man muss sich durch einige Literatur hindurchfressen, z.&amp;amp;nbsp;B. ISBN 0471619957 Sanjit Mitra, Handbook for DSP (1993), Kapitel „Special Filter Designs“ von [https://web.archive.org/web/20100610031102/http://faculty.cua.edu/regalia/ Phillip Regalia].&lt;br /&gt;
[https://web.itu.edu.tr/hulyayalcin/Signal_Processing_Books/DSP_Applications_Mitra.pdf Matlab-Plots dazu hier ab Seitenzahl 41]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
GNU Octave stellt die Hilbert-Transformation und den Parks-McClellan-hilbert-FIR-Filterentwurf im [http://octave.sourceforge.net/signal/function/remez.html octave-forge Paket &amp;quot;signal&amp;quot;] zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
Eine Fundgrube sind die Matlab-Texte von Prof. Schüssler, die vorab 1998 zum  zweiten Band seines Lehrbuchs auf seiner Webseite veröffentlicht wurden. Inzwischen ist der erste Band in der fünften Auflage erschienen [http://www.springer.com/engineering/signals/book/978-3-540-78250-6 ISBN 9783540782506] , der zweite Band ISBN 9783642011184 2010 erstmalig erschienen,  [http://www.lms.lnt.de/forschung/veroeffentlichungen/buecher/dsv.shtml Software-Download hier] aber die Webseite ist nach seinem Tod 2007 abgeschaltet. Zum Glück gibt es das  &lt;br /&gt;
[http://web.archive.org/web/20041206171820/www.nt.e-technik.uni-erlangen.de/~hws/dsv2programs/index.html  Webarchiv], wo die Texte noch zu finden sind.&lt;br /&gt;
&lt;br /&gt;
Zu dieser Zeit waren die Matlab-Programme noch nicht in „Toolboxen“ untergebracht, deren Funktion von außen nicht mehr sichtbar ist. Daher lassen sie sich relativ einfach in Scilab oder Octave übersetzen.&lt;br /&gt;
&lt;br /&gt;
Vier Versionen von Hilbert-Transformatoren werden hier berechnet: &lt;br /&gt;
* FIR-Hilbert, aufwendig, aber streng linearphasig, der bekannteste Typ, da schon lange mit dem Matlab-Befehl remez / firpm und Parameter &#039;hilbert&#039; berechenbar. Mit dem octave-forge Paket &amp;quot;signal&amp;quot; ist remez mit &amp;quot;hilbert&amp;quot; verfügbar. Scilab kennt diesen Parameter nicht.&lt;br /&gt;
* näherungsweise linearphasiger IIR-Hilbert, maximal flach,&lt;br /&gt;
* näherungsweise linearphasiger IIR-Hilbert, Tschebyscheff &lt;br /&gt;
* minimalphasiger IIR-Hilbert, kompakt, aber mit großen Gruppenlaufzeitschwankungen, eher für Audioanwendungen als Digitalsignale.&lt;br /&gt;
&lt;br /&gt;
Im Artikel von Schüßler/Steffen (siehe unten) sind in zwei vergleichenden Beispielen die Gruppenlaufzeitschwankungen des maximal Flachen etwa halb so groß, des Minimalphasigen etwa fünf Mal so groß wie die Tschbyscheff-Version.&lt;br /&gt;
&lt;br /&gt;
Zumindest der kompakte IIR-Hilbert lässt sich auch in einem ATmega unterbringen. Er besteht aus einer Verzögerung und zwei Allpässen, die wieder aus SOS-Teilfiltern aufgebaut sind. Pro Teilfilter gibt es nur einen Koeffizienten, sodass man mindestens acht Teilfilter verwenden kann.&lt;br /&gt;
&lt;br /&gt;
===Ein Hilbert-Kochrezept (noch unvollständig)===&lt;br /&gt;
&lt;br /&gt;
Folgen wir dem Zahlenbeispiel und Berechnungsweg im „Handbook for DSP“.&lt;br /&gt;
&lt;br /&gt;
Zuerst berechnen wir einen elliptischen &#039;&#039;Halbband&#039;&#039;-Tiefpass. Halbband besagt, dass die beiden Grenzfrequenzen symmetrisch zur halben Nyquist- Frequenz also 0,25 * Abtastfrequenz liegen, siehe Bild oben rechts. Die genauen Bedingungen lauten in der Schreibweise des Buches (&#039;&#039;p&#039;&#039;=passband, &#039;&#039;s&#039;&#039;=stopband):&lt;br /&gt;
* Omega&amp;lt;sub&amp;gt;s&amp;lt;/sub&amp;gt; + Omega&amp;lt;sub&amp;gt;p&amp;lt;/sub&amp;gt; = Pi &amp;lt;br&amp;gt; (auf Omega&amp;lt;sub&amp;gt;sample&amp;lt;/sub&amp;gt; normierte Skala: Samplerate=2*Pi)&lt;br /&gt;
* (1-Delta&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;)&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; +Delta&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;=1&lt;br /&gt;
&lt;br /&gt;
Als Zahlenwerte werden Omega&amp;lt;sub&amp;gt;s&amp;lt;/sub&amp;gt; = 0,55*Pi und Delta&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;=0,01 gewählt, und damit ein elliptischer IIR-Tiefpass 7.Ordnung berechnet.&lt;br /&gt;
Damit erhält er folgende Zahlenwerte der Pole:&lt;br /&gt;
&lt;br /&gt;
 0  0,436688  0,743707 0,927758&lt;br /&gt;
&lt;br /&gt;
===Scilab-Berechnung des Halbbandfilters===&lt;br /&gt;
&lt;br /&gt;
Mit Scilab erhalten wir nach einigem Ausprobieren praktisch dieselben Zahlenwerte, siehe Bild. Die Pole müssten für ein ideales Halbbandfilter genau auf der imaginären Achse liegen, der Realteil genau Null sein (Der Fehler kommt daher, dass die Angabe von f&amp;lt;sub&amp;gt;stop&amp;lt;/sub&amp;gt; vom Programm nicht berücksichtigt wird, das Filter wäre überbestimmt).&lt;br /&gt;
Diese Zahlen werden noch quadriert (&#039;&#039;konjugiert komplexe&#039;&#039; Pole zusammengefasst) und bilden schließlich die Koeffizienten des Hilbert-Transformators.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Halbbandfilter.png|Mit Scilab berechnetes Halbbandfilter 7.Ordnung|640px]]&lt;br /&gt;
&lt;br /&gt;
Die Übertragungsfunktion des gesuchten Hilbert-Transformators soll wie bisher H(z) heißen. Zur Unterscheidung nennen wir die bis jetzt berechnete Tiefpassfunktion G(z). &lt;br /&gt;
&lt;br /&gt;
Wieder wird sie in SOS-Teilfilter aufgeteilt. Hier allerdings in die &amp;lt;u&amp;gt;Summe&amp;lt;/u&amp;gt; von zwei &amp;lt;u&amp;gt;parallel&amp;lt;/u&amp;gt; geschalteten &#039;&#039;Allpass&#039;&#039;-Funktionen A&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; und A&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt; plus eine Verzögerung um einen Sampletakt, in der Übertragungsfunktion als „z&amp;lt;sup&amp;gt;-1&amp;lt;/sup&amp;gt;“ ausgedrückt.&lt;br /&gt;
&lt;br /&gt;
Ein Allpass läßt alle Signalfrequenzen mit unveränderter Amplitude durch, verändert nur die Phase. Seine SOS-Teilfunktion ist besonders einfach aufgebaut, zwei Koeffizienten sind Null, zwei sind gleich Eins und die beiden restlichen identisch. Damit benötigt man nur eine Multiplikation pro Teilfilter.&lt;br /&gt;
&lt;br /&gt;
Die Tiefpass-Übertragungsfunktion erhält so die Form:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;G(z) = ½ * ( A&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; (z&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;) + z&amp;lt;sup&amp;gt;-1&amp;lt;/sup&amp;gt; * A&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt; (z&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;))&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
mit&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
A_{1}(z^{2})=\frac{z^{-2}+0,190696}{1+0,190696\ast z^{-2}}\ast&lt;br /&gt;
{\frac{z^{-2}+0,860735}{1+0,860735\ast z^{-2}}}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
A_{2}(z^{2})=\frac{z^{-2}+0,553100}{1+0,553100\ast z^{-2}}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn man die beiden Ausgänge nicht addiert, sondern subtrahiert, entsteht ein Hochpass gleicher Grenzfrequenz. Beides kombiniert ergibt eine digitale &#039;&#039;Frequenzweiche&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Zum Übergang auf den Hilbert-Transformator ersetzen (&#039;&#039;substituieren&#039;&#039;) wir das z durch -jz und multiplizieren das ganze mit 2:&lt;br /&gt;
&lt;br /&gt;
H(z)= 2*G(-jz)&lt;br /&gt;
  &lt;br /&gt;
&#039;&#039;&#039;H(z) = A&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; (-z&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;) + j* z&amp;lt;sup&amp;gt;-1&amp;lt;/sup&amp;gt; * A&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt; (-z&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
mit&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
A_{1}(-z^{2})=\frac{z^{-2}-0,190696}{1-0,190696\ast z^{-2}}\ast&lt;br /&gt;
{\frac{z^{-2}-0,860735}{1-0,860735\ast z^{-2}}}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
A_{2}(-z^{2})=\frac{z^{-2}-0,553100}{1-0,553100\ast z^{-2}}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie man sieht, ändern sich nur die Vorzeichen. Die Pole liegen aber im Pol-Nullstellendiagramm auf der reellen Achse.&lt;br /&gt;
&lt;br /&gt;
Die Ausgänge der beiden Allpässe sind jetzt gegeneinander um 90 Grad phasenverschoben, und können auf einen I/Q-Modulator gegeben werden. Umgekehrt kann man auch die beiden Eingänge auftrennen, und zwei um 90 Grad versetzte Signale aus einem I/Q-Demodulator einspeisen und die Ausgangssignale addieren oder subtrahieren, je nach gewünschtem Seitenband.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Allpaesse.png]]&lt;br /&gt;
&lt;br /&gt;
Und weil das so gut funktionierte, hier noch die Berechnung des Hilbert-Transformators [http://www.mikrocontroller.net/topic/92630#new von Olli Niemitalo] mit einem Halbband-Tiefpass 17.Ordnung, was zu acht SOS-Teilfiltern führt, dazu folgt unten ein ATmega48-Programm.&lt;br /&gt;
Die originalen URL sind verwaist, aber im Webarchiv noch zu finden:&amp;lt;br&amp;gt;&lt;br /&gt;
https://web.archive.org/web/20070719141658/http://yehar.com/ViewHome.pl?page=dsp/hilbert/ &amp;lt;br&amp;gt;&lt;br /&gt;
https://web.archive.org/web/20070814013543/http://yehar.com/ViewHome.pl?page=dsp/hilbert/011729.html &amp;lt;br&amp;gt;&lt;br /&gt;
Olli ist auch heute (2019) noch aktiv:&amp;lt;br&amp;gt;&lt;br /&gt;
http://yehar.com/blog/&amp;lt;br&amp;gt;&lt;br /&gt;
speziell sein IIR-Hilbert:&amp;lt;br&amp;gt;&lt;br /&gt;
http://yehar.com/blog/?p=368&amp;lt;br&amp;gt;&lt;br /&gt;
Diskussion auch dazu:&amp;lt;br&amp;gt;&lt;br /&gt;
https://dsp.stackexchange.com/questions/37411/iir-hilbert-transformer/59157#59157&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Bild:Halbbandfilter2.png|Halbbandfilter 17.Ordnung|640px]]&lt;br /&gt;
&lt;br /&gt;
===Der näherungsweise linearphasige Hilbert-Transformator===&lt;br /&gt;
&lt;br /&gt;
Er wird im Handbook for DSP auf zwei Seiten sehr kurz abgehandelt. Statt aus zwei Allpässen besteht er aus einem einzigen, im anderen Zweig wird das Signal nur zeitverzögert, was mit einem Ringpuffer wenig Rechenzeit kostet. Eine Zeitverzögerung ist sozusagen die einfachste Form eines Allpasses, damit ist diese Bauform ein Spezialfall der oben gezeigten. Aus Schüsslers Texten erfahren wir noch, dass das Halbband-Tiefpassfilter zur Berechnung hier Tschebyscheff-Charakter haben muß.&lt;br /&gt;
&lt;br /&gt;
Das Zahlenbeispiel zitiert Regalia aus einer anderen Veröffentlichung [http://www.cs.tut.fi/~mr/MRJulk92.html (M. Renfors and T. Saramäki, A class of approximately linear phase digital filters composed of allpass subfilters 1986 ) ] Der Allpass hat neun Koeffizienten, die Zeitverzögerung beträgt 17 Sampletakte. Der Halbband-Tiefpass hat eine Sperrdämpfung von &amp;gt; 49 dB. Sein Frequenzgang und der Phasengang des berechneten Hilbert-Transformators sind als Bild gezeigt.&lt;br /&gt;
&lt;br /&gt;
Zum Allpass gibt es noch folgende Zahlenwerte:&lt;br /&gt;
&lt;br /&gt;
Pole location for A(z)&amp;lt;br&amp;gt;&lt;br /&gt;
z= 	-0.8699928078&amp;lt;br&amp;gt;&lt;br /&gt;
	 0.491194141 ± j0.183666529&amp;lt;br&amp;gt;&lt;br /&gt;
	 0.252724179 ± j0.463085544&amp;lt;br&amp;gt;&lt;br /&gt;
	-0.109950894 ± j0.548611467&amp;lt;br&amp;gt;&lt;br /&gt;
	-0.447326028 ± j0.356810323&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das könnte also ebenfalls noch in einen  ATmega passen.&lt;br /&gt;
&lt;br /&gt;
===Hilbert ohne Multiplizierer===&lt;br /&gt;
&lt;br /&gt;
Eine interessante Variante wird im Artikel [http://kondor.etf.bg.ac.yu/~lutovac/pdf/eusi98lm.pdf Design of multiplierless elliptic IIR halfband filters and Hilbert transformers] vorgestellt. Ähnlich wie im Cordic-Algorithmus für trigonometrische Funktionen werden Multiplikationen vermieden, durch geschickte Wahl der Koeffizienten als Zweierpotenzen.&lt;br /&gt;
&lt;br /&gt;
Die beiden Allpässe des Zahlenbeispiels haben folgende Übertragungsfunktionen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
A_1(z^{-2})&lt;br /&gt;
&amp;amp;=\frac{z^{-2}-0{,}12109375}{1-0{,}12109375 \cdot z^{-2}}&lt;br /&gt;
\cdot\frac{z^{-2}-0{,}6640625}{1-0{,}6640625 \cdot z^{-2}} \\&lt;br /&gt;
&amp;amp;=\frac{z^{-2}-(\frac18 - \frac1{256})}{1-(\frac18 - \frac1{256}) \cdot z^{-2}}&lt;br /&gt;
\cdot\frac{z^{-2}-(\frac12 + \frac18 + \frac1{32} + \frac1{128})}{1-(\frac12 + \frac18 + \frac1{32} + \frac1{128})\cdot z^{-2}}\\&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
A_2(z^{-2})\cdot{z^{-1}}&lt;br /&gt;
&amp;amp;=z^{-1}&lt;br /&gt;
\cdot\frac{z^{-2}-0{,}390625}{1-0{,}390625 \cdot z^{-2}}&lt;br /&gt;
\cdot\frac{z^{-2}-0{,}890625}{1-0{,}890625 \cdot z^{-2}}\\&lt;br /&gt;
&amp;amp;=z^{-1}&lt;br /&gt;
\cdot\frac{z^{-2}-(\frac14 + \frac18 + \frac1{64})}{1-(\frac14 + \frac18 + \frac1{64}) \cdot z^{-2}}&lt;br /&gt;
\cdot\frac{z^{-2}-(1 - \frac18 + \frac1{64})}{1-(1 - \frac18 + \frac1{64}) \cdot z^{-2}}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Hilber Transormator nach der FIR-Methode ==&lt;br /&gt;
&lt;br /&gt;
Nach dem Additionstheorem ergibt sich aus dem multiplikativen Mischen (u_prod = u_1 * u_2) zweier Wechselspannungen eine Überlagerung (u_sum = u_3 + u_4) zweier anderer Wechelspannungen; die Freqenz der einen Wechselspannung ist die Summe der Frequenzen der Faktor-Spannungen - die Frequenz der anderen Wechselspannung ist die Differenz der Frequenzen der Faktorspannungen. Jeweils eine der beiden Frequenzen ist das Nutz-Signal, die andere Frequenz ist die Spiegelfrequenz.&lt;br /&gt;
&lt;br /&gt;
Der Hilbert-Tranformator ist ein Mittel um nur das Nutzsignal und nicht die Spiegelfrequenz zu mischen. Es wird nach den Regeln der Multiplikation komplexer Zahlen gemischt. Eingabesignal und Mischoszillator müssen in der Form der EULERschen Identität vorliegen: &lt;br /&gt;
&lt;br /&gt;
y = A * exp( j * phi )  = A * ( cos( phi ) + j * sin( phi )  ) ; phi = omega * t ; omega = 2 * pi * f ; f ... Frequenz ; A ... Amplitude ; t ... Zeit&lt;br /&gt;
&lt;br /&gt;
Mit der exp() - Darstellung kann man mischen, indem man den Ausdruck phi = 2 * pi * t * (f1 + f2) anwendet. Dabei addieren sich die Frequenzen ohne Spiegelfrequenz. Beide Frequenzen müssen als komplexe Zahlen vorliegen, also jede Frequenz als zwei Wechselspannungen mit (jeweils pro Frequenz) gleicher Amplitude. Liegt nur ein einfaches Sinus-Signal vor, kann man das dazugehörige Cosinus-Signal durch Phasenverschiebung um 90° mit einem Hilbert-Transformator erreichen. Danach wendet man die Multiplikation an:&lt;br /&gt;
&lt;br /&gt;
y[ re, j * im ]:= x1[ re, j * im ]* x2[ re, j * im ] = (x1.re * x2.re - x1.im * x2.im) + j * (x1.re * x2.im + x2.re * x1.im) ; re ... Realteil ; im ... Imag. Teil&lt;br /&gt;
&lt;br /&gt;
Jedes Glied des einen Faktors mit jedem Glied des anderen Faktors unter Beachtung der imaginären Einheit multiplizieren. Wendet man bei dem Signal einer der beiden Frequenzen nur einen der beiden Anteile (entweder nur realen Cosinus-Teil oder imaginären Sinusteil) so entsteht eine &amp;quot;negative&amp;quot; Frequenz (der Zeiger in der komplexen Zahlenebene dreht sich andersherum). Somit wird diese Frequenz von der anderen subtrahiert (phi = 2 * pi * t * (f1 - f2)). Das kann sowohl rechnerisch als auch durch Umpolen einer Bandfilterwicklung errreicht werden. Für Zwischenergebnisse nutzt man beide Signalteile weiter, für z.B. eine Audioausgabe genügt einer.&lt;br /&gt;
&lt;br /&gt;
Kann man zu einem Sinussignal das Cosinus-Signal auch ohne synthetisches Filter erhalten? Genau weiß ich es nicht. Für einen Oszillator braucht man mindestens zwei Energiespeicher. Beide sind (wenn es kein Drehstromoszillator ist) um 90° phasenverschoben. Hier kommt man ohne synthetisches Filter aus. Anders bei Schallwellen. Der eine Speicher besteht hier sowohl aus Schalldruck als auch aus Schallschnelle. Sind beide um 0° phasenverschoben, so bewegt sich die Welle in die eine Richtung, bei 180° entsprechend entgegengesetzt. Der andere Speicher ist die 1. Ableitung von jeweils Schalldruck und Schallschnelle. Die Ableitung ist um 90° phasenverschoben aber bei frequenzabhängiger Amplitude ( y = A * sin( omega * t ) ; y&#039; = omega * A * cos( omega * t ) ). Ohne Spiegelfrequenz kann man das nur für eine feste Frequenz mischen. Bei einem Frequenzband braucht man das synthetische Filter.&lt;br /&gt;
&lt;br /&gt;
Der Hilbert-Transformator erzeugt aus einem Sinus-Signal das um 90° verschobene Cosinus-Signal. Ein Beispiel in Python:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Begin Hilbert FIR filter.&lt;br /&gt;
import math # Math&lt;br /&gt;
import numpy as np # Math&lt;br /&gt;
import matplotlib as mlp # Plot&lt;br /&gt;
import matplotlib.pyplot as plt # Plot&lt;br /&gt;
&lt;br /&gt;
FREQUENCY = 400.0 # 1 / s&lt;br /&gt;
RATE = 48000.0 # samples / s&lt;br /&gt;
SAMPLES = 4000&lt;br /&gt;
CELLS = 501&lt;br /&gt;
STEPS = SAMPLES - CELLS&lt;br /&gt;
PREFIX = (CELLS - 1) / 2&lt;br /&gt;
SUFFIX = CELLS - PREFIX&lt;br /&gt;
POSTFIX = SAMPLES - CELLS&lt;br /&gt;
&lt;br /&gt;
samples = range(SAMPLES)&lt;br /&gt;
cells = range(CELLS)&lt;br /&gt;
steps = range(STEPS)&lt;br /&gt;
prefixes = range(PREFIX)&lt;br /&gt;
suffixes = range(SUFFIX)&lt;br /&gt;
postfixes = range(POSTFIX)&lt;br /&gt;
&lt;br /&gt;
input = []&lt;br /&gt;
re = []&lt;br /&gt;
im = []&lt;br /&gt;
coefficients = []&lt;br /&gt;
&lt;br /&gt;
def plot():&lt;br /&gt;
&lt;br /&gt;
	for sample in samples:&lt;br /&gt;
		if(SAMPLES / 2 &amp;gt; sample):&lt;br /&gt;
			_phi = FREQUENCY * sample / RATE * 2.0 * math.pi&lt;br /&gt;
		else:&lt;br /&gt;
			_phi = 5 * FREQUENCY * sample / RATE * 2.0 * math.pi&lt;br /&gt;
		input.append(math.sin(_phi))&lt;br /&gt;
&lt;br /&gt;
	for cell in cells:&lt;br /&gt;
		arg = cell - (CELLS - 1) / 2.0&lt;br /&gt;
		if(0.0 == arg):&lt;br /&gt;
			coefficients.append(0.0)&lt;br /&gt;
		else:&lt;br /&gt;
			arg *= math.pi&lt;br /&gt;
			coefficients.append((1.0 - math.cos(arg)) / arg)&lt;br /&gt;
	&lt;br /&gt;
	for postfix in postfixes:&lt;br /&gt;
		coefficients.append(0.0)&lt;br /&gt;
	&lt;br /&gt;
	for prefix in prefixes:&lt;br /&gt;
		re.append(0.0)&lt;br /&gt;
		im.append(0.0)&lt;br /&gt;
		&lt;br /&gt;
	for step in steps:&lt;br /&gt;
		re.append(input[step + PREFIX])&lt;br /&gt;
		sum = 0.0&lt;br /&gt;
		for cell in cells:&lt;br /&gt;
			sum += input[step + cell] * coefficients[cell];&lt;br /&gt;
		im.append(sum)&lt;br /&gt;
		&lt;br /&gt;
	for suffix in suffixes:&lt;br /&gt;
		re.append(0.0)&lt;br /&gt;
		im.append(0.0)&lt;br /&gt;
	&lt;br /&gt;
	# Prepare the plot.&lt;br /&gt;
	plt.ylabel(&#039;amplitude&#039;)&lt;br /&gt;
	plt.xlabel(&#039;timesteps&#039;)&lt;br /&gt;
	plt.axis([0, SAMPLES - 1, -1.5, 1.5])&lt;br /&gt;
	plt.grid(True)&lt;br /&gt;
	plt.plot(samples, re, &#039;r-&#039;)&lt;br /&gt;
	plt.plot(samples, im, &#039;b-&#039;)&lt;br /&gt;
	plt.show()&lt;br /&gt;
# End.&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
Neben ein Array aus abgetasteten Werten eines akustischen Signales (hier Sinus-Signal, künstlich berechnet) wird das Array des Transformationskerns gelegt. Das Array des Transformationskerns ist dabei viel kürzer und es wird nur der gemeinsame Bereich berechnet. Der Wert des Cosinus-Signals, das zu dem Sinus-Signal gehört, das sich auf der Position der Mitte des Transformationskerns befindet, ergibt sich aus der Summe der Werte aus dem Sinus-Signal multiplizert mit den Faktoren aus dem Transformationskern mit gleichem Index. Das folgende Cosinus-Signal wird berechnet indem man zuvor den Transformationskern um einen Index gegenüber dem Eingabe-Sinus-Signal weiterschiebt (usw. bis zum Ende des Signales). Am Anfang und am Ende des berechneten Cosinus-Signales entsteht ein Stück Verlust der jeweils halb so lang wie der Transformationskern ist. Bei sehr lang dauernden Signalen (fast immer) ist statt dessen mit einem Ringpuffer zu arbeiten.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
t ... Zeit&lt;br /&gt;
b[Länge k] ... Transformationskern&lt;br /&gt;
i[undendlich lang] ... Sinus - Signal oder Summe aus Sinus-Signalen&lt;br /&gt;
o[undendlich lang] ... um 90° verschobenes Cosinus - Signal&lt;br /&gt;
=&amp;gt;&lt;br /&gt;
o[t] := Summe { i[n+t] * b[n+t] } ; -k/2 &amp;lt;= n &amp;lt;= +k/2 ; i &amp;gt;= k/2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Der Transformationskern kann wie folgt ermittelt werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x ... natürliche Zahl &amp;gt; 0&lt;br /&gt;
k ... 4 * x + 1&lt;br /&gt;
b[] ... Transformationskern der Länge k&lt;br /&gt;
n ... Index innerhalb des Tranformationskerns&lt;br /&gt;
pi ... 3.14159...&lt;br /&gt;
b[n] := ( 1 - cos( n * pi ) ) / ( n * pi ) ; Ausnahme ist b[0] := 0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Datei:FIR_Kernel_Small.png|200px|thumb|right|Hilbert Transformationskern klein]]&lt;br /&gt;
&lt;br /&gt;
Dabei ist das Argument der cos() - Funktion immer ganzzahlig. &amp;quot;1 - cos(...)&amp;quot; ist für ungerade &amp;quot;n&amp;quot; immer NULL. Der Kern hat nahe n == 0 maximale Werte und nimmt zum Rand hin ab. Ein Kern mit zuwenig Länge (k ist zu klein) wirkt als Hochpass und verkleinert die Amplitude von Signalen kleiner Frequenz (ist unbrauchbar). Kommen hohe und tiefe Frequenzen im Signal gleichzeitig vor, dann braucht man sowohl eine hohe Abtastrate als auch einen langen Kern ( k wird groß, z.B. Größenordnung 801 bei einem Audiosignal). Ändert sich das Nutzsignal unerwartet sprungartig so erhält man im Cosinus-Signal eine Art Sprungantwort.&lt;br /&gt;
&lt;br /&gt;
* Großer Transformationskern : [[Medium:FIR_Kernel_Big.png]]&lt;br /&gt;
* Transformation zweier Signale verschiedener Frequenz : [[Medium:Hilber_FIR_OK.png]]&lt;br /&gt;
* Transformation eines Sprunges im Signal : [[Medium:Hilbert_FIR_OK_Lense.png]]&lt;br /&gt;
* Transformationsfehler bei zu kleinem Kern (k ist zu klein) :  [[Medium:Hilbert_FIR_Too_Small_Kernel.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Zusammenfassung&amp;lt;/b&amp;gt;&lt;br /&gt;
Hilbert-Transformation ermittelt zu einem Sinus-Signal das um 90° verschobene Cosinus-Signal. Das gilt auch für eine Summe von Sinussignalen unterschiedlicher Frequenzen und Amplituden. Die Amplitude des Cosinus-Signales ist gleich der Amplitude des Sinus-Signales (kann geringfügig abweichen aber korrigiert werden). Das Transformieren erfolgt meist synthetisch, z.B. in digitalen Signal Prozessoren. Die Hilbert-Transformation wird verwendet, wenn man Sinus-Signal und Cosinus-Signal benötigt aber nur das Sinus-Signal vorliegt. Beide Signale (sin(...) und cos(...)) zusammen entsprechen einer Folge komplexer Zahlen. Damit kann man multiplikativ mischen ohne Spiegelfrequenz. Liegen beide Faktoren der Mischung als komplexe Zahlen vor, kann man jedes Glied der einen Zahl mit jedem Glied der anderen Zahl multiplizieren unter Beachtung der komplexen Einheit &amp;quot;j&amp;quot;. Falls man sich dabei beide Faktoren jedoch in der exp( j * omega * t ) Schreibweise denkt, so multipliziert man statt dessen Potenzen, indem man die Exponenten addiert. Für eine Berechnung braucht man 4 Multiplikationen, was entweder digital erfolgen kann oder im analogen Fall vier Mischer (z.B. Ringmischer oder Gilbertzellen) benötigt, wenn man das ganze Ergebnis braucht. Der Transformationskern ist ein Array aus Zahlen deren Werte in der Mitte des Arrays groß sind und zum Rand hin abnehmen. &lt;br /&gt;
&lt;br /&gt;
==Weitere Literatur zu Hilbert==&lt;br /&gt;
* Schüssler / [http://www.lnt.de/LMS/staff/index.php?lang=de&amp;amp;function=1&amp;amp;person=5 Steffen] &amp;quot;Halfband Filters and Hilbert Transformers&amp;quot; &amp;lt;br&amp;gt; Irgendwo im Web hatte ich den vollständigen Artikel als PDF gefunden, leider die Adresse nicht notiert, Google findet nur [http://www.springerlink.com/content/p5480n6p8t73t633/ kostenpflichtige Downloads].&lt;br /&gt;
* Dutta / Kumar [http://eprint.iitd.ac.in/dspace/bitstream/2074/1608/1/roydig1989.pdf On Digital Differentiators, Hilbert Transformers, and Half-Band Low-Pass Filters] &amp;lt;br&amp;gt; dank Schrifterkennungsprogramm leicht lädiert&lt;br /&gt;
* Miroslav Lutovac / Ljiljana Milic [http://www.telfor.rs/telfor2000/radovi/7-10.pdf Half-band IIR Filter Design Using Matlab],  [http://kondor.etf.bg.ac.yu/~lutovac/confer.htm weitere Artikel der Autoren]&lt;br /&gt;
* Göckler / Damjanovic [http://www.dsv.rub.de/imperia/md/content/public/wsr06_goecklerdamjanovic.pdf A Family of Efficient Complex Halfband Filters]&lt;br /&gt;
&lt;br /&gt;
==ATmega-Programm Hilbert-Transformer ( fast fertig, schwingt leider)==&lt;br /&gt;
Da der Adressenbereich des ATmega nicht groß genug ist, wird die Tabelle im SRAM in zwei Hälften geteilt.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;* Hilbert transformer with ATmega48P, 90 degree broadband phase shifter   *&lt;br /&gt;
;* 15 MHz xtal, input ADC0, PWM-output OCR1a/b, test output PD0            *&lt;br /&gt;
;* Christoph Kessler 2008                         db1uq_at_t-online_dot_de *&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
.nolist&lt;br /&gt;
.include &amp;quot;m48pdef.inc&amp;quot;&lt;br /&gt;
.list&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;* register 0-15 (no &amp;quot;immediate&amp;quot;-operations possible):&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
.def	mult_l	= r0	; multiplier result&lt;br /&gt;
.def	mult_h	= r1	; multiplier result&lt;br /&gt;
.def	zero	= r2	; zero register (used to add carry flag)&lt;br /&gt;
.def	savsrg	= r3	; save status register during interrupt routine&lt;br /&gt;
.def	reg04	= r4	; free&lt;br /&gt;
.def	reg05	= r5	; free&lt;br /&gt;
.def	reg06	= r6	; free&lt;br /&gt;
.def	reg07	= r7	; free&lt;br /&gt;
.def	reg08	= r8	; free&lt;br /&gt;
.def	reg09	= r9	; free&lt;br /&gt;
.def	reg10	= r10	; free&lt;br /&gt;
.def	reg11	= r11	; free&lt;br /&gt;
.def	reg12	= r12	; free&lt;br /&gt;
.def	accu0	= r13	; Accumulator - 32bit for Interrupt routine&lt;br /&gt;
.def	accu1	= r14	; Accumulator - 32bit for Interrupt routine&lt;br /&gt;
.def	accu2	= r15	; Accumulator - 32bit for Interrupt routine&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;* register 16-23 (&amp;quot;immediate&amp;quot;-operations possible):&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
.def	accu3	= r16	; Accumulator - 32bit for Interrupt routine&lt;br /&gt;
.def	reg17	= r17	; free&lt;br /&gt;
.def	reg18	= r18	; free&lt;br /&gt;
.def	reg19	= r19	; free&lt;br /&gt;
.def	datal	= r20	; Data samples mul register&lt;br /&gt;
.def	datah	= r21	;  for Interrupt routine&lt;br /&gt;
.def	coefl	= r22	; Filter coefficient mul register&lt;br /&gt;
.def	coefh	= r23	;  for Interrupt routine&lt;br /&gt;
;***************************************************************************&lt;br /&gt;
;* register 24-31    (16Bit-registers) &lt;br /&gt;
;***************************************************************************&lt;br /&gt;
.def	tmp1	= r24	; general temporary register&lt;br /&gt;
.def	tmp2	= r25	; general temporary register&lt;br /&gt;
;	XL	= r26	; free&lt;br /&gt;
;	XH	= r27	; free&lt;br /&gt;
;	YL	= r28	; used by Interrupt routine&lt;br /&gt;
;	YH	= r29	; used by Interrupt routine&lt;br /&gt;
;	ZL	= r30	; init routine only, free for main program&lt;br /&gt;
;	ZH	= r31	; init routine only, free for main program&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* constants :&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;1st table:&lt;br /&gt;
	;&amp;quot;allpass&amp;quot;0:&lt;br /&gt;
.equ	 x10	= 0&lt;br /&gt;
	; allpass 2:&lt;br /&gt;
.equ	 x12	= 2&lt;br /&gt;
.equ	 x22	= 4&lt;br /&gt;
.equ	 y02	= 6&lt;br /&gt;
.equ	 y12	= 8&lt;br /&gt;
.equ	 y22	= 10&lt;br /&gt;
	; allpass 4:&lt;br /&gt;
.equ	 x14	= 12&lt;br /&gt;
.equ	 x24	= 14&lt;br /&gt;
.equ	 y04	= 16&lt;br /&gt;
.equ	 y14	= 18&lt;br /&gt;
.equ	 y24	= 20&lt;br /&gt;
	; allpass 6:&lt;br /&gt;
.equ	 x16	= 22&lt;br /&gt;
.equ	 x26	= 24&lt;br /&gt;
.equ	 y06	= 26&lt;br /&gt;
.equ	 y16	= 28&lt;br /&gt;
.equ	 y26	= 30&lt;br /&gt;
	; allpass 8:&lt;br /&gt;
.equ	 x18	= 32&lt;br /&gt;
.equ	 x28	= 34&lt;br /&gt;
.equ	 y08	= 36&lt;br /&gt;
.equ	 y18	= 38&lt;br /&gt;
.equ	 y28	= 40&lt;br /&gt;
&lt;br /&gt;
.equ	 k2	= 42&lt;br /&gt;
.equ	 k4	= 44&lt;br /&gt;
.equ	 k6	= 46&lt;br /&gt;
.equ	 k8	= 48&lt;br /&gt;
;2nd table:&lt;br /&gt;
.equ	 k1	= 0&lt;br /&gt;
.equ	 k3	= 2&lt;br /&gt;
.equ	 k5	= 4&lt;br /&gt;
.equ	 k7	= 6&lt;br /&gt;
	; allpass 1:&lt;br /&gt;
.equ	 x11	= 8&lt;br /&gt;
.equ	 x21	= 10&lt;br /&gt;
.equ	 y01	= 12&lt;br /&gt;
.equ	 y11	= 14&lt;br /&gt;
.equ	 y21	= 16&lt;br /&gt;
	; allpass 3:&lt;br /&gt;
.equ	 x13	= 18&lt;br /&gt;
.equ	 x23	= 20&lt;br /&gt;
.equ	 y03	= 22&lt;br /&gt;
.equ	 y13	= 24&lt;br /&gt;
.equ	 y23	= 26&lt;br /&gt;
	; allpass 5:&lt;br /&gt;
.equ	 x15	= 28&lt;br /&gt;
.equ	 x25	= 30&lt;br /&gt;
.equ	 y05	= 32&lt;br /&gt;
.equ	 y15	= 34&lt;br /&gt;
.equ	 y25	= 36&lt;br /&gt;
	; allpass 7:&lt;br /&gt;
.equ	 x17	= 38&lt;br /&gt;
.equ	 x27	= 40&lt;br /&gt;
.equ	 y07	= 42&lt;br /&gt;
.equ	 y17	= 44&lt;br /&gt;
.equ	 y27	= 46&lt;br /&gt;
;*****************************************************&lt;br /&gt;
;* Macros&lt;br /&gt;
;*****************************************************&lt;br /&gt;
.MACRO load_node&lt;br /&gt;
	ldd	datal,Y+@0	; Load low byte of node &lt;br /&gt;
	ldd	datah,Y+@0+1	; Load high byte of node&lt;br /&gt;
.ENDMACRO&lt;br /&gt;
.MACRO update_node&lt;br /&gt;
	std	Y+@0,datal	; Store low byte of node &lt;br /&gt;
	std	Y+@0+1,datah	; Store high byte of node&lt;br /&gt;
.ENDMACRO&lt;br /&gt;
.MACRO add_node&lt;br /&gt;
	ldd	coefl,Y+@0	; Load 2nd node low&lt;br /&gt;
	ldd	coefh,Y+@0+1	; Load 2nd node high&lt;br /&gt;
	add	datal,coefl	; Add low bytes&lt;br /&gt;
	adc	datah,coefh	; Add with carry high bytes&lt;br /&gt;
.ENDMACRO&lt;br /&gt;
.MACRO mult_32&lt;br /&gt;
	ldd	coefl,Y+@0	; Load low byte of coefficient&lt;br /&gt;
	ldd	coefh,Y+@0+1	; Load high byte of coefficient&lt;br /&gt;
	muls	coefh,datah	; Signed multiply, coefficient high byte and data high byte&lt;br /&gt;
	mov     accu2,mult_l	; Copy result word into accumulator byte 2:3&lt;br /&gt;
	mov     accu3,mult_h	; Copy result word into accumulator byte 2:3&lt;br /&gt;
	mul	coefl,datal	; Unsigned multiply, coefficient low byte and data low byte&lt;br /&gt;
	mov	accu0,mult_l	; Copy result word into accumulator byte 2:3&lt;br /&gt;
	mov	accu1,mult_h	; Copy result word into accumulator byte 2:3&lt;br /&gt;
	mulsu	coefh,datal	; Signed-unsigned multiply, coefficient high byte and data low byte&lt;br /&gt;
	sbc	accu3,zero	; Sign extention&lt;br /&gt;
	add	accu1,mult_l	; Add low byte of result to accumulator byte 1&lt;br /&gt;
	adc	accu2,mult_h	; Add with carry high byte of result to accumulator byte 2&lt;br /&gt;
	adc	accu3,zero	; Add carry to accumulator byte 3&lt;br /&gt;
	mulsu	datah,coefl	; Signed-unsigned multiply, data high byte and coefficient low byte&lt;br /&gt;
	sbc	accu3,zero	; Sign extention&lt;br /&gt;
	add	accu1,mult_l	; Add low byte of result to accumulator byte 1&lt;br /&gt;
	adc	accu2,mult_h	; Add with carry high byte of result to accumulator byte 2&lt;br /&gt;
	adc	accu3,zero	; Add carry to accumulator byte 3&lt;br /&gt;
.ENDMACRO&lt;br /&gt;
.MACRO subtr_node&lt;br /&gt;
	ldd	datal,Y+@0	; Load 2nd node low&lt;br /&gt;
	ldd	datah,Y+@0+1	; Load 2nd node high&lt;br /&gt;
	sub	accu0,datal	; Subtract low byte&lt;br /&gt;
	sbc	accu1,datah	; Subtract with carry high byte&lt;br /&gt;
	sbc	accu2,zero	;&lt;br /&gt;
	sbc	accu3,zero	;&lt;br /&gt;
.ENDMACRO&lt;br /&gt;
.MACRO limit_store&lt;br /&gt;
	cpi	accu3,$40	; accu &amp;lt;   $40000000 ?&lt;br /&gt;
	brlo	NoLimit1	;&lt;br /&gt;
	cpi	accu3,-$40	; accu &amp;gt;= -$40000000 ?&lt;br /&gt;
	brsh	NoLimit1	;&lt;br /&gt;
	clr	accu2		; accu2 = $00&lt;br /&gt;
	cpi	accu3,0		;&lt;br /&gt;
	brge	PosLim1		; &lt;br /&gt;
	ldi	accu3,$80	; accu3 = $80&lt;br /&gt;
	rjmp	Limit1		; &lt;br /&gt;
PosLim1:&lt;br /&gt;
	ldi	accu3,$7F	; accu3 = $7F	&lt;br /&gt;
	com	accu2		; accu2 = $FF	&lt;br /&gt;
	rjmp	Limit1		; &lt;br /&gt;
NoLimit1:&lt;br /&gt;
	lsl	accu1		; Scaling to gain factor 2^16&lt;br /&gt;
	rol	accu2		; &lt;br /&gt;
	rol	accu3		; &lt;br /&gt;
Limit1:&lt;br /&gt;
	std	Y+@0,accu2	; &lt;br /&gt;
	std	Y+@0+1,accu3	; &lt;br /&gt;
.ENDMACRO&lt;br /&gt;
.LISTMAC&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* reset/interrupt-vectors:&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
.cseg&lt;br /&gt;
	rjmp	Initial		; after RESET to main program&lt;br /&gt;
	reti			; External Interrupt Request 0&lt;br /&gt;
	reti			; External Interrupt Request 1&lt;br /&gt;
	reti			; Pin Change Interrupt Request 0&lt;br /&gt;
	reti			; Pin Change Interrupt Request 1&lt;br /&gt;
	reti			; Pin Change Interrupt Request 2&lt;br /&gt;
	reti			; Watchdog Time-out Interrupt&lt;br /&gt;
	reti			; Timer/Counter2 Compare Match A&lt;br /&gt;
	reti			; Timer/Counter2 Compare Match B&lt;br /&gt;
	reti			; Timer/Counter2 Overflow&lt;br /&gt;
	reti			; Timer/Counter1 Capture Event&lt;br /&gt;
	reti			; Timer/Counter1 Compare Match A&lt;br /&gt;
	reti			; Timer/Counter1 Compare Match B&lt;br /&gt;
	reti			; Timer/Counter1 Overflow&lt;br /&gt;
	reti			; Timer/Counter0 Compare Match A&lt;br /&gt;
	reti			; Timer/Counter0 Compare Match B&lt;br /&gt;
	reti			; Timer/Counter0 Overflow&lt;br /&gt;
	reti			; SPI Serial Transfer Complete&lt;br /&gt;
	reti			; USART0, Rx Complete&lt;br /&gt;
	reti			; USART0 Data register Empty&lt;br /&gt;
	reti			; USART0, Tx Complete&lt;br /&gt;
	rjmp	ADCint		; ADC Conversion Complete&lt;br /&gt;
	reti			; EEPROM Ready   &lt;br /&gt;
	reti			; 2-wire Serial Interface&lt;br /&gt;
	reti			; Store Program Memory Read&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* after reset: initialise stack,ports&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
Initial: &lt;br /&gt;
	ldi	tmp1,Low(RAMEND)&lt;br /&gt;
	out	SPL,tmp1	;&lt;br /&gt;
	ldi	tmp1,High(RAMEND)&lt;br /&gt;
	out	SPH,tmp1	; stack initialised&lt;br /&gt;
	clr	zero		; always zero&lt;br /&gt;
	ldi	tmp1,$FF	; &lt;br /&gt;
	out	PortB,tmp1	; PortB = % 1111 1111&lt;br /&gt;
	out	PortC,zero	; PortC = % 0000 0000&lt;br /&gt;
	out	PortD,tmp1	; PortD = % 1111 1111&lt;br /&gt;
	out	DDRB,tmp1	; PortB direction = % 1111 1111&lt;br /&gt;
	out	DDRC,zero	; PortC direction = % 0000 0000&lt;br /&gt;
	out	DDRD,tmp1	; PortD direction = % 1111 1111&lt;br /&gt;
	ldi	tmp1,$A1	; pos. outputs, fast PWM 8Bit&lt;br /&gt;
	sts	TCCR1A,tmp1	;&lt;br /&gt;
	ldi	tmp1,$09	; fast PWM 8Bit, clk/1 (no prescaling)&lt;br /&gt;
	sts	TCCR1B,tmp1	;&lt;br /&gt;
	sts	OCR1AH,zero	;&lt;br /&gt;
	sts	OCR1AL,zero	;&lt;br /&gt;
	sts	OCR1BH,zero	;&lt;br /&gt;
	sts	OCR1BL,zero	;&lt;br /&gt;
	ldi	tmp1,$40	; Ref=Vcc, right-adj, ADC0=input&lt;br /&gt;
	sts	ADMUX,tmp1	;&lt;br /&gt;
	ldi	tmp1,$EE	; Start,Auto, enable Int, Clk/64&lt;br /&gt;
;	ldi	tmp1,$EF	; Start,Auto, enable Int, Clk/128&lt;br /&gt;
	sts	ADCSRA,tmp1	;&lt;br /&gt;
	ldi	tmp1,$00	; free running&lt;br /&gt;
	sts	ADCSRB,tmp1	;&lt;br /&gt;
	ldi	tmp1,$01	; disable ADC0 dig.inp (optional)&lt;br /&gt;
	sts	DIDR0,tmp1	;&lt;br /&gt;
	ldi	ZL,low(CoTblF&amp;lt;&amp;lt;1)	; move filter coefficents&lt;br /&gt;
	ldi	ZH,high(CoTblF&amp;lt;&amp;lt;1)	; from program-flash&lt;br /&gt;
	ldi	YL,low(CoTblS)	; to SRAM&lt;br /&gt;
	ldi	YH,high(CoTblS)	;&lt;br /&gt;
	ldi	tmp1,16		; count 8 * 2-Byte coefficients&lt;br /&gt;
TbLoop:&lt;br /&gt;
	lpm	tmp2,Z+		; fetch 1 byte from coefficient table&lt;br /&gt;
	st	Y+,tmp2		; copy coefficient to Sram, increment Y&lt;br /&gt;
	dec	tmp1&lt;br /&gt;
	brne	TbLoop&lt;br /&gt;
	ldi	YL,low(DatTbl1)	; load SRAM-Pointer for Interrupt routine&lt;br /&gt;
	ldi	YH,high(DatTbl1)	;&lt;br /&gt;
	sei			; enable interrupts&lt;br /&gt;
&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* Main program:&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
Endless:&lt;br /&gt;
	rjmp	Endless		; &lt;br /&gt;
&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* ADC-Interrupt routine: compute filter and update PWM output&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
ADCint:&lt;br /&gt;
	sbi	PortD,0		; just to measure INT-Time&lt;br /&gt;
	in	savsrg,SREG	; save status register&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
&lt;br /&gt;
; allpass 2&lt;br /&gt;
	load_node 	x10	;&lt;br /&gt;
	add_node 	y22	;         y22   +---+ y12 +---+&lt;br /&gt;
	mult_32		k2	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+&lt;br /&gt;
	subtr_node	x22	;          |    +---+     +---+    |&lt;br /&gt;
	limit_store 	y02	;          v                       |&lt;br /&gt;
	load_node 	x12	;   x10  +---+   +---+    +---+    | &lt;br /&gt;
	update_node 	x22	;    o--&amp;gt;| + |--&amp;gt;|*K2|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	load_node 	x10	;    |   +---+   +---+  + +---+   y02&lt;br /&gt;
	update_node 	x12	;    |                    - A&lt;br /&gt;
	lds	datal,ADCL	;    |    +---+     +---+   |&lt;br /&gt;
	lds	datah,ADCH	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o&lt;br /&gt;
	dec	datah		;    |    +---+ x12 +---+  x22&lt;br /&gt;
	dec	datah		;    |&lt;br /&gt;
	lsl	datal		;    +-----------+&lt;br /&gt;
	rol	datah		;         +---+  |&lt;br /&gt;
	lsl	datal		;  ADC &amp;gt;--|1/z|--+&lt;br /&gt;
	rol	datah		;         +---+ &lt;br /&gt;
	lsl	datal		; &lt;br /&gt;
	rol	datah		; &lt;br /&gt;
	lsl	datal		; convert 10 bit unsigned &lt;br /&gt;
	rol	datah		; to 15 Bit signed&lt;br /&gt;
	lsl	datal		; $03FF -&amp;gt; $01FF -&amp;gt; $3FE0&lt;br /&gt;
	rol	datah		; $0000 -&amp;gt; $FE00 -&amp;gt; $C000&lt;br /&gt;
	lsl	datal		;  &lt;br /&gt;
	rol	datah		; &lt;br /&gt;
	update_node 	x10	; save new sample for 2nd allpass-chain&lt;br /&gt;
	load_node 	y12	; &lt;br /&gt;
	update_node 	y22	; &lt;br /&gt;
	load_node 	y02	;&lt;br /&gt;
	update_node 	y12	;&lt;br /&gt;
&lt;br /&gt;
; allpass 4&lt;br /&gt;
	add_node 	y24	;&lt;br /&gt;
	mult_32		k4	;         y24   +---+ y14 +---+&lt;br /&gt;
	subtr_node	x24	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+&lt;br /&gt;
	limit_store 	y04	;          |    +---+     +---+    |&lt;br /&gt;
	load_node 	x14	;          v                       |&lt;br /&gt;
	update_node 	x24	;   y02  +---+   +---+    +---+    | &lt;br /&gt;
	load_node 	y02	;  -&amp;gt;o--&amp;gt;| + |--&amp;gt;|*K4|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	update_node 	x14	;    |   +---+   +---+  + +---+   y04&lt;br /&gt;
	load_node 	y14	;    |                    - A&lt;br /&gt;
	update_node 	y24	;    |    +---+     +---+   |&lt;br /&gt;
	load_node 	y04	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o&lt;br /&gt;
	update_node 	y14	;         +---+ x14 +---+  x24&lt;br /&gt;
&lt;br /&gt;
; allpass 6&lt;br /&gt;
	add_node 	y26	;&lt;br /&gt;
	mult_32		k6	;         y26   +---+ y16 +---+ &lt;br /&gt;
	subtr_node	x26	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+ &lt;br /&gt;
	limit_store 	y06	;          |    +---+     +---+    | &lt;br /&gt;
	load_node 	x16	;          v                       |&lt;br /&gt;
	update_node 	x26	;   y04  +---+   +---+    +---+    | &lt;br /&gt;
	load_node 	y04	;  -&amp;gt;o--&amp;gt;| + |--&amp;gt;|*K6|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	update_node 	x16	;    |   +---+   +---+  + +---+   y06&lt;br /&gt;
	load_node 	y16	;    |                    - A&lt;br /&gt;
	update_node 	y26	;    |    +---+     +---+   |&lt;br /&gt;
	load_node 	y06	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o&lt;br /&gt;
	update_node 	y16	;         +---+ x16 +---+  x26&lt;br /&gt;
&lt;br /&gt;
; allpass 8&lt;br /&gt;
	add_node 	y28	;&lt;br /&gt;
	mult_32		k8	;         y28   +---+ y18 +---+ &lt;br /&gt;
	subtr_node	x28	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+&lt;br /&gt;
	limit_store 	y08	;          |    +---+     +---+    |&lt;br /&gt;
	load_node 	x18	;          v                       |&lt;br /&gt;
	update_node 	x28	;   y06  +---+   +---+    +---+    | &lt;br /&gt;
	load_node 	y06	;  -&amp;gt;o--&amp;gt;| + |--&amp;gt;|*K8|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	update_node 	x18	;    |   +---+   +---+  + +---+   y08&lt;br /&gt;
	load_node 	y18	;    |                    - A&lt;br /&gt;
	update_node 	y28	;    |    +---+     +---+   |&lt;br /&gt;
	load_node 	y08	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o &lt;br /&gt;
	update_node 	y18	;         +---+ x18 +---+  x28 &lt;br /&gt;
	load_node 	x10	;&lt;br /&gt;
	ldi	YL,Low(DatTbl2)	;&lt;br /&gt;
&lt;br /&gt;
; allpass 1&lt;br /&gt;
	add_node 	y21	;&lt;br /&gt;
	mult_32		k1	;         y21   +---+ y11 +---+&lt;br /&gt;
	subtr_node	x21	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+&lt;br /&gt;
	limit_store 	y01	;          |    +---+     +---+    |&lt;br /&gt;
	load_node 	x11	;          v                       |&lt;br /&gt;
	update_node 	x21	;   x10  +---+   +---+    +---+    | &lt;br /&gt;
	load_node 	x10	;  -&amp;gt;o--&amp;gt;| + |--&amp;gt;|*K1|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	update_node 	x11	;    |   +---+   +---+  + +---+   y01&lt;br /&gt;
	load_node 	y11	;    |                    - A&lt;br /&gt;
	update_node 	y21	;    |    +---+     +---+   |&lt;br /&gt;
	load_node 	y01	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o&lt;br /&gt;
	update_node 	y11	;         +---+ x11 +---+  x21&lt;br /&gt;
&lt;br /&gt;
; allpass 3&lt;br /&gt;
	add_node 	y23	;&lt;br /&gt;
	mult_32		k3	;         y23   +---+ y13 +---+&lt;br /&gt;
	subtr_node	x23	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+&lt;br /&gt;
	limit_store 	y03	;          |    +---+     +---+    |&lt;br /&gt;
	load_node 	x13	;          v                       |&lt;br /&gt;
	update_node 	x23	;   y01  +---+   +---+    +---+    | &lt;br /&gt;
	load_node 	y01	;  -&amp;gt;o--&amp;gt;| + |--&amp;gt;|*K3|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	update_node 	x13	;    |   +---+   +---+  + +---+   y03&lt;br /&gt;
	load_node 	y13	;    |                    - A&lt;br /&gt;
	update_node 	y23	;    |    +---+     +---+   |&lt;br /&gt;
	load_node 	y03	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o&lt;br /&gt;
	update_node 	y13	;         +---+ x13 +---+  x23&lt;br /&gt;
&lt;br /&gt;
; allpass 5&lt;br /&gt;
	add_node 	y25	;&lt;br /&gt;
	mult_32		k5	;         y25   +---+ y15 +---+&lt;br /&gt;
	subtr_node	x25	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+&lt;br /&gt;
	limit_store 	y05	;          |    +---+     +---+    |&lt;br /&gt;
	load_node 	x15	;          v                       |&lt;br /&gt;
	update_node 	x25	;   y03  +---+   +---+    +---+    | &lt;br /&gt;
	load_node 	y03	;  -&amp;gt;o--&amp;gt;| + |--&amp;gt;|*K5|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	update_node 	x15	;    |   +---+   +---+  + +---+   y05&lt;br /&gt;
	load_node 	y15	;    |                    - A&lt;br /&gt;
	update_node 	y25	;    |    +---+     +---+   |&lt;br /&gt;
	load_node 	y05	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o&lt;br /&gt;
	update_node 	y15	;         +---+ x15 +---+  x25&lt;br /&gt;
&lt;br /&gt;
; allpass 7&lt;br /&gt;
	add_node 	y27	;&lt;br /&gt;
	mult_32		k7	;         y27   +---+ y17 +---+&lt;br /&gt;
	subtr_node	x27	;          o--&amp;lt;-|1/z|&amp;lt;-o--|1/z|&amp;lt;---+&lt;br /&gt;
	limit_store 	y07	;          |    +---+     +---+    |&lt;br /&gt;
	load_node 	x17	;          v                       |&lt;br /&gt;
	update_node 	x27	;   y05  +---+   +---+    +---+    | &lt;br /&gt;
	load_node 	y05	;  -&amp;gt;o--&amp;gt;| + |--&amp;gt;|*K7|---&amp;gt;| - |---&amp;gt;o---&amp;gt; &lt;br /&gt;
	update_node 	x17	;    |   +---+   +---+  + +---+   y07&lt;br /&gt;
	load_node 	y17	;    |                    - A&lt;br /&gt;
	update_node 	y27	;    |    +---+     +---+   | &lt;br /&gt;
	load_node 	y07	;    +----|1/z|--o-&amp;gt;|1/z|-&amp;gt;-o &lt;br /&gt;
	update_node 	y17	;         +---+ x17 +---+  x27&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* PWM - D/A-output&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
; output y07 to PWM-DAC&lt;br /&gt;
&lt;br /&gt;
;test: output y01&lt;br /&gt;
	ldd	accu3, Y+y01+1	;&lt;br /&gt;
;&lt;br /&gt;
	subi	accu3,$80	; signed to unsigned  $8000 -&amp;gt;$0000, $7FFF -&amp;gt;$FFFF&lt;br /&gt;
	sts	OCR1AH,zero	; &lt;br /&gt;
	sts	OCR1AL,accu3	; fast PWM 8 bit y07 output to OCR1A&lt;br /&gt;
	ldi	YL,Low(DatTbl1)	; back to 1st data table&lt;br /&gt;
; output y08 to PWM-DAC&lt;br /&gt;
;	load_node 	y08	; load y08&lt;br /&gt;
&lt;br /&gt;
; test outpt y02&lt;br /&gt;
	load_node 	y02	; load y02&lt;br /&gt;
;&lt;br /&gt;
	subi	datah,$80	; signed to unsigned  $8000 -&amp;gt;$0000, $7FFF -&amp;gt;$FFFF&lt;br /&gt;
	sts	OCR1BH,zero	; &lt;br /&gt;
	sts	OCR1BL,accu3	; fast PWM 8 bit y08 output to OCR1B&lt;br /&gt;
	cbi	PortD,0		; just to measure INT-Time&lt;br /&gt;
	out	SREG,savsrg	; restore status register&lt;br /&gt;
	reti			; &lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* coefficient table in flash memory&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
CoTblF:&lt;br /&gt;
	.dw 	15709 	 	; k2 *32768 (0,4794008655888)&lt;br /&gt;
	.dw 	28712	 	; k4 *32768 (0,8762184935393)&lt;br /&gt;
	.dw 	32001		; k6 *32768 (0,9765975895082)&lt;br /&gt;
	.dw 	32686	 	; k8 *32768 (0,9974992559356)&lt;br /&gt;
	.dw 	 5301	 	; k1 *32768 (0,1617584983677)&lt;br /&gt;
	.dw 	24020		; k3 *32768 (0,7330289323415)&lt;br /&gt;
	.dw 	30977 		; k5 *32768 (0,9453497003291)&lt;br /&gt;
	.dw 	32460	 	; k7 *32768 (0,9905991566845)&lt;br /&gt;
&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
;* data in SRAM&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
.dseg&lt;br /&gt;
.org	$0100&lt;br /&gt;
DatTbl1:&lt;br /&gt;
	; &amp;quot;allpass&amp;quot; 0&lt;br /&gt;
	.dw 	$0000 	 	; x10&lt;br /&gt;
	; allpass 2&lt;br /&gt;
	.dw 	$0000 	 	; x12&lt;br /&gt;
	.dw 	$0000 	 	; x22&lt;br /&gt;
	.dw 	$0000 	 	; y02&lt;br /&gt;
	.dw 	$0000 	 	; y12&lt;br /&gt;
	.dw 	$0000 	 	; y22&lt;br /&gt;
	; allpass 4&lt;br /&gt;
	.dw 	$0000 	 	; x14&lt;br /&gt;
	.dw 	$0000 	 	; x24&lt;br /&gt;
	.dw 	$0000 	 	; y04&lt;br /&gt;
	.dw 	$0000 	 	; y14&lt;br /&gt;
	.dw 	$0000 	 	; y24&lt;br /&gt;
	; allpass 6&lt;br /&gt;
	.dw 	$0000 	 	; x16&lt;br /&gt;
	.dw 	$0000 	 	; x26&lt;br /&gt;
	.dw 	$0000 	 	; y06&lt;br /&gt;
	.dw 	$0000 	 	; y16&lt;br /&gt;
	.dw 	$0000 	 	; y26&lt;br /&gt;
	; allpass 8&lt;br /&gt;
	.dw 	$0000 	 	; x18&lt;br /&gt;
	.dw 	$0000 	 	; x28&lt;br /&gt;
	.dw 	$0000 	 	; y08&lt;br /&gt;
	.dw 	$0000 	 	; y18&lt;br /&gt;
	.dw 	$0000 	 	; y28&lt;br /&gt;
CoTblS:&lt;br /&gt;
	.dw 	$0000 	 	; k2&lt;br /&gt;
	.dw 	$0000 	 	; k4&lt;br /&gt;
	.dw 	$0000		; k6&lt;br /&gt;
	.dw 	$0000	 	; k8&lt;br /&gt;
DatTbl2:&lt;br /&gt;
	.dw 	$0000	 	; k1&lt;br /&gt;
	.dw 	$0000		; k3&lt;br /&gt;
	.dw 	$0000 		; k5&lt;br /&gt;
	.dw 	$0000	 	; k7&lt;br /&gt;
	; allpass 1&lt;br /&gt;
	.dw 	$0000 	 	; x11&lt;br /&gt;
	.dw 	$0000 	 	; x21&lt;br /&gt;
	.dw 	$0000 	 	; y01&lt;br /&gt;
	.dw 	$0000 	 	; y11&lt;br /&gt;
	.dw 	$0000 	 	; y21&lt;br /&gt;
	; allpass 3&lt;br /&gt;
	.dw 	$0000 	 	; x13&lt;br /&gt;
	.dw 	$0000 	 	; x23&lt;br /&gt;
	.dw 	$0000 	 	; y03&lt;br /&gt;
	.dw 	$0000 	 	; y13&lt;br /&gt;
	.dw 	$0000 	 	; y23&lt;br /&gt;
	; allpass 5&lt;br /&gt;
	.dw 	$0000 	 	; x15&lt;br /&gt;
	.dw 	$0000 	 	; x25&lt;br /&gt;
	.dw 	$0000 	 	; y05&lt;br /&gt;
	.dw 	$0000 	 	; y15&lt;br /&gt;
	.dw 	$0000 	 	; y25&lt;br /&gt;
	; allpass 7&lt;br /&gt;
	.dw 	$0000 	 	; x17&lt;br /&gt;
	.dw 	$0000 	 	; x27&lt;br /&gt;
	.dw 	$0000 	 	; y07&lt;br /&gt;
	.dw 	$0000 	 	; y17&lt;br /&gt;
	.dw 	$0000 	 	; y27&lt;br /&gt;
;*************************************************************************&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Kategorie:AVR-Projekte]]&lt;br /&gt;
[[Category:DSP]]&lt;/div&gt;</summary>
		<author><name>Claus w</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Datei:Hilbert_FIR_Too_Small_Kernel.png&amp;diff=102894</id>
		<title>Datei:Hilbert FIR Too Small Kernel.png</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Datei:Hilbert_FIR_Too_Small_Kernel.png&amp;diff=102894"/>
		<updated>2021-01-09T20:48:09Z</updated>

		<summary type="html">&lt;p&gt;Claus w: /* Beschreibung */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Beschreibung ==&lt;br /&gt;
Phasenverschiebung zweier Sinus-Signale um jeweils 90° mit dem Hilbert-FIR-Transformator. Bei ausreichend großem Transformator-Kern (siehe https://www.mikrocontroller.net/articles/Datei:FIR_Kernel_Small.png für einen kleinen Kern) werden alle Signale um 90° bei gleicher und gleichbleibender Amplitude verschoben. Dieses Bild zeigt das Ergebnis, wenn der Filterkern zu klein ist (zuwenig Indexe hat). Er wirkt als Hochpass und die tiefere Frequenz (links im Bild) hat eine abweichende Amplitude.&lt;br /&gt;
&lt;br /&gt;
== Lizenz ==&lt;br /&gt;
{{Bild-frei}}&lt;/div&gt;</summary>
		<author><name>Claus w</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Datei:Hilbert_FIR_Too_Small_Kernel.png&amp;diff=102893</id>
		<title>Datei:Hilbert FIR Too Small Kernel.png</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Datei:Hilbert_FIR_Too_Small_Kernel.png&amp;diff=102893"/>
		<updated>2021-01-09T20:47:38Z</updated>

		<summary type="html">&lt;p&gt;Claus w: Phasenverschiebung zweier Sinus-Signale um jeweils 90° mit dem Hilbert-FIR-Transformator. Bei ausreichend großem Transformator-Kern (siehe https://www.mikrocontroller.net/articles/Datei:FIR_Kernel_Small.png für einen kleinen Kern) werden alle Signal…&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Beschreibung ==&lt;br /&gt;
Phasenverschiebung zweier Sinus-Signale um jeweils 90° mit dem Hilbert-FIR-Transformator. Bei ausreichend großem Transformator-Kern (siehe https://www.mikrocontroller.net/articles/Datei:FIR_Kernel_Small.png für einen kleinen Kern) werden alle Signale um 90° bei gleicher und gleichbleibender Amplitude verschoben. Dieses Bild zeigt das Ergebnis, wenn der Filterkern zu klein ist (zuwenig Indexe hat). Er wirkt als Hochpass und die Tiefere Frequenz (links im Bild) hat eine abweichende Amplitude.&lt;br /&gt;
== Lizenz ==&lt;br /&gt;
{{Bild-frei}}&lt;/div&gt;</summary>
		<author><name>Claus w</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Datei:Hilbert_FIR_OK_Lense.png&amp;diff=102892</id>
		<title>Datei:Hilbert FIR OK Lense.png</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Datei:Hilbert_FIR_OK_Lense.png&amp;diff=102892"/>
		<updated>2021-01-09T20:43:05Z</updated>

		<summary type="html">&lt;p&gt;Claus w: Phasenverschiebung zweier Sinus-Signale um jeweils 90° bei gleicher und gleichbleibender Amplitude. Für den Filterkern siehe https://www.mikrocontroller.net/articles/Datei:FIR_Kernel_Small.png. Zwischen den beiden Signalen erfolgt ein sprunghafter Ü…&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Beschreibung ==&lt;br /&gt;
Phasenverschiebung zweier Sinus-Signale um jeweils 90° bei gleicher und gleichbleibender Amplitude. Für den Filterkern siehe https://www.mikrocontroller.net/articles/Datei:FIR_Kernel_Small.png. Zwischen den beiden Signalen erfolgt ein sprunghafter Übergang der den Transformator überlastet. Es wird eine Art Sprungantwort ausgegeben.&lt;br /&gt;
== Lizenz ==&lt;br /&gt;
{{Bild-frei}}&lt;/div&gt;</summary>
		<author><name>Claus w</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Datei:Hilber_FIR_OK.png&amp;diff=102891</id>
		<title>Datei:Hilber FIR OK.png</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Datei:Hilber_FIR_OK.png&amp;diff=102891"/>
		<updated>2021-01-09T20:40:09Z</updated>

		<summary type="html">&lt;p&gt;Claus w: Phasenverschiebung zweier verschiedener Sinus-Signale um jeweils 90° und gleicher sowie gleichbleibender Amplitude mit dem selben Hilber-FIR-Transformator der beide Male auch mit den selben Parametern arbeitet (Siehe https://www.mikrocontroller.net/ar…&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Beschreibung ==&lt;br /&gt;
Phasenverschiebung zweier verschiedener Sinus-Signale um jeweils 90° und gleicher sowie gleichbleibender Amplitude mit dem selben Hilber-FIR-Transformator der beide Male auch mit den selben Parametern arbeitet (Siehe https://www.mikrocontroller.net/articles/Datei:FIR_Kernel_Small.png für den Filterkern).&lt;br /&gt;
== Lizenz ==&lt;br /&gt;
{{Bild-frei}}&lt;/div&gt;</summary>
		<author><name>Claus w</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Datei:FIR_Kernel_Big.png&amp;diff=102890</id>
		<title>Datei:FIR Kernel Big.png</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Datei:FIR_Kernel_Big.png&amp;diff=102890"/>
		<updated>2021-01-09T20:37:45Z</updated>

		<summary type="html">&lt;p&gt;Claus w: Großer Transformationskern eines Hilbert-Transformators nach der FIR-Methode. Einzelheiten siehe kleiner Transformationskern (https://www.mikrocontroller.net/articles/Datei:FIR_Kernel_Small.png).&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Beschreibung ==&lt;br /&gt;
Großer Transformationskern eines Hilbert-Transformators nach der FIR-Methode. Einzelheiten siehe kleiner Transformationskern (https://www.mikrocontroller.net/articles/Datei:FIR_Kernel_Small.png).&lt;br /&gt;
== Lizenz ==&lt;br /&gt;
{{Bild-frei}}&lt;/div&gt;</summary>
		<author><name>Claus w</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Datei:FIR_Kernel_Small.png&amp;diff=102889</id>
		<title>Datei:FIR Kernel Small.png</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Datei:FIR_Kernel_Small.png&amp;diff=102889"/>
		<updated>2021-01-09T20:35:23Z</updated>

		<summary type="html">&lt;p&gt;Claus w: Die Grafik zeigt den Transformationskern eines Hilbert-Transormators nach der FIR-Methode. Erzeugungsvorschrift: 
  k := 4 * x + 1; 
  x ... natürliche Zahl; 
  -k/2 &amp;lt;= n &amp;lt;= +k/2; n ... Position im Kern; 
  b_n := ( 1 - cos ( n * PI )  ) / ( n * PI );…&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Beschreibung ==&lt;br /&gt;
Die Grafik zeigt den Transformationskern eines Hilbert-Transormators nach der FIR-Methode. Erzeugungsvorschrift: &lt;br /&gt;
  k := 4 * x + 1; &lt;br /&gt;
  x ... natürliche Zahl; &lt;br /&gt;
  -k/2 &amp;lt;= n &amp;lt;= +k/2; n ... Position im Kern; &lt;br /&gt;
  b_n := ( 1 - cos ( n * PI )  ) / ( n * PI ); b_n ... Kern-Faktor an n-ter Position; Ausnahme b_n := 0 für n == 0;&lt;br /&gt;
 Anwendung:&lt;br /&gt;
  y[i] := Summe(-k/2 &amp;lt;= n &amp;lt;= k/2) mit x[i + n] * b[n]; Summe über alle Indexe &amp;quot;n&amp;quot;; x ... Eingabe; y ... Ergebnis&lt;br /&gt;
cos - Ausdruck: Argument immer gannzahlig, Vorzeichen alterniert, Differenz immer positiv, ungerade Zahlen Kern-Zahlen immer NULL, nahe der Mitte (n = 0), mit größerem &amp;quot;n&amp;quot; abnehmend. Ringpuffer verwenden!&lt;br /&gt;
&lt;br /&gt;
== Lizenz ==&lt;br /&gt;
{{Bild-frei}}&lt;/div&gt;</summary>
		<author><name>Claus w</name></author>
	</entry>
</feed>