Hallo ich bin Schüler und wir haben gerade mit der AVR Programmierung angefangen (in C). Jeder hat sein eigenes Projekt bekommen und er soll es bis zu einem gewissen Datum fertig stellen. Ich habe eine FSM Logic für den Drehimpulsgeber gemacht. Wir haben es letztes Schuljahr auf ein GAL gebrannt und es hat funktioniert. Jetzt bekomme ich jedoch beim ATMEGA 8 ein paar Probleme. Und zwar zählt er bei mir öfters rechts statt links egal in welche Richtung ich drehe. Ich bin schon am verzweifeln warum das so ist. Ich füge mal mein C Quelltext ein um es zu zeigen. Ich habe schon geguckt aber ich habe es ncht hinbekommen das es funktioniert. Ich habe schon im Forum geguckt aber das habe ich alles nicht verstanden, weil es auf Atmega 16 oder auch auf anderen Mikrokontrollern für gemacht worden ist. Und irgendwie muss ich das auch erklären können, deswegen hab ich das mit der FSM gemacht. Ich hoffe das jemand mir helfen kann.
1 | #include <avr\io.h> |
2 | #include "libbko_lcd.h" |
3 | #include <util\delay.h> |
4 | #include <avr/interrupt.h> |
5 | |
6 | unsigned int iZahl=20; |
7 | int time; |
8 | |
9 | int main (void) |
10 | {
|
11 | DDRD = 0x00; //Auf Eingang setzten (B) |
12 | DDRC = 0xFF; //Auf Ausgang setzten (C) |
13 | |
14 | |
15 | //PORTC = 0xFF; //Pull ups aktivieren
|
16 | //Bei 0xFF ist Pull up aktiviert
|
17 | //Bei 0x00 ist Pull up deaktiviert
|
18 | |
19 | int tempA;//= 0x00; |
20 | int tempB;//= 0x00; |
21 | int tempC;//= 0x00; |
22 | |
23 | int iDreh = 20; |
24 | |
25 | ///ZUSTÄNDE
|
26 | int ruhe = 0; //RUHE |
27 | int links1 = 1; //Links 1 |
28 | int links2 = 2; //Links 2 |
29 | int rechts1 = 3; //Rechts 1 |
30 | int rechts2 = 4; //Rechts 2 |
31 | |
32 | |
33 | |
34 | //NEU
|
35 | // Timer 0 konfigurieren
|
36 | TCCR0 = (1<<CS01); // Prescaler 8 |
37 | |
38 | |
39 | // Overflow Interrupt erlauben
|
40 | TIMSK |= (1<<TOIE0); |
41 | |
42 | // Global Interrupts aktivieren
|
43 | sei(); |
44 | |
45 | lcd_init(); |
46 | |
47 | int zustand = 0; //Aktueller Zustand |
48 | |
49 | PORTC = 0xFF; |
50 | |
51 | while(1) |
52 | {
|
53 | |
54 | tempA = PIND & 1; //0b0000000X |
55 | tempB = PIND & 1<<1; //0b000000X0 |
56 | tempC = PIND & 1<<2; //0b00000X00 |
57 | |
58 | if(iDreh == 23) |
59 | {
|
60 | iZahl++; |
61 | |
62 | iDreh=20; |
63 | |
64 | lcd_reset(); |
65 | _delay_ms(50); |
66 | lcd_ausgabe(iZahl); |
67 | }
|
68 | |
69 | if(iDreh == 17) |
70 | {
|
71 | iZahl--; |
72 | |
73 | iDreh=20; |
74 | |
75 | lcd_reset(); |
76 | _delay_ms(50); |
77 | lcd_ausgabe(iZahl); |
78 | }
|
79 | |
80 | switch (zustand) |
81 | {
|
82 | case 0: //Ruhe |
83 | //lcd_puts("ruhe = 0");
|
84 | PORTC = 0b00000001; |
85 | if((PIND & 1)==0b00000000 && (PIND & 1<<1)==0b00000010) //A=0 B=1 |
86 | {
|
87 | //Links 1
|
88 | zustand = links1; |
89 | }
|
90 | else if((PIND & 1)==0b00000001 && (PIND & 1<<1)==0b00000000) //A=1 B=0 |
91 | {
|
92 | //Rechts 1
|
93 | zustand = rechts1; |
94 | }
|
95 | else
|
96 | {
|
97 | //Ruhe
|
98 | zustand = ruhe; |
99 | }
|
100 | |
101 | |
102 | |
103 | break; |
104 | case 1: //Links 1 |
105 | //lcd_puts("links1 = 1");
|
106 | PORTC = 0b00000010; |
107 | if((PIND & 1)==0b00000001 && (PIND & 1<<1)==0b00000000) //A=1 B=0 |
108 | {
|
109 | //Links 2
|
110 | zustand = links2; |
111 | }
|
112 | else if((PIND & 1)==0b00000000 && (PIND & 1<<1)==0b00000010) //A=0 B=1 |
113 | {
|
114 | //Links 1
|
115 | zustand = links1; |
116 | }
|
117 | else if((PIND & 1)==0b00000000 && (PIND & 1<<1)==0b00000000) //A=0 B=0 |
118 | {
|
119 | //Links 1
|
120 | zustand = links1; |
121 | }
|
122 | else
|
123 | {
|
124 | //Ruhe
|
125 | //zustand=links1;
|
126 | zustand = ruhe; |
127 | }
|
128 | |
129 | break; |
130 | case 2: //Links 2 |
131 | //lcd_puts("links2 = 2");
|
132 | PORTC = 0b00010011; |
133 | |
134 | //Ruhe
|
135 | zustand = ruhe; |
136 | |
137 | iDreh --; |
138 | /*
|
139 | lcd_reset();
|
140 | _delay_ms(50);
|
141 | lcd_ausgabe(iZahl);
|
142 | */
|
143 | //_delay_ms(100);
|
144 | //lcd_puts("links");
|
145 | //_delay_ms(500);
|
146 | |
147 | break; |
148 | case 3: //Rechts 1 |
149 | PORTC = 0b00000100; |
150 | //lcd_puts("rechts1 = 3");
|
151 | |
152 | if((PIND & 1)==0b00000000 && (PIND & 1<<1)==0b00000010) //A=0 B=1 |
153 | {
|
154 | //Rechts 2
|
155 | zustand = rechts2; |
156 | }
|
157 | else if((PIND & 1)==0b00000001 && (PIND & 1<<1)==0b00000000) //A=1 B=0 |
158 | {
|
159 | //Rechts 1
|
160 | zustand = rechts1; |
161 | }
|
162 | else if((PIND & 1)==0b00000000 && (PIND & 1<<1)==0b00000000) //A=0 B=0 |
163 | {
|
164 | //Rechts 1
|
165 | zustand = rechts1; |
166 | }
|
167 | else
|
168 | {
|
169 | //Ruhe
|
170 | //zustand = rechts1;
|
171 | zustand = ruhe; |
172 | }
|
173 | |
174 | break; |
175 | case 4: //Rechts 2 |
176 | //lcd_puts("rechts2 = 4");
|
177 | PORTC = 0b00001100; |
178 | |
179 | //Ruhe
|
180 | zustand = ruhe; |
181 | |
182 | iDreh ++; |
183 | /*
|
184 | lcd_reset();
|
185 | _delay_ms(50);
|
186 | lcd_ausgabe(iZahl);
|
187 | */
|
188 | //_delay_ms(100);
|
189 | //lcd_puts("rechts");
|
190 | //_delay_ms(500);
|
191 | |
192 | break; |
193 | default:
|
194 | ///lcd_reset();
|
195 | |
196 | PORTC = 0xFF; |
197 | //_delay_ms(1000);
|
198 | ///lcd_puts("ERREOR");
|
199 | _delay_ms(500); |
200 | |
201 | break; |
202 | }
|
203 | }
|
204 | return 1; |
205 | }
|
206 | |
207 | |
208 | #ifndef TIMER0_OVF_vect
|
209 | // Für ältere WinAVR Versionen z.B. WinAVR-20071221
|
210 | #define TIMER0_OVF_vect TIMER0_OVF0_vect
|
211 | #endif
|
212 | |
213 | ISR (TIMER0_OVF_vect) |
214 | {
|
215 | //time++;
|
216 | }
|