Auswertung Drehimpulsgeber ohne Interrupt und Delay Kategorie: Programmierung Basic (von Montelucon - 11.11.2008 20:33) | ||
| ||
Hallo zusammen, da ich leider immer noch nicht weiÃ?, wie man auf Port C.5 der C-Contol Pro Mega 32 einen Interrupt legt, bzw. wie man diesen daran auswertet, habe ich mir meinen eigenen Code geschrieben. Der Code ist getestet und funktioniert sehr gut. Vor allem da er ohne Delay auskommt, kann der Geber sehr schnell oder sehr langsam gedreht werden und funktioniert dennoch. Ich weiÃ? aber nicht, ob er nicht noch optimiert werden kann. Falls also jemand eine bessere Idee hat, immer her damit. Ã?ber einen Schalter, der im Inkrementalgeber integriert ist, wird die Impulszählung aktiviert und auch wieder deaktiviert. Am LCD wird der Zählerstand angezeigt und die beiden LEDs kennzeichnen die Aktivierung, bzw. Deaktivierung. Und falls der Code oder eine Abwandlung davon von jemanden verwendet wird, würde mich eine Nachricht hier freuen. Mich interessiert schon, ob der Beitrag hier jemanden helfen konnte. Hier noch ein Link zu einem Beitrag, bei dem das gleiche Problem mit Interrupt auf Port C.4 gelöst wurde. gehe zu Beitrag » GruÃ? Monte Hier der Code für die CC-Pro Mega 32: ' PORTBELEGUNG: ' Ausgang A wird auf Port C.5, Ausgang B auf Port C.6 gelegt ' Der extra Schalter liegt auf Port C.7 ' TECHNIK: ' Signale des Gebers (Conrad Best.Nr. 705538): ' Ausgang B: ----____----____----____----____----____- ' Ausgang A: _----____----____----____----____----____ ' RastPos.: _|___|___|___|___|___|___|___|___|_ ' 1 2 3 4 5 6 7 8 n ' Es wird gegen Masse geschaltet => gedrückt=0 / nicht gedrückt=1 (invertierte Logik) ' SONSTIGES: ' Benötigte Bibliotheken: IntFunc_Lib.cc & LCD_Lib.cc ' Bei Drehrichtung "links" geht das erste Bit leider verloren. ' ACHTUNG: Die internen PullUp sind deaktiviert! Bitte Geber gemäÃ? Schaltplan ' des Herstellers anschlieÃ?en. (Kondensatoren, Widerstände, +5V, Masse) ' ----------------------------------------------------------------------- ' Ports für Inkremenatalgeber definieren ' #define SW_P Port_ReadBit(23) ' Port C.7 Eingabeport #define SW_B Port_ReadBit(22) ' Port C.6 Eingabeport #define SW_A Port_ReadBit(21) ' Port C.5 Eingabeport ' ----------------------------------------------------------------------- ' Ports für LEDs definieren ' #define LED1_Aus Port_WriteBit(31,1) ' Port D.7 aus #define LED1_Ein Port_WriteBit(31,0) ' Port D.7 an #define LED2_Aus Port_WriteBit(30,1) ' Port D.6 aus #define LED2_Ein Port_WriteBit(30,0) ' Port D.6 an ' ----------------------------------------------------------------------- ' Variablen für Inkremenatalgeber definieren ' Dim counter As Integer ' Zähler ' ----------------------------------------------------------------------- ' Variablen für LCD definieren ' Dim zahlalstext(9) As Char ' Charakter für LCD definieren (Zahl als Text) ' ----------------------------------------------------------------------- ' Hauptprogramm ' Sub main() Port_DataDirBit(31,1) ' Port D.7 auf Ausgang = LED1 an Port_DataDirBit(30,1) ' Port D.6 auf Ausgang = LED2 an LCD_Reset() ' LCD initialisieren counter = 35 ' Zähler initialisieren requestInput() ' Gehe zu: warten bis Schalter "P" gedrückt End Sub ' ----------------------------------------------------------------------- ' Endlosschleife zum Abfragen des Schalterausgang "P" (quasi Standby) ' Sub requestInput() Do While SW_P = 0 ' Quasi Entprellen End While LED2_Ein ' LED 2 einschalten LED1_Ein ' LED 1 einschalten Do While 1 ' Endlosschleife, bis Schalter gedrückt If SW_P = 0 Then ' Wenn Schalter gedrückt, Schleife beenden Exit End If End While requestGeber() ' Wenn Schalter gedrückt, frage den Geber ab End Sub ' ----------------------------------------------------------------------- ' Endlosschleife zum Abfragen des Inkrementalgebers Schalter "A" + "B" ' Sub requestGeber() Do While SW_P = 0 ' Quasi Entprellen End While LED2_Aus ' LED 2 ausschalten LED1_Aus ' LED 1 ausschalten LCD_print(counter) ' "counter" am LCD anzeigen Do While 1 ' Endlosschleife, bis Schalter "P" gedrückt wird If SW_P = 0 Then ' Wenn Schalter "P" gedrückt -> Abbruch requestInput() Exit End If If SW_B <> SW_A Then ' Mache nur, wenn Schalter in Bewegung If SW_B = 1 Then ' Nur wenn Schalter "B" nicht gedrückt Do ' Warte auf Zustandsänderung If SW_P = 0 Then ' Wenn Schalter "P" gedrückt -> Abbruch requestInput() End If Loop While SW_B If SW_A = 1 Then ' Auswertung "rechts" / "links" counter = counter - 1 Else counter = counter + 1 End If LCD_print(counter) ' Am LCD anzeigen End If End If ' Dieser Teil ist nur nötig, wenn die Periodendauer eines Schaltzyklus ' zwei Restpositionen dauert. Bei Periode = Rastposition kann der Teil ' gelöscht werden. ' -------------------------------------------------------------------- If SW_B <> SW_A Then If SW_B = 0 Then Do ' Warte auf Zustandsänderung If SW_P = 0 Then ' Wenn Schalter "P" gedrückt -> Abbruch requestInput() End If Loop While SW_B = 0 If SW_A = 0 Then ' Auswertung "rechts" / "links" counter = counter - 1 Else counter = counter + 1 End If LCD_print(counter) ' Am LCD anzeigen End If End If ' -------------------------------------------------------------------- End While End Sub ' ----------------------------------------------------------------------- ' LCD-Ausgabe ' Sub LCD_print(zahl As Integer) LCD_ClearLCD() ' LCD Display löschen Str_WriteWord(zahl,10,zahlalstext,0,1) ' Zahl in Text wandeln LCD_CursorPos(&H0) ' Cursor auf Zeile 1 Pos 0 LCD_WriteText(zahlalstext) ' Text schreiben End Sub ' ----------------------------------------------------------------------- ' LCD Initialisieren ' Sub LCD_Reset() LCD_Init() ' LCD high-level Initialisierung LCD_ClearLCD() ' LCD Display löschen LCD_CursorOff() ' Curser ausschalten End Sub | ||
Antwort schreiben Antworten: Re: Auswertung Drehimpulsgeber ohne Interrupt und Delay (von PeterS - 12.11.2008 9:50) Re: Auswertung Drehimpulsgeber ohne Interrupt und Delay (von Montelucon - 12.11.2008 12:50) |
Zur Übersicht - INFO - Neueste 50 Beiträge - Neuer Beitrag - Suchen - Zum C-Control-I-Forum - Zum C-Control-II-Forum