Hallo Ralf,
so eine TI DSP habe ich auch schon mal programmiert. Das wäre allerdings hier etwas Overkill.

Aber wenn du das 10 Jahre gemacht hast, kann ich ja frei von der Leber weg erklären.
Vorbemerkung: Die Markierung der Nockenwellenscheibe passiert den Reflexkoppler 36° vor OT. Das wird mittels Strobokop eingestellt. Der Prozessor wartet im Prinzip so lange, bis der Motor sich an die richtige Stelle gedreht hat, dann wird die Zündung ausgelöst.
Der Controller misst nicht die Drehzahl, sondern die Periodendauer zwischen zwei steigenden Flanken, die der Reflexkoppler liefert. Diese Periodendauern (T) folgen der Drehzahl bzw. Winkelfrequenz (f) nichtlinear. logisch Daher muss T in f umgerechnet werden um einen linearen Offset für das Kennfeld zu erreichen. Da mich aber eigentlich auch die Drehzahl nicht interessiert, wird T nicht in f umgerechnet sondern mittels einer Division linearisiert. Dabei ist der Dividend so zu wählen, dass günstige Werte, die einen Arrayoffset bilden können, entstehen. (0,1,2,3...62,63)
T wird mittels eines 16-Bit Timers ermittelt. Ein externer Interrupt, der durch den Reflexkoppler ausgelöst wird, holt den aktuellen Timerwert und setzt den Timer auf 0 zurück. Der Timerwert entspricht dann der Periodendauer. Der selbe Timer löst auch den Zündimpuls mittels eines Compare-Ereignisses aus. Um dieses Ereignis zu erzeugen, wird ein Comparewert benötigt, der der Drehzahl und dem gewünschten Zündzeitpunkt entspricht.
Dieser Comparewert wird dann zur Laufzeit aus T und dem Wert im Kennfeld (Zündwinkel) errechnet.
Dadurch ist sichergestellt, das durch Drehzahlschwankungen, die nicht mehr aufgelöst werden können, der Zündzeitpunkt immer dem Wert im Kennfeld entspricht. Die Auflösung beträgt bei mir 0,65°.
kurzer Ablauf:
1. neues T ermittelt und retten -> T'
2. T linearisieren (Offset = X / T)
3. mittels Offset, Zündzeitpunkt aus Kennfeld holen (Arrayindex)
4. T' mit X multiplizieren und durch 4096 teilen (warum steht unten)
5. (T' * X) / 4096 = Comparewert
6. Comparewert in Compareregister schreiben
7. Zündung erfolgt bei Compare Ereignis
Da der Controller ja keine Fließkommas verarbeiten kann, wird der Zündwinkel umgerechnet. Ich lasse das ganze Kennfeld mit EXCEL ausrechnen und kopiere es dann in den Controller. Die 2048 ergeben bei meiner Dimensionierung Werte von 0 bis 205 (8-Bit).
Formel:
X = gewünschter Zündwinkel
( ( (36° - X°) * 2048 ) / 360° ) = Zündwinkel im Kennfeld
Das Teilen durch 4096 bzw. 2*2048 ist nötig um die Erweiterung wieder herauszurechnen. Außerdem dreht die Nockenwelle nur halb so schnell wie der Motor, das muss berücksichtigt werden.
In "Version 1" habe ich einfach anhand der Drehzahl direkt den Comparwert aus dem Kennfeld gelesen. Das funktionierte aber sehr schlecht, besonders bei niedrigen Drehzahlen. Der Zündzeitpunkt sprang fürchterlich vor und zurück. Man müsste ein enormes Kennfeld mit enorm vielen Einträgen machen um den Jitter wegzubekommen. Jetzt hat das Kennfeld nur noch ein Viertel der größe und dennoch ist die Auflösung besser.
Ich hatte zunächst fürchterliche Störungen, trotz sauberer Masseführung. Nichts hat geholfen. Der Stromanstieg der ja auch durch die Masse muss war zu schnell und zu heftig und hat alles gestört. (Servos, Fernsteuerung, Multimeter) Auch Schirmung war sinnlos. Das Problem war die enorme Größe der Masseleitung (Chassis). Sie hat als Antenne gewirkt. Ohne Chassis als Masse gab es nicht die geringste Störung. Das ließ sich aber letzlich ganz einfach mittels Entstörwiderstand von 4,7k (Kohleschicht, Metallfilm schlägt durch) beheben. Seitdem iss absolute Ruhe. Natürlich, sollten dennoch die bekannten "Masseregeln" eingehalten werden.
Wenn du was nich verstanden, oder noch fragen hast, meld dich einfach.
Gruß Paul