returnch0,ch1,ch2,ch3,ch4,ch5,ch6;// Rückgabe von chars
146
}
147
148
voidmain(void)
149
{
150
PICConfig();// Konfigurieren der PORTs
151
InitUsart();// Start der USART- Schnittstelle
152
PORTCbits.RC0=1;// Anschalten EIN/Aus Lampe
153
//InttoChar(counter); // Zähler in chars zum Senden umwandeln
154
//loop
155
while(1)//Hauptprogramm
156
{
157
//Counter(); // Zählen
158
InttoChar(counter);// Zähler in chars zum Senden umwandeln
159
counter=ncounter;
160
Nop();// Warten
161
Nop();// Warten
162
Senden(ch0);// Senden Vorzeichen
163
Senden(ch1);// Senden Zehntausender
164
Senden(ch2);// Senden Tausender
165
Senden(ch3);// Senden Hunderter
166
Senden(ch4);// Senden Zehner
167
Senden(ch5);// Senden Einer
168
Senden(ch6);// Senden Trennzeichen
169
}// Ende Endlosschleife
170
return0;
171
}/* Ende Mainfunktion */
Anbei mein Code!
Das Auslesen des Drehgebers funktioniert. Auch Das umrechnen von int inc
char und auch das Senden der einzelnen Chars.
Alles funktioniert. Aber ohne die Schleife.
Sobald ich mein Inttochar() Funktion in die Schleife packe. KOmmt am PC
nur noch Mist an. ICh weiß nicht mehr weiter. Kann sich das einer
erklären!?
Zum Testen habe ich den Counter manuell beladen ( =-12856) for der
Schleife umgewandelt und dann in die Schleife => Unendliches Senden.
Funktioniert perfekt.
Doch sobal ich das Umrechnen in die Schleife schiebe, funktioniert gar
nix mehr;-(
Hat vielleicht jemand ne Idee?
Grüße Pascal
InttoChar() enthaelt eindeuting fehler:
In C kann man Variablen nicht zur gleichen zeit aendern (normaler
weise).
s1, s2, s3, s4, s5 = 0;
wird
s1 = 0;
s2 = 0;
etc.
Man kann auch nicht mehrere Variablen von einer function zurueck
schicken - brauchst du hier sowieso nicht da ch1 - ch6 global deklariert
sind; du kannst sie ueberall im Programm benutzen.
InttoChar() schaut sonst aus als ob es funktionieren sollte, koennte
aber viel eleganter sein (mit for loop und einem array)
Ich hoffe das hilft!
Josef
Vielleicht sollte man auch mal den Compiler
wechseln. Ich finde es bemerkenswert das
bei soetwas:
> return ch0, ch1, ch2, ch3, ch4, ch5, ch6; // Rückgabe von chars
nicht sofort beim Compiler die Alarmglocken angehen.
Oder handelt es sich um das typische
Nachwuchsproblem? (aka: Kann posten aber nicht lesen,
z.b Fehlermeldungen)
Olaf
olaf schrieb:
>> return ch0, ch1, ch2, ch3, ch4, ch5, ch6; // Rückgabe von chars>> nicht sofort beim Compiler die Alarmglocken angehen.> Oder handelt es sich um das typische> Nachwuchsproblem? (aka: Kann posten aber nicht lesen,> z.b Fehlermeldungen)
Da gibt es keine Fehlermeldung.
Es ist in C erlaubt, Anweisungen durch Komma zu trennen. Der
Rückgabewert ist dann die letzte Anweisung ch6.
Peter
danke für die schnelle Hilfe.
Hab eureTipps befolgt und jetzt funktioniert, das immerwährende Senden.
Es lag daran, dass meine Stellenvariablen s1 - s5 global definiert waren
und somit immer irreale zufällige Werte annahmen. Hab sie nur lokal in
der Funktion deklariert und jetzt gehts.
Jetzt muss ich mich nur noch ans Zählen machen.
Da hätt ich auch das gleiche Problem:
Hier nochmla die FUnktion
1
voidCounter(void)
2
{
3
gray_code=PORTBbits.RB0;//A1 X
4
gray_help=gray_code<<1;// X0
5
gray_code=gray_help|PORTBbits.RB1;//B1 XY
6
gray_help=gray_code<<1;// XY0
7
Nop();// 0,2 µs Warten
8
gray_code=gray_help|PORTBbits.RB0;//A2 XYZ
9
gray_help=gray_code<<1;// XYZ0
10
gray_code=gray_help|PORTBbits.RB1;//B2 XYZW
11
Nop();// 0,2 µs Warten
12
switch(gray_code)
13
{
14
case0b00000001:
15
counter--;
16
break;
17
case0b00000010:
18
counter++;
19
break;
20
case0b00000100:
21
counter--;
22
break;
23
case0b00000111:
24
counter++;
25
break;
26
case0b00001101:
27
counter--;
28
break;
29
case0b00001110:
30
counter++;
31
break;
32
case0b00001000:
33
counter--;
34
break;
35
case0b00001011:
36
counter++;
37
break;
38
}// Ende Switch- Anweisung
39
returncounter;
40
}
Meine Codelogik funktioniert irgendwie nicht.
Was passiert, wenn ich die Eingänge in ein char speichere?
Speichert der PIC für ein High eine 1 bzw. 0b0000001 / 0x01 ? oder eine
ASCI CODE EINS?
Daran hängts bei mir gerade noch.
Weil er bei mir willkürlich und langsam vor und zurück zählt.
Grüße
Pascal
PicNeuling schrieb:
> Was passiert, wenn ich die Eingänge in ein char speichere?>> Speichert der PIC für ein High eine 1 bzw. 0b0000001 / 0x01 ? oder eine> ASCI CODE EINS?
Ein char ist auch nichts anderes als eine Variable, die einen kleinen
Integer speichern kann, lediglich bei I/O (also printf, scanf und
Konsorten) wird ein char anders behandelt.
Du solltest dir aber angewöhnen, für alles was in Wirklichkeit Bytes
sind, immer 'unsigned char' zu benutzen. Bei char alleine ist nicht
festgelegt, ob da jetzt ein Vorzeichen berücksichtigt wird oder nicht.
Je nachdem können Schiebeoperationen mächtig in die Hose gehen.
Wenn du in einen char die Zahl 1 speicherst, dann steht da auch das
Bitmuster für die Zahl 1 drinnen.
>> Daran hängts bei mir gerade noch.
Es hängt bei dir daran, dass du kein C-Buch hast, welches dir die
Grundlagen von C beigebracht hat.
PicNeuling schrieb:
> Weil er bei mir willkürlich und langsam vor und zurück zählt.
Sieh dir mal diese Sequenz an
1
gray_code=PORTBbits.RB0;//A1 X
2
gray_help=gray_code<<1;// X0
3
gray_code=gray_help|PORTBbits.RB1;//B1 XY
4
gray_help=gray_code<<1;// XY0
5
Nop();// 0,2 µs Warten
6
gray_code=gray_help|PORTBbits.RB0;//A2 XYZ
7
gray_help=gray_code<<1;// XYZ0
8
gray_code=gray_help|PORTBbits.RB1;//B2 XYZW
9
Nop();// 0,2 µs Warten
10
11
switch(gray_code)
Aha. Du denkst tatsächlich, dass dein Benutzer den Drehgeber exakt in
den 0.2µs drehen wird, die du ihm dafür Zeit gibst, während er in den
restlichen Millisekunden, die du fürs UART senden brauchst, drehen kann
wie ein Verrückter und nichts passiert.
Dein Code kann nur Veränderungen feststellen, die sich zeitlich nach dem
erstmaligen Abfragen hier
Ich hab ein C- Buch.
Mir gehts es um das Problem:
char c1 = PORTBbits.RB0;
char c2 = PORTBBIts.RB1;
Wenn ein Lowpegel anliegt (0V) => Was ist in c1 und c2 gespeichert.
Wenn ein Highpegel anliegt (2,5V => Schmitttrigger erkennt es ls High)
=> Was ist in c1 und c2 gespeichert?
Für Highpegel:
c1 = 1;
oder
c1 = '1' bzw. c1 = 0x31 bzw. c1 = 61;
Für Lowpegel:
c1 = 0;
oder
c1 = '0' oder c1 = 0x30 bzw. c1 = 60;
Welche Zeile speichert der PIC?
Ich weiß einfach nicht wie der PIC den Highpegel interpretiert und ich
keinem Buch finde ich etwas.
PicNeuling schrieb:
> Ich hab ein C- Buch.>>> Mir gehts es um das Problem:>>>> char c1 = PORTBbits.RB0;> char c2 = PORTBBIts.RB1;>> Wenn ein Lowpegel anliegt (0V) => Was ist in c1 und c2 gespeichert.
0
> Wenn ein Highpegel anliegt (2,5V => Schmitttrigger erkennt es ls High)> => Was ist in c1 und c2 gespeichert?
1
> Für Highpegel:> c1 = 1;> oder> c1 = '1' bzw. c1 = 0x31 bzw. c1 = 61;
Wo sollen die her komme?
Nochmal. Ein char ist ein (kleiner) Integer. Wenn du dort ein Bit setzt,
dann setzt du ein Bit. Nur weil das Teil char heisst, tauchen da nicht
magisch irgendwelche ASCII Zeichen auf.
@kbuchegg
Danke für die Char Antwort. Das wollte ich wissen.
Ok das mit dem Abfragen erscheint mir logisch.
Das muss per Timerinterrupt geschehen, oder?
Doch was muss genau in die Interruptroutine und wie aktiviere ich sie!?
Nur bei A?
grüße
PAscal
PicNeuling schrieb:
> @kbuchegg>> Danke für die Char Antwort. Das wollte ich wissen.>> Ok das mit dem Abfragen erscheint mir logisch.>> Das muss per Timerinterrupt geschehen, oder?
Kann, muss nicht (fürs erste).
Ein erster Erfolg wäre es, wenn in der Funktion der aktuelle Zustand des
Drehgebers mit dem Zustand des Drehgebers im vorhergehenden
Funktionsaufruf verglichen werden würde.
Vorausgesetzt die Funktion wird häufig genug aufgerufen, kann dir somit
keine Veränderung am Drehgeber mehr durch die Lappen gehen.
Hi @all
Danke erstmal für die Hilfe.
Mein Programm funktioniet jetzt. Doch leider ist das Auslesen des
Drehgebers viel zu langsam. (Er hat 5000 Schritte pro Umdrehung).
Also muss ich doch auf den Interrupt umzwischen.
Ich denke mal, das logischte wäre ein PORTB-ON-CHANGE Interrupt der bei
einem Highsignal von A (also RB0) in diese InterruptServiceroutine geht,
oder?
zum Aktivieren der Interrupts, reicht
// PORTB-ON-CHANGE-INTERRUPT konfigurieren
INTCON = 0x11001000;
INTCON2 = 0x10000001;
oder?
nun nehme ich einfach meine Counter funktion und packe sie in die ISR,
oder?
void Interrupt(void)
{
new = (PORTBbits.RB0<<1) | (PORTBbits.RB1);
code = (old<<2) | (new);
switch (code)
{
case 0b00000001: counter++; break;
case 0b00000111: counter++; break;
case 0b00001110: counter++; break;
case 0b00001000: counter++; break;
case 0b00000010: counter--; break;
case 0b00000100: counter--; break;
case 0b00001101: counter--; break;
case 0b00001011: counter--; break;
} // Ende Switch- Anweisung
old = new;
flag=1;
INTCON.RBIF = 0;
return 0;
}
Doch wenn der PIC die Routine abgearbeitet hat, wo steht er dann
innerhalb der main- funktion!?
Denn wenn er an die letzte Stelle vom Programm springt, an der er gerade
war.
Brauche ich ja meine Endlosschleife noch, die immer int in char
umrechnet und sendet,oder!?
Reicht das schon?
Echt nochmal und schonmal vielen vielen Dank für eureHilfe
Grüße
Also hat vielleicht jemand so eine allgemeine Interruptroutine und
Konfiguration
Pascal