Re: Auswertung Inkrementaldrehgeber Kategorie: Programmierung C (von Hannes - 15.07.2008 15:40) | ||
Als Antwort auf Auswertung Inkrementaldrehgeber von Endress - 11.07.2008 10:44 | ||
| ||
Hi, ich hab bei meinem Mega32 einen Drehimpulsgeber (z.B Conrad 705538 - 62) angeschlossen, der funktioniert sehr gut. Schaltbild siehe Datenblatt! In dem Programm kann man Stunden und Minuten der Echtzeituhr mit dem Drehimpulsgeber einstellen. Gruss #define OK_button Port_ReadBit(21) // Drehimpulsgeber OK_Taster Port C.5 #define Drehimpg_SWAC Port_ReadBit(27) // Drehimpulsgeber Switch_AC Port D.3 #define Drehimpg_SWBC Port_ReadBit(20) // Drehimpulsgeber Switch_BC Port C.4 #define LED1_Ein Port_WriteBit(30,1) // Port D.6 #define LED1_Aus Port_WriteBit(30,0) // ------------ globale Variablen ------------------ byte cnt1; // Uhrzeit int Stunde, Minute, Sekunde; // Uhrzeit byte forward, reward; // Drehimpulsgeber: Zähler vorwärts, Z. rückwärts void main(void) // --------------- Hauptprogramm ------------------- { cnt1=0; // RTC, alle 10ms +1 Stunde=0; Minute=0; Sekunde=0; // Startzeit festlegen LCD_Init(); // Display initialisieren LCD_ClearLCD(); // Display löschen LCD_CursorOff(); // Display Cursor ausschalten Port_DataDirBit(27,0); // PortD.3 auf Eingang = INT1 = Switch_AC Port_DataDirBit(20,0); // PortD.4 auf Eingang = Switch_BC Port_DataDirBit(21,0); // PortD.5 auf Eingang = OK_Taster Port_DataDirBit(30,1); // Port D.6 auf Ausgang = LED1 Irq_SetVect(INT_1, Drehimpulsgeber); // INT1 setzen für Drehimpulsgeber Ext_IntEnable(1,1); // INT1: Mode 1 = steigende + fallende Flanke Irq_SetVect(INT_TIM2COMP,INT_10ms); // Interrupt Service Routine für RTC definieren Uhrzeit_einstellen(); } //-------------------------------------- Uhrzeit einstellen ---------------------------------------- void Uhrzeit_einstellen(void) { char text[3], text1[5], text2[5]; byte Stunde_alt, Minute_alt; text1 ="Std:"; text2 ="Min:"; do // Endlosschleife { LCD_WriteString(0x40, text1); // "Std:" aufs LCD Zeile 2, Spalte 1 ausgeben Stunde_alt=24; // "24" um aktuelle Stunde aufs LCD zu schreiben do { if (forward) // wenn forwärts gedreht wurde { forward=0; // wieder löschen für nächsten IRQ Stunde++; // Stunde +1 if (Stunde>23) Stunde=23; // Stunde (max) = 23 } if (reward) // wenn rückwärts gedreht wurde { reward=0; Stunde--; // Stunde -1 if (Stunde < 0) Stunde = 0; // Stunde (min) = 0 } if ( Stunde != Stunde_alt) // Stunde nur aufs LCD schreiben { // wenn sich der Wert geändert hat Str_WriteWord(Stunde,10,text,0,2); LCD_WriteString(0x44, text); Stunde_alt = Stunde; } } while(OK_button); // weiter wenn OK_Taster gedrückt, // sonst Schleife erneut ausführen while(!OK_button); // weiter wenn OK_Taster losgelassen LCD_WriteString(0x40, text2); // "Min:" aufs LCD Zeile 2, Spalte 1 ausgeben Minute_alt=60; do // die selbe Schleife für Minute { if (forward) { forward=0; Minute++; if (Minute > 59) Minute = 59; // Minute (max) = 59 } if (reward) { reward=0; Minute--; if (Minute < 0) Minute = 0; // Minute (min) = 0 } if ( Minute != Minute_alt) { Str_WriteWord(Minute,10,text,0,2); LCD_WriteString(0x44, text); Minute_alt = Minute; } } while(OK_button); while(!OK_button); } while(1); } /*----------------------------------------- LCD: WriteString --------------------------------------- Ausgabe eines Textes aufs LCD-Display an LCD-Position. �bergabe der Parameter LCD-Position und des Textes. */ void LCD_WriteString(byte LCD_Pos, char text[]) { LCD_CursorPos(LCD_Pos); LCD_WriteText(text); } /*------------------------------------------ Drehimpulsgeber --------------------------------------- Die Funktion wird immer dann aufgerufen, sobald der Drehimpulsgeber links oder rechts gedreht wird. Schalter AC liegt an INT1, bei einer steigenden oder fallenden Flanke wird diese Funktion aufgerufen, und es werden die Schalter AC und BC eingelesen und verglichen ob vorwärts oder rückwärts gedreht wurde. Wurde vorwärts (rechts) gedreht wird die globale Variable forward um 1 erhöht, entsprechend reward bei rückwärts (links). */ void Drehimpulsgeber(void) { Ext_IntDisable(1); // INT1 sperren byte in1, in2; int irqcnt1; // Drehimpulsgeber in1 = Drehimpg_SWAC; // Switch_AC = PortD.3 einlesen in2 = Drehimpg_SWBC; // Switch_BC = PortC.4 einlesen if (in1 != in2) // es wurde vorwärts gedreht forward++; else reward++; // es wurde rückwärts gedreht Ext_IntEnable(1,1); // INT1 freigeben irqcnt1=Irq_GetCount(INT_1); } //-------------------------------------- Echtzeituhr ----------------------------------------------- void RTC(void) { cnt1++; if (cnt1==50) LED1_Ein; if (cnt1==100) { Display_Time(); Sekunde++; if (Sekunde==60) { Sekunde=0; Minute++; if (Minute==60) { Minute=0; Stunde++; if (Stunde==24) Stunde=0; } } cnt1=0; LED1_Aus; } } // Ausgabeformat der Uhr festlegen void Display_Time(void) { Write2Digits(0,Stunde); // Stunde LCD_WriteChar(':'); Write2Digits(3,Minute); // Minute LCD_WriteChar(':'); Write2Digits(6,Sekunde); // Sekunde } // Zeichenausgabe void Write2Digits(byte pos,byte val) { char num[3]; LCD_CursorPos(pos); // LCD Cursor positionieren Str_WriteWord(val,10,num,0,2); // Zahl mit Basis 10, Offset 0, 2 stellig in String schreiben LCD_WriteText(num); // String ausgeben } //--------------------------------- Interrupt alle 10ms --------------------------------------------- void INT_10ms(void) { int irqcnt; RTC(); // Funktionsaufrauf: RTC irqcnt=Irq_GetCount(INT_TIM2COMP); // Interrupt Request Counter } | ||
Antwort schreiben Antworten: Re: Auswertung Inkrementaldrehgeber (von UlliS - 15.07.2008 16:00) Re: Auswertung Inkrementaldrehgeber (von Hannes - 16.07.2008 7:53) Re: Auswertung Inkrementaldrehgeber (von UlliS - 16.07.2008 15:16) Re: Auswertung Inkrementaldrehgeber (von Endress - 22.07.2008 14:04) |
Zur Übersicht - INFO - Neueste 50 Beiträge - Neuer Beitrag - Suchen - Zum C-Control-I-Forum - Zum C-Control-II-Forum