Hallo nochmal! Wieder habe ich ein Problem mit dem Abfragen von Tastern. und zwar soll einfach beim Druck auf einen Taster am STk500 die darüberligende LED leuchten. Nur irgendwie habe ich es auch noch nicht ganz mit den Pullup-Widerständen verstanden.... Was ist falsch? #include <avr/io.h> int main(void) { DDRA=0xFF; //Ausgang = PortA PORTB=0x00; //Pullup-Widerstände ausschalten DDRB=0x00; //PortB als Eingang for(;;) { if (PORTB=0x01) //wenn erster Taster1 gedrückt ist, dann... { PORTA=0x01; //leuchte LED1 } } . . . . } Danke!
Die Taster sind Low-Side angeschlossen! Wenn ein Taster gedrückt wird, liegt eine Null (Low-Pegel) am Pin und keine 1.
Fragt man für die Eingänge nicht eher PINB (anstelle von PortB) ab? Also folgendermaßen: if (PINB == 0x01) { ... } Gruß Biff
Hallo, PORTB=0x00; //Pullup-Widerstände ausschalten DDRB=0x00; //PortB als Eingang und sollte man die PullUps nicht eher EINschalten, damit es überhaupt einen Hig-Pegel am Pin geben kann, wenn nichts gedrückt ist? PS: die PullUps liegen zwischen Eingangspin und +Ub, wenn sie eingeschaltet sind und sorgen so dafür, daß es überhaupt definierte Verhältnisse in dieser Beschaltung gibt. Ohne hängt der Pin einfach nur in der Luft, wenn die Taste nicht gedrückt ist... Gruß aus Berlin Michael
ok vielen Dank! ich habe meinen fehler selbst gefunden...es war die If-Abfrage mit == und =. Programmiere nebenher noch Visual Basic und da gibts kein "==" sondern NUR "=", drum war ich bissl verwirrt ;) nun noch eine Frage: Ich habe selbst ein Board aufgebaut und bei dem muss ich nicht wie beim STK500 beispielsweise den Taster1 mit "0x7F" sondern einfach mit "0x01" abfragen. Woran liegt das? Gibt es so eine Art "invertierung" in C, damit ich anstelle von 0x7F für das STK500 auch 0x01 schreiben kann? danke!
EinSteigÄr wrote: > ok vielen Dank! > > ich habe meinen fehler selbst gefunden...es war die If-Abfrage mit == > und =. Programmiere nebenher noch Visual Basic und da gibts kein "==" > sondern NUR "=", drum war ich bissl verwirrt ;) Das war aber nicht dein einziges Problem :-) > > nun noch eine Frage: > > Ich habe selbst ein Board aufgebaut und bei dem muss ich nicht wie beim > STK500 beispielsweise den Taster1 mit "0x7F" sondern einfach mit "0x01" > abfragen. Woran liegt das? Das liegt daran, dass du deine Taster anders angeschlossen hast, als sie im STK500 angeschlossen sind. Im STK500 sind sie so angeschlossen: PIN ---o----------+ | / / | | GND ----------+ Du hast deine so angeschlossen Vcc -------------+ | / / | | PIN ---o----------+ | +-+ | | +-+ | GND -----------+ Wenn also in der STK Variante der Taster geschlossen wird, so stellt er eine Verbindung zu Masse her. Das hat den Vorteil, dass dann die AVR internen Pullup Widerstände zugeschaltet werden können und keine externen benötigt werden wie bei deiner Lösung. (Du hast doch Pulldown Widerstände eingebaut, oder?) > Gibt es so eine Art "invertierung" in C, > damit ich anstelle von 0x7F für das STK500 auch 0x01 schreiben kann? Sicher gibt es das: Die Tilde ~ ~0x01 == 0x7F ~0x7F == 0x01 Die Tilde dreht alle Bits um. Sollte sich aber auch in deinem C Buch finden.
ok vielen Dank! Habe es jetzt gecheckt... Nun noch eine Frage lieber Karl heinz, und zwar bin ich nun fast mit meinem Projekt fertig. (Außer dass ich noch die Schaltung löten muss -> kann ja nicht das STK500 abgeben ;) und noch paar Verbesserungen am Programm vornehmen muss)... Hier mal der Quellcode. Ich hoffe du weißt noch um was es ging. Es ist das Projekt mit den Lichtschranken, die nacheinander Durchfahren werden. Sobald eine Lichtschranke durchfahren wird, wird der momentane TimerRegister in eine variable (reg1...8) gespeichert und der bis dahin stattgefundene Überlauf dieses Timer-Registers (ubergabe1...8). Der 8. Taster ist zum Senden der Variablen (ubergabe1...8 und reg1...8) über den UART gedacht. Nun mein Problem: Wenn ich im Terminal die werte ansehe (also nachdem ich den schalter8: 0x7F gedrückt habe), kommen da schon mal nicht alle werte an, obwohl ich nacheinander die 8 Taster drücke. Somit müssten ja 14 Werte (8 "reg"-variablen und 8 "ubergabe"-variablen plus jeweils ein x dazwischen) erscheinen. Es kommen aber immer nur 5 (plus Trenn"x"). Die x haben nur die Aufgabe, dass das von mir geschrieben VisualBasic Programm weiß, wann es die werte in die nächste Textbox/Variable schreiben soll. Nächstes Problem ist, dass MINUS-Zahlen kommen??!! Hier der Code:
1 | _________________________________________________________________________
|
2 | #include <inttypes.h> |
3 | #include <avr/io.h> |
4 | |
5 | //Für 8 Lichtschranken programmiert
|
6 | //---------------------------------------------------------------------------
|
7 | int uart_putc(unsigned char c) |
8 | {
|
9 | while (!(UCSRA & (1<<UDRE))) /* warten bis Senden moeglich */ |
10 | {
|
11 | }
|
12 | |
13 | UDR = c; /* sende Zeichen */ |
14 | return 0; |
15 | }
|
16 | |
17 | //---------------------------------------------------------------------------
|
18 | int sendx(void) |
19 | {
|
20 | while (!(UCSRA & (1<<UDRE))) /* warten bis Senden moeglich */ |
21 | {
|
22 | }
|
23 | |
24 | UDR = 'x'; /* sende Zeichen */ |
25 | }
|
26 | //---------------------------------------------------------------------------
|
27 | |
28 | void uart_puts (char *s) |
29 | {
|
30 | while (*s) |
31 | { /* so lange *s != '\0' also ungleich dem "String-Endezeichen" */ |
32 | uart_putc(*s); |
33 | s++; |
34 | }
|
35 | }
|
36 | //-------------------------------------------------------------------------------
|
37 | int wandle(int y) |
38 | {
|
39 | char Buffer[20]; |
40 | int i = y; |
41 | |
42 | sprintf( Buffer, "%d", i ); |
43 | |
44 | uart_puts( Buffer ); |
45 | |
46 | }
|
47 | |
48 | |
49 | //-------------------------------------------------------------------------------------------------------------------
|
50 | |
51 | int main (void) |
52 | {
|
53 | int ubergabe=0,ubergabe1=0,ubergabe2=0,ubergabe3=0, ubergabe4=0,ubergabe5=0,ubergabe6=0,ubergabe7=0,ubergabe8=0; |
54 | int reg1=0,reg2=0,reg3=0,reg4=0,reg5=0,reg6=0,reg7=0,reg8=0, kontrol=0; |
55 | DDRD =0xFF; |
56 | DDRB =0x00; |
57 | TCCR0 |= (1<<CS00); |
58 | |
59 | for(;;) |
60 | {
|
61 | if (TIFR &(1<<TOV0)) //wenn generell Überlauf, erhöhe Variable "ubergabe" um eins |
62 | {
|
63 | ubergabe++; |
64 | TIFR = 1<<TOV0; |
65 | }
|
66 | |
67 | if (PINB==0xFE) //wenn Taste1 gedrückt wird, dann schreibe in Var "reg1" den Zählerstand (TCNT0) |
68 | { //und den momentanen Wert von Var "uberlauf" in "uberlauf1" |
69 | reg1=TCNT0; |
70 | ubergabe1=ubergabe; |
71 | }
|
72 | if (PINB==0xFD) |
73 | {
|
74 | reg2=TCNT0; |
75 | ubergabe2=ubergabe; |
76 | }
|
77 | if (PINB==0xFB) |
78 | {
|
79 | reg3=TCNT0; |
80 | ubergabe3=ubergabe; |
81 | |
82 | }
|
83 | if (PINB==0xF7) |
84 | {
|
85 | reg4=TCNT0; |
86 | ubergabe4=ubergabe; |
87 | }
|
88 | if (PINB==0xEF) |
89 | {
|
90 | reg5=TCNT0; |
91 | ubergabe5=ubergabe; |
92 | }
|
93 | if (PINB==0xDF) |
94 | {
|
95 | reg6=TCNT0; |
96 | ubergabe6=ubergabe; |
97 | }
|
98 | if (PINB==0xBF) |
99 | {
|
100 | reg7=TCNT0; |
101 | ubergabe7=ubergabe; |
102 | }
|
103 | if (PINB==0x7F) |
104 | {
|
105 | reg8=TCNT0; //sobald der letzte Taster(taster8) gedrückt wird, dann wird der Timer gestoppt und über kontrol=1 das senden der Daten über den UART verursacht |
106 | ubergabe8=ubergabe; |
107 | TCCR0=0; |
108 | kontrol=1; |
109 | }
|
110 | |
111 | if (kontrol==1) |
112 | {
|
113 | UCSRB |= (1<<TXEN); //Senden aktivieren |
114 | UCSRC |= (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1); // |
115 | |
116 | UBRRH = 00; //Baudrate einstellen 9600 bei 8 MHz |
117 | UBRRL = 51; |
118 | |
119 | sendx(); |
120 | wandle(reg1); |
121 | sendx(); |
122 | wandle(ubergabe1); |
123 | sendx(); |
124 | wandle(reg2); |
125 | sendx(); |
126 | wandle(ubergabe2); |
127 | sendx(); |
128 | wandle(reg3); |
129 | sendx(); |
130 | wandle(ubergabe3); |
131 | sendx(); |
132 | wandle(reg4); |
133 | sendx(); |
134 | wandle(ubergabe4); |
135 | sendx(); |
136 | wandle(reg5); |
137 | sendx(); |
138 | wandle(ubergabe5); |
139 | sendx(); |
140 | wandle(reg6); |
141 | sendx(); |
142 | wandle(ubergabe6); |
143 | sendx(); |
144 | wandle(reg7); |
145 | sendx(); |
146 | wandle(ubergabe7); |
147 | sendx(); |
148 | wandle(reg8); |
149 | sendx(); |
150 | wandle(ubergabe8); |
151 | TCCR0=0; |
152 | kontrol=0; |
153 | }
|
154 | |
155 | }
|
156 | }
|
Viiiielen Dank! :)
EinSteigÄr wrote: > Nun mein Problem: Wenn ich im Terminal die werte ansehe (also nachdem > ich den schalter8: 0x7F gedrückt habe), kommen da schon mal nicht alle > werte an, obwohl ich nacheinander die 8 Taster drücke. Somit müssten ja > 14 Werte (8 "reg"-variablen und 8 "ubergabe"-variablen plus jeweils ein > x dazwischen) erscheinen. Es kommen aber immer nur 5 (plus Trenn"x"). Wie hast du das kontrolliert? Häng doch mal ein Terminalprogramm (Hyperterminal) an die Leitung und schau nach was da ankommt. So wie es aussieht, gibt es 2 Fehlermöglichkeiten: Entweder schickt der Sender (also der AVR) nicht das was er soll oder der Empfänger wertet das empfangene nicht korrekt aus. Da das empfangende Programm ebenfalls von dir ist, kann der Fehler in beiden stecken. Und um rauszukriegen in welchem, ersetzt man halt mal eine Seite durch ein Programm, von dem man weiss das es funktioniert. In deinem Fall ist das einfachste, da mal ein Termialprogramm ala Hyperterminal dranzuhängen. > Die x haben nur die Aufgabe, dass das von mir geschrieben VisualBasic > Programm weiß, wann es die werte in die nächste Textbox/Variable > schreiben soll. Nächstes Problem ist, dass MINUS-Zahlen kommen??!! Auch das ist klar. Bei dir ist alles ein int. Und ein int kann nun mal auch negativ werden. Insbesondere wird eine Addition von 1 zur größtmöglichen positiven Zahl einen 'Überlauf' zur kleinstmöglichen Zahl bewirken. Genau aus dem Grund gibt es den Datentyp 'unsigned int'. Dann musst du dir aber raussuchen welches Formatierzeichen der sprintf für unsigned int haben will. > > Hier der Code: Du solltest dir wirklich ein C Buch zulegen. Ist dir das ewige Code-Duplizieren nicht auf den Wecker gefallen? Sowas macht man doch mit Arrays.
also ich habe es vorhin ja mit einem TerminalProgramm (Hyperterminal von Microsoft) aber da kommen eben nicht alle werte an und außerdem manchmal "minus"-zahlen. das ist eben der fehler. Genauso kommt es aber auch in meinem VB-Programm an, also kanns schon mal nicht am visualbasic-programm von mir liegen, da ja hyperterminal das gleiche anzeigt.
schmeiss doch mal die sendx() Funktion raus. Die braucht keiner. Und dann veränderst du dein Hauptprogramm so: UCSRB |= (1<<TXEN); //Senden aktivieren UCSRC |= (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1); // UBRRH = 00; //Baudrate einstellen 9600 bei 8 MHz UBRRL = 51; uart_putc( 'a' ); wandle(reg1); uart_putc( 'b' ); wandle(ubergabe1); uart_putc( 'c' ); wandle(reg2); uart_putc( 'd' ); wandle(ubergabe2); uart_putc( 'e' ); wandle(reg3); uart_putc( 'f' ); wandle(ubergabe3); uart_putc( 'g' ); wandle(reg4); uart_putc( 'h' ); wandle(ubergabe4); uart_putc( 'i' ); wandle(reg5); uart_putc( 'j' ); wandle(ubergabe5); uart_putc( 'k' ); wandle(reg6); uart_putc( 'l' ); wandle(ubergabe6); uart_putc( 'm' ); wandle(reg7); uart_putc( 'n' ); wandle(ubergabe7); uart_putc( 'o' ); wandle(reg8); uart_putc( 'p' ); wandle(ubergabe8); TCCR0=0; kontrol=0; } und siehst mal nach, welche Werte denn kommen und welche nicht. > und außerdem manchmal > "minus"-zahlen. Ja. Sagte ich doch schon warum das so ist. PS: Und zieh die UART Initialisierung vor die Schleife. Es reicht völlig, wenn der UART einmal bei Programmstart initialisiert wird. Es gibt keinen Grund das jedesmal zu machen.
habe mal deine veränderung am code so reingeschrieben und geflasht. folgendes kommt am Terminal nun an: a0b0c0d0e0f0g0h0i0j0k0l0m0n0o142p-10330a0b0 nachdem ich die taste 0x7F gedrückt habe. danke
sorry! habe was falsches kopiert. Das ist angekommen: a0b0c0d0e0f0g0h0i0j0k0l0m0n0o142p-10330
Na ja. Sind doch alle da! Von 'a' bis 'p'! Die negative kriegst du weg, indem du jetzt endlich mal die Umstellung von 'int' zu 'unsigned int' machst. Und dann musst du dich mal damit beschäftigen, warum ein Teil der Werte 0 ist.
naja, weil eben die variablen noch nicht gefüllt sind bis zu dem zeitpunkt, wo ich den 0x7f drücke
ok, also ich werde heute mal die "int" variablentypen mit "unsigned int" ersetzen. Dann müsste das Problem mit dem vorzeichen vor den Zahlen behoben sein :-) danke!
Denk aber dran, dass das Formatierzeichen im sprintf ebenfalls ersetzt werden muss.
Also. habe heute mal aus den "int" Datentypen "unsigned int" gemacht, aber anscheinend erfolglos. Wenn ich mein Programm nun so laufen lasse, wie Karl-Heinz mir vorgeschlagen hat, bringt er wieder die zeichen von a-p im Terminal, jedoch immer noch die "-" -> vorzeichen. Hier der Terminal-Ausdruck, nachdem alle Taster nacheinander gedrückt wurden: a213b30121c128d-12895e63f11358g12h30918i49j-11897k166l19707m233n-18894o1 42p3595a213b30121c128d-12895e63f11358g12h30918i49j-11 897k166l19707m233n-18894o158p3595 Hier nochmal der gesamte Code: [ c ] int main (void) { unsigned int ubergabe=0,ubergabe1=0,ubergabe2=0,ubergabe3=0, ubergabe4=0,ubergabe5=0,ubergabe6=0,ubergabe7=0,ubergabe8=0; unsigned int reg1=0,reg2=0,reg3=0,reg4=0,reg5=0,reg6=0,reg7=0,reg8=0, kontrol=0; DDRD =0xFF; DDRB =0x00; TCCR0 |= (1<<CS00); //Prescaler für Timer UCSRB |= (1<<TXEN); //Senden aktivieren UCSRC |= (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1); UBRRH = 00; //Baudrate einstellen 9600 bei 8 MHz UBRRL = 51; for(;;) { if (TIFR &(1<<TOV0)) //wenn generell Überlauf, erhöhe Variable "uberlauf" um eins { ubergabe++; TIFR = 1<<TOV0; } if (PINB==0xFE) //wenn Taste1 gedrückt wird, dann schreibe in Var "reg1" den Zählerstand (TCNT0) { //und den momentanen Wert von Var "uberlauf" in "uberlauf1" reg1=TCNT0; ubergabe1=ubergabe; } if (PINB==0xFD) { reg2=TCNT0; ubergabe2=ubergabe; } if (PINB==0xFB) { reg3=TCNT0; ubergabe3=ubergabe; //bei Druck auf Taste3, Timer beenden (TCCR0=0) } //Speichert bis hierher bei verschiedenen Tastendrücken die momentanen Überläufe (ubergabe1-3) //sowie die momentanen Registerwerte (reg1-3) if (PINB==0xF7) { reg4=TCNT0; ubergabe4=ubergabe; } if (PINB==0xEF) { reg5=TCNT0; ubergabe5=ubergabe; } if (PINB==0xDF) { reg6=TCNT0; ubergabe6=ubergabe; } if (PINB==0xBF) { reg7=TCNT0; ubergabe7=ubergabe; } if (PINB==0x7F) { reg8=TCNT0; ubergabe8=ubergabe; TCCR0=0; kontrol=1; } if (kontrol==1) { /* sendx(); wandle(reg1); sendx(); wandle(ubergabe1); sendx(); wandle(reg2); sendx(); wandle(ubergabe2); sendx(); wandle(reg3); sendx(); wandle(ubergabe3); sendx(); wandle(reg4); sendx(); wandle(ubergabe4); sendx(); wandle(reg5); sendx(); wandle(ubergabe5); sendx(); wandle(reg6); sendx(); wandle(ubergabe6); sendx(); wandle(reg7); sendx(); wandle(ubergabe7); sendx(); wandle(reg8); sendx(); wandle(ubergabe8); TCCR0=0; kontrol=0;*/ uart_putc( 'a' ); wandle(reg1); uart_putc( 'b' ); wandle(ubergabe1); uart_putc( 'c' ); wandle(reg2); uart_putc( 'd' ); wandle(ubergabe2); uart_putc( 'e' ); wandle(reg3); uart_putc( 'f' ); wandle(ubergabe3); uart_putc( 'g' ); wandle(reg4); uart_putc( 'h' ); wandle(ubergabe4); uart_putc( 'i' ); wandle(reg5); uart_putc( 'j' ); wandle(ubergabe5); uart_putc( 'k' ); wandle(reg6); uart_putc( 'l' ); wandle(ubergabe6); uart_putc( 'm' ); wandle(reg7); uart_putc( 'n' ); wandle(ubergabe7); uart_putc( 'o' ); wandle(reg8); uart_putc( 'p' ); wandle(ubergabe8); kontrol=0; } } } [ /c ] Außerdem: Wenn man nicht sofort den Taster 0x7F "zum Senden" loslässt, kommt der String - logischerweise - sooft, bis man den Schalter loslässt. Wie kann ich nur Einmal den String senden?? Vielen dank!
> Hier nochmal der gesamte Code: Das ist nicht der geamte Code. Wo ist die Funktion wandle? Nochmal: Deine Funktion wandle() kriegt jetzt einen unsigned int! Das heist du musst das Formatierzeichen im sprintf austauschen! %d ist für int, %u ist für unsigned int. > Wie kann ich nur Einmal den String senden?? Indem du eine Variable benutzt, in der du dir merkst, dass die ganze Litanei schon gesendet wurde. Ist die Variable auf 0 und kommt der Zustand 0x7F dann sendest du die Daten und setzt die Variable auf 1 Wenn du das nächste mal 0x7F antriffst und diese Variable ist auf 1, dann weist du, dass die Daten schon gesendet wurden und brauchst nichts tun. Jetzt musst du dir nur noch ein schönes Plätzchen suchen, wo die Variable wieder auf 0 gesetzt wird. Nachtrag: Mit deiner kontrol Variablen hast du schon den Grundstock dafür. Daraus kannst du diese Steuerung aufbauen.
Dann studier mal das hier. Deine Kopier-Orgien sind ja grauenhaft. Sowas macht man mit Arrays und ein paar Schleifen.
1 | void SendeWerte( unsigned int Overflows[], unsigned int Values[] ) |
2 | {
|
3 | unsigned char i; |
4 | unsigned char Filler = 'a'; |
5 | |
6 | for( i = 0; i < 8; ++i ) { |
7 | uart_putc( Filler++ ); |
8 | wandle( Values[i] ); |
9 | |
10 | uart_putc( Filler++ ); |
11 | wandle( Overflows[i] ); |
12 | }
|
13 | }
|
14 | |
15 | int main (void) |
16 | {
|
17 | unsigned int Ueberlauf = 0; |
18 | unsigned int Ueberlaeufe[8] = { 0 }; |
19 | unsigned int Zaehler[8] = { 0 }; |
20 | unsigned char Tasten[8] = { 0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F }; |
21 | unsigned char i; |
22 | unsigned char Gesendet = 0; |
23 | |
24 | DDRD = 0xFF; |
25 | DDRB = 0x00; |
26 | |
27 | TCCR0 |= (1<<CS00); //Prescaler für Timer |
28 | |
29 | UCSRB |= (1<<TXEN); //Senden aktivieren |
30 | UCSRC |= (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1); |
31 | |
32 | UBRRH = 00; //Baudrate einstellen 9600 bei 8 MHz |
33 | UBRRL = 51; |
34 | |
35 | for(;;) |
36 | {
|
37 | if (TIFR &(1<<TOV0)) //wenn generell Überlauf, erhöhe Variable "uberlauf" um eins |
38 | {
|
39 | Ueberlauf++; |
40 | TIFR = 1<<TOV0; |
41 | }
|
42 | |
43 | for( i = 0; i < 8; ++i ) { // alle Tasten abfragen |
44 | if( PINB == Tasten[i] ) // war die Taste i gedrueckt ? |
45 | {
|
46 | Zaehler[i] = TCNT0; // Werte merken |
47 | Ueberlaeufe[i] = Ueberlauf; |
48 | |
49 | if( i == 7 ) { // War das die letzte Taste ? |
50 | if( !Gesendet ) { // Wurden die Werte schon gesendet ? |
51 | SendeWerte( Ueberlaeufe, Zaehler); // Nein: Werte senden |
52 | Gesendet = 1; // und merken dass schon gesendet wurde |
53 | }
|
54 | }
|
55 | else
|
56 | Gesendet = 0; // Taste gedrückt, aber es war nicht die letzte Taste |
57 | // Wenn das nächste mal die letzte Taste gedrueckt wird
|
58 | // gibt es wieder was zum Senden
|
59 | }
|
60 | }
|
61 | }
|
62 | }
|
Danke für die Code-Lösung, werde diese wohl auch so anwenden, ist mit arrays wirklich viel einfacher. Trotzdem zeige ich nochmal meinen Code. Die Vorzeichen habe ich nun wegbekommen. Jetzt geht es um ein Verständnis-Problem: Ich schicke ja nacheinander immer "reg", dann x und dann "ubergabe". Wie kann es sein, dass die Zahlen im terminal so aussehen? 23x3998x239x1999x..... | | reg, uberlauf Wie kann es mit meinem Code vorkommen, dass die Überläufe nicht aufsteigend größer werden, da die "uberlauf"-variable ja eigentlich hochzählen sollte und immer der momentane Wert in die "uberlauf1-8" reingeschrieben werden sollen, die dann am terminal ausgegeben werden? Es müsste doch ein aufsteigendes "uberlauf"-muster im terminal geben? Macht es aber nicht danke
Hier der gesamte Code: #include <inttypes.h> #include <avr/io.h> //Für 8 Lichtschranken gemacht //---------------------------------------------------------------------- ----- unsigned int uart_putc(unsigned char c) { while (!(UCSRA & (1<<UDRE))) /* warten bis Senden moeglich */ { } UDR = c; /* sende Zeichen */ return 0; } //---------------------------------------------------------------------- ----- int sendx(void) { while (!(UCSRA & (1<<UDRE))) /* warten bis Senden moeglich */ { } UDR = 'x'; /* sende Zeichen */ } int senda(void) { while (!(UCSRA & (1<<UDRE))) /* warten bis Senden moeglich */ { } UDR = 'a'; /* sende Zeichen */ } //---------------------------------------------------------------------- ----- void uart_puts (unsigned char *s) { while (*s) { /* so lange *s != '\0' also ungleich dem "String-Endezeichen" */ uart_putc(*s); s++; } } //---------------------------------------------------------------------- --------- unsigned int wandle(unsigned int y) { unsigned char Buffer[20]; unsigned int i = y; sprintf( Buffer, "%u", i ); uart_puts( Buffer ); } //---------------------------------------------------------------------- --------------------------------------------- int main (void) { unsigned int ubergabe=0,ubergabe1=0,ubergabe2=0,ubergabe3=0, ubergabe4=0,ubergabe5=0,ubergabe6=0,ubergabe7=0,ubergabe8=0; unsigned int reg1=0,reg2=0,reg3=0,reg4=0,reg5=0,reg6=0,reg7=0,reg8=0, kontrol=0; DDRD =0xFF; DDRB =0x00; TCCR0 |= (1<<CS00); //Prescaler für Timer UCSRB |= (1<<TXEN); //Senden aktivieren UCSRC |= (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1); UBRRH = 00; //Baudrate einstellen 9600 bei 8 MHz UBRRL = 51; for(;;) { if (TIFR &(1<<TOV0)) //wenn generell Überlauf, erhöhe Variable "uberlauf" um eins { ubergabe++; TIFR = 1<<TOV0; } if (PINB==0xFE) //wenn Taste1 gedrückt wird, dann schreibe in Var "reg1" den Zählerstand (TCNT0) { //und den momentanen Wert von Var "uberlauf" in "uberlauf1" reg1=TCNT0; ubergabe1=ubergabe; } if (PINB==0xFD) { reg2=TCNT0; ubergabe2=ubergabe; } if (PINB==0xFB) { reg3=TCNT0; ubergabe3=ubergabe; //bei Druck auf Taste3, Timer beenden (TCCR0=0) } //Speichert bis hierher bei verschiedenen Tastendrücken die momentanen Überläufe (ubergabe1-3) //sowie die momentanen Registerwerte (reg1-3) if (PINB==0xF7) { reg4=TCNT0; ubergabe4=ubergabe; } if (PINB==0xEF) { reg5=TCNT0; ubergabe5=ubergabe; } if (PINB==0xDF) { reg6=TCNT0; ubergabe6=ubergabe; } if (PINB==0xBF) { reg7=TCNT0; ubergabe7=ubergabe; } if (PINB==0x7F) { reg8=TCNT0; ubergabe8=ubergabe; TCCR0=0; kontrol=1; } if (kontrol==1) { senda(); wandle(reg1); sendx(); wandle(ubergabe1); sendx(); wandle(reg2); sendx(); wandle(ubergabe2); sendx(); wandle(reg3); sendx(); wandle(ubergabe3); sendx(); wandle(reg4); sendx(); wandle(ubergabe4); sendx(); wandle(reg5); sendx(); wandle(ubergabe5); sendx(); wandle(reg6); sendx(); wandle(ubergabe6); sendx(); wandle(reg7); sendx(); wandle(ubergabe7); sendx(); wandle(reg8); sendx(); wandle(ubergabe8); sendx(); TCCR0=0; kontrol=0; /*uart_putc( 'a' ); wandle(reg1); uart_putc( 'b' ); wandle(ubergabe1); uart_putc( 'c' ); wandle(reg2); uart_putc( 'd' ); wandle(ubergabe2); uart_putc( 'e' ); wandle(reg3); uart_putc( 'f' ); wandle(ubergabe3); uart_putc( 'g' ); wandle(reg4); uart_putc( 'h' ); wandle(ubergabe4); uart_putc( 'i' ); wandle(reg5); uart_putc( 'j' ); wandle(ubergabe5); uart_putc( 'k' ); wandle(reg6); uart_putc( 'l' ); wandle(ubergabe6); uart_putc( 'm' ); wandle(reg7); uart_putc( 'n' ); wandle(ubergabe7); uart_putc( 'o' ); wandle(reg8); uart_putc( 'p' ); wandle(ubergabe8); kontrol=0;*/ } //---------------------------------------------------------------------- -------------------------------------------- } }
EinSteigÄr wrote: > > Ich schicke ja nacheinander immer "reg", dann x und dann "ubergabe". Wie > kann es sein, dass die Zahlen im terminal so aussehen? > > 23x3998x239x1999x..... > | | > reg, uberlauf > Wie kann es mit meinem Code vorkommen, dass die Überläufe nicht > aufsteigend größer werden, da die "uberlauf"-variable ja eigentlich > hochzählen sollte und immer der momentane Wert in die "uberlauf1-8" > reingeschrieben werden sollen, die dann am terminal ausgegeben werden? > Es müsste doch ein aufsteigendes "uberlauf"-muster im terminal geben? > Macht es aber nicht Wie schnell taktest du deinen µC und wie schnell drückst du die Tasten? Ich geh mal von 4 Mhz aus. d.h. der Timer zählt mit 4 Mhz, da der Prescaler 1 ist. Bis zum Überlauf muss er bis 256 zählen. Das passiert in 1 Sekunde 4000000 / 256 = 15625 mal Ein unsigned int kann bis 65535 zählen. Da deine ueberlauf Variable 15625 mal in der Sekunde erhöht wird, ist dieser Zahlenbereich in knapp 4 Sekunden einmal durch, dann beginnt ueberlauf wieder bei 0 Oder anders ausgedrückt, wenn du nicht innerhalb von 4 Sekunden (bei 4 Mhz Takt), alle Tasten der Reihe nach drückst, siehst du einen Sprung. Wenn dein µC mit 16 Mhz läuft, hast du entsprechend wendiger Zeit. Dann bist du in knapp 1 Sekunde einmal rum. Und dann hast du natuerlich noch das Problem, dass du die ganzen Zaehler nie auf 0 zurücksetzt. Da du zwischen den Zahlen aber immer nur x ausgibst, weist du in deiner Zahlenreihe nie, wo denn ein neuer Messzyklus beginnt.
ich muss doch die zähler auch nicht auf null zurücksetzen, wenn ich in meinem VB-Programm die Differenz (zeit-uberlaufe1,2 = uberlauf2-uberlauf1) oder?
EinSteigÄr wrote: > ich muss doch die zähler auch nicht auf null zurücksetzen, wenn ich in > meinem VB-Programm die Differenz (zeit-uberlaufe1,2 = > uberlauf2-uberlauf1) > > oder? Setz einfach mal ein paar Zahlenwerte ein und du wirst sehen was dann raus kommt.
also es funktioniert :) habe mal gaaanz schnell die taster nacheinander gedrückt und habe gesehen, dass es aufsteigend funktioniert. Werde dann entweder - wie karlheinz geschrieben hat - immer die werte auf 0 zurücksetzen oder einfach größere Datentypen für die Variablen verwenden. Danke!
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.