Hallo,
nachdem mir die Suchfunktion nicht mehr weiterhelfen kann und auch meine
Bekannten mir nicht mehr helfen konnten wende ich mich mit meinem
Problem ans Forum.
Ich habe die Aufgabe 2 4-schrittige Quadraturencoder auszulesen und
diese Daten an den Rechner zu schicken, damit eine Weiterverarbeitung in
Labview folgen kann. Das Programm zum Auslesen basiert auf dem
Beispielcode von Peter Dannegger. Zur Kommunikation mittels Uart
verwende ich fertige Dateien und Initialisierungsbefehle von Peter
Fleury.
Ich verwende einen ATMega 168 Crumb Modul. Dieses Modul trägt den
ATMega168 einen UART zu USB Wandler und ein Quarz das, auf 20 MHz
taktet.
Die Versuche Strings per UART in der Mainmethode zu senden waren
erfolgreich und konnten mit Putty angezeigt werden.
Es sollte ein Programm folgen, dass über Interrupts die Encoder
ausliest, und die Werte sendet.
Ich möchte Timer 0 verwenden um die Encoder auszulesen und Timer 2 um
die akkumulierten Werte auszugeben.
Um eine Beschädigung der Encoder vollständig auszuschließen. Wird das
Programm getestet, ohne dass sie angeschlossen sind. Es müsste die
durchgehende Ausgabe des Wertes 0 für jeden Encoder folgen.
Leider funktioniert nichts. Putty detektiert keine Datenausgabe des
Mikrocontrollers. Die Kompilierung des C-Programms erzeugt 0 Warnungen.
Wo liegt der logische Fehler in diesem Programm?
gruß Christoph
1 | #include <avr/io.h>
|
2 | #include <avr/interrupt.h>
|
3 | #include <stdlib.h>
|
4 | #include "uart.h"
|
5 |
|
6 |
|
7 | #ifndef F_CPU
|
8 |
|
9 | #warning "F_CPU war noch nicht definiert, wird nun nachgeholt mit 20000000"
|
10 | #define F_CPU 20000000UL // Systemtakt in Hz - Definition als unsigned long beachten
|
11 | // Ohne ergeben sich unten Fehler in der Berechnung
|
12 | #endif
|
13 |
|
14 | #define UART_BAUD_RATE 9600
|
15 | //Target Atmega 168
|
16 |
|
17 |
|
18 |
|
19 | #define PHASE_A1 (PINC & 1<<PINC0)
|
20 | #define PHASE_B1 (PINC & 1<<PINC1)
|
21 | #define PHASE_A2 (PINC & 1<<PINC2)
|
22 | #define PHASE_B2 (PINC & 1<<PINC3)
|
23 |
|
24 |
|
25 |
|
26 | int8_t enc_delta1; //-128 ... 127
|
27 | int8_t enc_delta2;
|
28 | int8_t Wert1 = 0;
|
29 | int8_t Wert2 = 0;
|
30 | char out1[4] ;
|
31 | char out2[4] ;
|
32 |
|
33 | void encode_init(void)
|
34 | {
|
35 | TCCR2B = (1<<WGM22) | (1<<CS22) | (1<<CS21) | (1<<CS20);
|
36 | OCR2B = 10;
|
37 | TCCR0B = (1<<WGM01) | (1<<CS02) | (1<<CS00);
|
38 | OCR0B = 1;
|
39 | TIMSK2 = 1<<OCIE2B;
|
40 | TIMSK0 = 1<<OCIE0B;
|
41 | //beide Zähler initialisieren
|
42 | }
|
43 |
|
44 |
|
45 | ISR (TIMER2_COMPB_vect) //Abtastzeit
|
46 | {
|
47 | static int8_t last1;
|
48 | static int8_t last2;
|
49 | int8_t new1,diff1;
|
50 | int8_t new2,diff2;
|
51 | new1 = 0;
|
52 | if(PHASE_A1)
|
53 | new1 = 3;
|
54 | if(PHASE_B1)
|
55 | new1 ^=1; //convert grey to binary
|
56 | diff1 = last1 -new1; //difference last - new
|
57 | if (diff1 & 1){ //bit 0 = value (1)
|
58 | last1 = new1; //store new as next last
|
59 | enc_delta1 += (diff1 & 2) -1; //bit 1 = direction(+/-)
|
60 | }
|
61 |
|
62 | new2 = 0;
|
63 | if(PHASE_A2)
|
64 | new2 = 3;
|
65 | if(PHASE_B2)
|
66 | new2 ^=1; //convert grey to binary
|
67 | diff2 = last2 -new2; //difference last - new
|
68 | if (diff2 & 1){ //bit 0 = value (1)
|
69 | last2 = new2; //store new as next last
|
70 | enc_delta2 += (diff2 & 2) -1; //bit 1 = direction(+/-)
|
71 | }
|
72 |
|
73 | }
|
74 |
|
75 | ISR (TIMER0_COMPB_vect){ //Interrupt, der per UART daten an den PC sendet
|
76 | cli();
|
77 | itoa(Wert1,out1,10);
|
78 | itoa(Wert2,out2,10);
|
79 | uart_puts(out1);
|
80 | uart_puts("\r\n");
|
81 | uart_puts(out2);
|
82 | uart_puts("\r\n");
|
83 | Wert1 = 0;
|
84 | Wert2 = 0;
|
85 | sei();
|
86 | }
|
87 |
|
88 |
|
89 |
|
90 | int8_t encode_read1(void) //read four step encoders
|
91 | {
|
92 | int8_t val1;
|
93 | cli();
|
94 | val1 = enc_delta1;
|
95 | enc_delta1 &= 3;
|
96 | sei();
|
97 | return val1 >> 2;
|
98 | }
|
99 |
|
100 | int8_t encode_read2(void) //read four step encoders
|
101 | {
|
102 | int8_t val2;
|
103 | cli();
|
104 | val2 = enc_delta2;
|
105 | enc_delta2 &= 3;
|
106 | sei();
|
107 | return val2 >> 2;
|
108 | }
|
109 |
|
110 | int main(void)
|
111 | {
|
112 |
|
113 | encode_init();
|
114 | uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) );
|
115 |
|
116 | sei();
|
117 |
|
118 | while(42){
|
119 |
|
120 | Wert1 =Wert1 + encode_read1();
|
121 | Wert2 =Wert2 + encode_read2();
|
122 | }
|
123 |
|
124 | return 0;
|
125 | }
|