1 | // PORTB-ON-CHANGE-INTERRUPT konfigurieren
|
2 | INTCON = 0b11100000; // Interruptregister setzen
|
3 | INTCON2 = 0b00000000; // Interruptregister setzen
|
4 | //Timer 0 Konfiguration + Starten
|
5 | T0CON = 0b11000000;
|
6 | [\c]
|
7 |
|
8 |
|
9 | Das 2 Thema ist, sobald mein Motor an ist, schwankt der Drehgeber zwischen ca. 3 Flanken. Und sendet deswegen Werte wie -00003 bis +00000 bis +00003.
|
10 |
|
11 | Mir fhelt logisch nicht an, wie ich meine Countervariable 4 mal speichere, und die erste und die letzte vergleiche, ob deren DIffernez größer 5 ist!?
|
12 | Kann mir jemand auf die Sprünge helfen?
|
13 |
|
14 | VIelen Dank schon einmal
|
15 |
|
16 | grüße
|
17 |
|
18 | Hier ist der komplette CODE
|
19 |
|
20 | [c]
|
21 | /** I N C L U D E S **********************************************************/
|
22 | #include "p18f2550.h" // PIC- Header
|
23 | #include "delays.h" // für Warteschleifen
|
24 | #include "usart.h" // für RS232- Schnittstelle
|
25 | #include "timers.h" // für Timerinterrupt
|
26 | #include "stdlib.h" // für Standardbibliothek
|
27 | /** Configuration Fuses********************************************************/
|
28 | #pragma config FOSC = HS // Quarz HS 20 MHZ an OSC1- OSC2
|
29 | #pragma config PWRT = ON // PowerOnTimer AN
|
30 | #pragma config BOR = OFF // BOR AUS
|
31 | #pragma config WDT = OFF // Watchdog Timer
|
32 | #pragma config LVP = OFF // Low Voltage ICSP AUS
|
33 | #pragma config PBADEN = OFF // PORTA Analogeingänge AUS
|
34 | #pragma config VREGEN = OFF // VREGEN AUS
|
35 | #pragma config MCLRE = ON // Master Reset AN
|
36 | #pragma config PLLDIV = 1 // PLLTeiler = 1 => 20 MHz
|
37 | #pragma config CPUDIV = OSC1_PLL2 // OSCTeiler = 1 => 20 MHz
|
38 | #pragma config USBDIV = 1 // CPUTeiler = 1 => 20 MHz
|
39 | /** Globale Variablendeklarationen*********************************************/
|
40 | signed long int counter = 0; // Zähler -2.147.483.648 bis 2.147.483.647
|
41 | signed long int counter_old = 0; // Vergleichszähler
|
42 | signed long int counter_test = 0;
|
43 | char ch0, ch1, ch2, ch3, ch4, ch5, ch6;
|
44 | char ch0 = '+'; // Vorzeichen
|
45 | char ch1 = '\n'; // Schlusszeichen
|
46 | char code = 0; // Graycode
|
47 | char new = 0; // Neuer Zustand
|
48 | char old = 0; // Alter Zustand
|
49 | /** Programm **************************************************/
|
50 | void high_isr(void);
|
51 | #pragma code high_vector=0x08
|
52 | void interrupt_at_high_vector(void)
|
53 | {
|
54 | _asm goto high_isr _endasm
|
55 | }
|
56 | #pragma code
|
57 | #pragma interrupt high_isr
|
58 | void high_isr (void)
|
59 | {
|
60 | new = (PORTBbits.RB6<<1) | (PORTBbits.RB7); // Kanal A + B einlesen
|
61 | code = (old<<2) | (new); // Graycode bilden
|
62 | switch (code) // Gray- Code Auswertung
|
63 | {
|
64 | case 0b00000001: counter++; break; // Drehung im Uhrzeigersinn
|
65 | case 0b00000111: counter++; break; // Drehung im Uhrzeigersinn
|
66 | case 0b00001110: counter++; break; // Drehung im Uhrzeigersinn
|
67 | case 0b00001000: counter++; break; // Drehung im Uhrzeigersinn
|
68 | case 0b00000010: counter--; break; // Drehung gegen den Uhrzeigersinn
|
69 | case 0b00000100: counter--; break; // Drehung gegen den Uhrzeigersinn
|
70 | case 0b00001101: counter--; break; // Drehung gegen den Uhrzeigersinn
|
71 | case 0b00001011: counter--; break; // Drehung gegen den Uhrzeigersinn
|
72 |
|
73 | // case 0b00000011: PORTCbits.RC2 = 1; break; // Fehler
|
74 | // case 0b00000110: PORTCbits.RC2 = 1; break; // Fehler
|
75 | // case 0b00001100: PORTCbits.RC2 = 1; break; // Fehler
|
76 | // case 0b00001001: PORTCbits.RC2 = 1; break; // Fehler
|
77 | // 0000 , 1111 , 0101 , 1010 keine Veränderung des Zustandes
|
78 | } // Ende Switch- Anweisung
|
79 | old = new; // Neuen Zustand als Alten Zustand speichern
|
80 | INTCONbits.TMR0IF = 0; // Interrupt zurücksetzen
|
81 | }
|
82 | void InitUsart(void) // Funktion USART Konfiguration
|
83 | {
|
84 | SPBRG = 20; // Baudrate 57600 Baud SPBRG- Berechnung 59524 = 20000000/(16*(20+1)) = Fehlerquote unter 5% ; 1 BIT = 1,74 µs ; 57600 Baud
|
85 | SPBRGH = 0; // 8 Bit Übertragung
|
86 | TRISCbits.TRISC6 = 1; // Aktivierung Senden TXD
|
87 | TRISCbits.TRISC7 = 1; // Aktivierung Empfangen RXD
|
88 | RCSTA = 0b10000100; // Empfangsregister konfigurieren
|
89 | TXSTA = 0b00100100; // Senderegister konfigurieren
|
90 | }
|
91 | void PICConfig(void) // Funktion PIC Konfiguration
|
92 | {
|
93 | // PORTA => Ausgänge LEDs RA0, RA4, RA5
|
94 | TRISA = 0x00; // PORT A Ausgänge deklarieren
|
95 | PORTA = 0x00; // PORT A auf Null setzen
|
96 | LATA = 0x00; // PORT A Latchregister auf Null setzen
|
97 | // PORTB => Eingänge Inkrementalgeber
|
98 | TRISB = 0xFF; // PORT B Ausgänge deklarieren
|
99 | PORTB = 0x00; // PORT B auf Null setzen
|
100 | LATB = 0x00; // PORT B Latchregister auf Null setzen
|
101 | // PORTC => alles Ausgänge RC0, RC1, RC2
|
102 | TRISC = 0x00; // PORT C Ausgänge deklarieren
|
103 | PORTC = 0x00; // PORT C auf Null setzen
|
104 | LATC = 0x00; // PORT C Latchregister auf Null setzen
|
105 | // PORTB-ON-CHANGE-INTERRUPT konfigurieren
|
106 | INTCON = 0b11100000; // Interruptregister setzen
|
107 | INTCON2 = 0b00000000; // Interruptregister setzen
|
108 | //Timer 0 Konfiguration + Starten
|
109 | T0CON = 0b11000000;
|
110 | return 0; // Rückgabewert (void) Konfiguration
|
111 | }
|
112 | void Senden(unsigned char byte) // Funktion für USART Senden
|
113 | {
|
114 | WriteUSART(byte); // Byte in RS232 Sendebyte schreiben
|
115 | while(BusyUSART( )); // Warten bis Sendebyte leer
|
116 | return 0; // Rückgabewert (void) Senden
|
117 | }
|
118 | void InttoChar(void) // Funktion INT in CHAR Umwandlung
|
119 | {
|
120 | int s1 = 0, s2 = 0, s3 = 0, s4 = 0, s5 = 0; // Counterstellenvariablen
|
121 | signed long int ncounter = 0; // Hilfscounter
|
122 | ncounter = counter/4; // Originalcounter zwischenspeichern
|
123 | if(ncounter == 0 || ncounter > 0) // Zähler positiv?
|
124 | {
|
125 | ch0 = '+'; // Vorzeichen positiv
|
126 | }
|
127 | if (ncounter < 0) // Zähler negativ?
|
128 | {
|
129 | ch0 = '-'; // Vorzeichen negativ
|
130 | ncounter = (ncounter*(-1)); // Invertieren
|
131 | }
|
132 | for(;ncounter > 9999;ncounter -= 10000) // Zehntausenderstellen
|
133 | {s1++;}
|
134 | for(;ncounter > 999;ncounter -= 1000) // Tausenderstellen
|
135 | {s2++;}
|
136 | for(;ncounter > 99;ncounter -= 100) // Hunderterstellen
|
137 | {s3++;}
|
138 | for(;ncounter > 9;ncounter -= 10) // Zehnerstellen
|
139 | {s4++;}
|
140 | for(;ncounter > 0;ncounter -= 1) // Einerstellen
|
141 | {s5++;}
|
142 | ch1 = s1 + 0x30; // Zehntausenderstelle CHAR zum Senden
|
143 | ch2 = s2 + 0x30; // Tausenderstelle CHAR zum Senden
|
144 | ch3 = s3 + 0x30; // Hunderterstelle CHAR zum Senden
|
145 | ch4 = s4 + 0x30; // Zehnerstelle CHAR zum Senden
|
146 | ch5 = s5 + 0x30; // Einerstelle CHAR zum Senden
|
147 | ch6 = '\n'; // Abschlusszeichen CHAR zum Senden
|
148 | // counter = ncounter; // Originalzähler zurückgeben
|
149 | return 0; // Rückgabewert (void) Umwandlung
|
150 | }
|
151 | void main(void) // Hauptprogramm starten
|
152 | {
|
153 | PICConfig(); // Konfigurieren der PORTs
|
154 | InitUsart(); // Start der USART- Schnittstelle
|
155 | PORTCbits.RC0 = 1; // Anschalten EIN/Aus Lampe
|
156 | //loop
|
157 | while(1) //Hauptschleife
|
158 | {
|
159 | // if(counter > 0)
|
160 | // { PORTAbits.RA4 = 1; }
|
161 | // if(counter < 0)
|
162 | // { PORTAbits.RA5 = 1; }
|
163 | counter_test = counter/4;
|
164 | while(counter_test != counter_old)
|
165 | {
|
166 | InttoChar(); // Zähler in chars zum Senden umwandeln
|
167 | Senden(ch0); // Senden Vorzeichen
|
168 | Senden(ch1); // Senden Zehntausender
|
169 | Senden(ch2); // Senden Tausender
|
170 | Senden(ch3); // Senden Hunderter
|
171 | Senden(ch4); // Senden Zehner
|
172 | Senden(ch5); // Senden Einer
|
173 | Senden(ch6); // Senden
|
174 | counter_old = counter_test;
|
175 | }
|
176 | PORTCbits.RC1 = 0; // LED Senden AUS
|
177 | PORTCbits.RC2 = 0; // LED Fehler AUS
|
178 | PORTAbits.RA4 = 0; // LED Rechts AUS
|
179 | PORTAbits.RA5 = 0; // LED Links AUS
|
180 | } // Ende Endlosschleife
|
181 | } /* Ende Mainfunktion */
|