So, nach gefühlten 30 days of night war es am Ende doch nicht so schwierig, den Takt über HW auszugeben
Dafür wird der Timer0 im fast PWM Modus mit OCRA als Top betrieben. Bei Comparematch wird der Ausgang OC0A getoggelt. UMVERDRAHTEN von PD2 nach PB2
Der Drehgeber verändert mit seinen Impulsen aus der Links-/Rechtsroutine heraus das OCRA Register und ändert damit die Frequenz. Wahrscheinlich hat sich die Wirkung der Drehrichtung geändert. Die Wahl fiel auf PWM Modus, da hier das Update des OCRA nicht sofort geschieht, sondern nur zu einem bestimmten TCNT0 Stand.
Da hatte ich auch gewisse Schwierigkeiten. Nach Datenblatt für Tiny2313 findet der Update bei Zählerstand Top statt. Nun ist OCRA aber Top. Was passiert, wenn getoggelt wird und "gleichzeitig" OCRA verändert wird. Konnte ich dem Datenblatt nicht entnehmen.
Den Fall wird es selten geben, aber er ist vorhanden und wird deshalb auch eintreten (nach Murphy - und nach Drehencoderbetätigung). Vielleicht macht es nichts - Ausprobieren.
Bei zB einem Mega88 wird das OCRA nach Datenblatt bei Bottom upgedated. Da hätte ich überhaupt keine Bedenken.
Ganz sicher bin ich mir wie immer nicht, ob ich den Rest richtig umgeschrieben habe.
Wenn Du ein langes Wochenende hast, könnte es jetzt gelaufen sein
PS: Und was ich gerade noch entdeckt habe: Mit der Angabe $baud initialisiert Bascom die Register für UART. Du hast den Encoder auf RX und TX hängen. Hat anscheinend bisher nichts ausgemacht. Um Verwicklungen zu vermeiden könnte man das auskommentieren. Hab ich gerade noch im Code oben gemacht.Code:' BASCOM-Programm ' Stefan Hoffmann 2009 ' Drehimpulsgeber/Encoder mit ENCODER-Befehl ' ' In: Drehimpulsgeber an d.0 und d.1 sowie Taster ' Testprogramm für A3967 Platine mit Dir Step und Enable ' Modifiziert von Searcher die dritte mit zusätzlichem Timer1 ' Timer0 für HW-Step Ausgabe auf PB2(OC0A) im fast PWM genutzt !!! ' UMVERKABELN: Taktausgabe nun auf PB2 statt PD6 $regfile = "attiny2313.dat" $framesize = 32 $swstack = 32 $hwstack = 34 '1. 32 nach 34 geändert $crystal = 8000000 'Interner Osz. 8 MHz '*** $baud = 9600 aktivieren nur wenn UART auch genutzt wird. ' Inputs: Drehimpulsgeber an d.0 und d.1 sowie Taster an d.3 '-----Deklarationen fuer Drehimpulsgeber: Config Pind.0 = Input Encoder_a Alias Pind.0 'Encoder Signal B an Pin 2 Config Pind.1 = Input Encoder_b Alias Pind.1 'Encoder Signal A an Pin 3 Config Pind.3 = Input Taster1 Alias Pind.3 'Taster Portd.0 = 1 'Pullups für den Drehencoder Portd.1 = 1 '2. pind nach portd geändert Portd.3 = 1 'LED-Outputs stellvertretend für Step, Dir, Enable 'In der endgültigen Hardware liegen: Step/Takt auf PD.2(PB.2) / Taster auf PD.3 / Enable auf PD4 / Richtung auf PD5 / Config Portb.2 = Output '!!!!!von PD2 nach PB2(OC0A) geändert !!!!!!!!!!!! Config Portd.5 = Output Portd.5 = 0 ' Pin 9 - Dir - Richtungssignal Config Portd.4 = Output Portd.4 = 0 ' Pin 16 - Enable - generelles Ein-Ausschaltsignal Config Portb.0 = Output Portb.0 = 0 'Pin 9 - LED_DE - am Drehencoder Anzeige Chip_dir Alias Portd.5 Chip_enable Alias Portd.4 Dim Wert As Byte 'statt word als byte declariert Wert = 127 'Mit mittlerer Geschwindigkeit anfangen, Startwert für den Drehencoder Dim Zustand As Byte '*****************Deklarationen für den Taster - am DE - für die Lang-kurz- und Doppelklickroutine Dim Zaehler As Byte Const Langzaehler = 100 'Danach gilt die Taste als lange gedrueckt Const Doppelzaehler = 20 'Innerhalb dessen muss zweiter Klick erfolgen Dim Gedrueckt As Byte 'Art des Drueckens (Kurz/Lang/Doppel) Const Kurz = 1 Const Lang = 2 Const Doppel = 3 Dim I As Byte Chip_enable = 1 'Motor aus Chip_dir = 1 'Dir '******************************************************************************* 'Neue Timer0 Konfiguration. Hab kein Bascom Kommando für Timer0 - Fast PWM und OC0A Toggle gefunden 'deshalb "zu Fuß" Tccr0a = Bits(com0a0 , Wgm01 , Wgm00) 'toggle OC0A, fast PWM Tccr0b = Bits(wgm02 , Cs02 , Cs00) 'fast PWM - top OCR0A, prescale 1024 '******************************************************************************* Const Anz_umschaltungen = 6 'Hier Anzahl der Laufrichtungsumschaltungen festlegen, mindestens 2 Dim Umschaltungen As Byte 'Zählt Laufrichtungsumschaltungen Umschaltungen = 0 'initialiesieren (ist aber an dieser Programmstelle sowieso = 0) Dim Sekunden As Byte 'Dient zum Abzählen von Sekunden in der Isr_Sekunden_takt Sekunden = 1 'initialisieren Config Timer1 = Timer , Prescale = 256 , Clear Timer = 1 'Clear Timer on Compare Match Compare1a = 31249 'Wert für eine Sekunde, Timer fängt nach einer Sekunde wieder bei 0 an On Compare1a Isr_sekunden_takt 'Compare1a Interrupt wird erst in der Haupschleife enabled Enable Interrupts '***********Hauptschleife:********** Do Zustand = Encoder(pind.0 , Pind.1 , Linksroutine , Rechtsroutine , 0) Debounce Taster1 , 0 , Tastenauswertung , Sub Select Case Gedrueckt 'Hier koennen beliebige Anweisungen erfolgen Case Kurz: 'Es wurde einmal kurz gedrueckt Chip_enable = 0 'Motor ein bei einmal kurz gedrückt Case Lang: 'Die Taste wurde lange gedrueckt If Timsk.ocie1a = 0 Then 'Wenn Comparematchinterrupt nicht enabled, dann.. Toggle Chip_dir 'Sofort Laufrichtung umschalten Incr Umschaltungen 'Zähler für Laufrichtungsumschaltungen erhöhen Timer1 = 0 'Timercounter von Beginn an laufen lassen Set Tifr.ocf1a Enable Compare1a 'ISR für Sekundenzählen und Chip_dir Toggle einschalten Else If Umschaltungen = Anz_umschaltungen Then 'Wenn genug Umschaltungen, dann aufhören Disable Compare1a 'Isr für Chip_dir toggle abschalten Sekunden = 1 'Für nächsten Gebrauch initialisieren Umschaltungen = 0 'Für nächsten Gebrauch initialisieren Gedrueckt = Kurz 'In Normallauf schalten End If End If Case Doppel: 'Die Taste wurde doppelt gedrueckt Chip_enable = 1 'Motor aus wenn doppelt gedrückt Disable Compare1a 'Isr für Chip_dir toggle abschalten Sekunden = 1 'Für nächsten Gebrauch initialisieren Umschaltungen = 0 'Für nächsten Gebrauch initialisieren End Select Loop End '**********************Interrupt-Routine Timer1 Sekundentakt ******************* Isr_sekunden_takt: 'ISR toggelt alle 6 Sekunden den Chip_dir If Sekunden < 6 Then 'solange noch keine 6 Mal durchlaufen ... Incr Sekunden '...nur inkrementieren Else 'sonst ... Sekunden = 1 'Sekundenzähler zurücksetzten und ... Toggle Chip_dir '... Laufrichtung umschalten Incr Umschaltungen 'Zähler für Laufrichtungsumschaltungen erhöhen End If Return '***********************Sub-Routinen Drehencoder ****************************** Linksroutine: If Wert > 21 Then Decr Wert Ocr0a = Wert Return Rechtsroutine: If Wert < 250 Then Incr Wert Ocr0a = Wert Return '*****************Subroutine Tasterauswertung ********************************** Tastenauswertung: Zaehler = 0 Do Incr Zaehler Waitms 10 Loop Until Taster1 = 1 Or Zaehler = Langzaehler If Zaehler = Langzaehler Then 'lange gedrueckt Gedrueckt = Lang Else 'einmal kurz gedrueckt Zaehler = 0 Do Incr Zaehler Waitms 10 Loop Until Taster1 = 0 Or Zaehler = Doppelzaehler If Zaehler = Doppelzaehler Then 'bleibt bei einmal kurz Gedrueckt = Kurz Else Gedrueckt = Doppel 'zweites Mal kurz gedrueckt End If End If Return
Gruß
Searcher







Hoffentlich liegt das Ziel auch am Weg
Zitieren

Lesezeichen