Liebe Gemeinde,
ich bin vor kurzem von Bascom auf C umgestiegen. Nachdem ich das AVR GCC
Tutorial durchgearbeitet habe und ein paar LED's blinken lassen habe,
wollte ich eine vor kurzem geschriebenen Code in Basic (2 Drehencoder,
Daten seriell senden) nun in C übersetzen. Die Logik, Interrupts usw.
funktioniert soweit auch nur aus irgendeinem Grund empfange ich mit
Putty keine Daten.
Habe auch mit der Foren-Suchfunktion bzw. Google nichts finden können!!
Anbei die - meiner Meinung nach wichtigen Code Zeilen;
1
#define F_CPU 16000000UL
2
#define BAUD 250000UL
3
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)
4
5
Serial[0]=1;
6
Serial[1]=2;
7
Serial[2]=7;
8
Serial[3]=-;
9
Serial[4]=2;
10
Serial[5]=5;
11
Serial[6]=5;
12
Serial[7]=;;
13
14
UCSRC|=((1<<UMSEL)|(1<<UCSZ1)|(1<<UCSZ0));
15
UCSRB|=(1<<RXEN)|(1<<TXEN)|(1<<RXCIE);
16
UBRRH=UBRR_VAL>>8;
17
UBRRL=UBRR_VAL&0xFF;
18
19
ISR(TIMER1_OVF_vect)
20
{
21
22
for(uint8_tSend=0;Send<sizeof(Serial);Send++){
23
UDR=Serial[Send];
24
UDR_DBG=Serial[Send];
25
}
26
27
}
Eigentlich sollte ich in Putty ja 127-255; empfangen
Selbst wenn die Baudraten bzw. CPU Takt nicht stimmen, empfängt Putty
wenigstens Datenmüll nur bei mir kommt garnix an!
Wäre nett wenn mir hier wer weiterhelfen könnte.
Vielen Dank im Vorraus für eure Hilfe!!
>for(uint8_t Send=0;Send<sizeof(Serial);Send++)>{>UDR=Serial[Send];>UDR_DBG=Serial[Send];>}
Jo, immer schön in UDR reinballern und bloss nicht warten
bis das Byte auch gesendet werden konnte.
Kein Wunder das das nicht geht.
Was Holger meint ist, dass du immer erstmal auf das UDR-empty Bit warten
solltest, bevor du neue Daten dort reinschaufelst.
Einfach in die Schleife vor dem befüllen von UDR
while (!(UCSRA&_BV(UDRE)));
einfügen.
Und UBRR errechnet sich als FCPU/16/baud-1:
Für 19.2k bei 16MHz CPU mal 51 hart in UBRRL schreiben und in UBRRH eine
0.
Hallo zusammen,
vielen Dank für die Antworten! :-)
Das mit der While schleife leuchtet ein, werde ich gleich anwenden. Da
hat mir meine ewige Bascomprogrammierung einen "Streich" gespielt!!
(printbin)
2. BAUD-RATEN Berechnung: Ich hab das Makro zwar so aus dem Tutorial
kopiert, aber weiter oben steht ja die Formel wie von dir angegeben,
wird ebenfalls angepasst!
Vielen Dank an euch schonmal für die schnellen Antworten!!
Gruß
Matthias
Martin N. schrieb:> würde ich noch klammern:UCSRB |= ((1<<RXEN)|(1<<TXEN)|(1<<RXCIE));
@Martin N. da geb ich dir recht... man sollte sich als Anfänger eine
einheitliche Schreibweise angewöhnen!
Danke für den Hinweis!
Matthias
Matthias Lindner schrieb:> Serial[0]=1;
...
> Serial[7]=;;
Guck dir mal an, wie in C Charakter-Konstanten aussehen.
So wird PUTTY da bestimmt nicht den Text "127-255;" empfangen - und das
meinst du doch, oder?
Hi,
Char ist in einfache Anführungszeichen zu setzen... also Serial='X';
Nur im Code sieht das wie folgt aus
volatile uint8_t Interm=45; //Das - zeichen ist Datenblockende
volatile uint8_t Term=59; //Semikolon ist Sendeende
volatile uint8_t Serial[8]; //Serielles Senderegister
Ich habe mir gedacht, wenn ich anhand der ASCII Tabelle das jeweilige
Zeichen (anhand der Nummer) in eines der Bytes schreibe, kann der
"Master"
sorry der läuft mit Bascom.. :-( das auch lesen. Soll heißen, das
darzustellende zeichen berechnen z.b. 1 und dann 48 für Zahlenwerte
addieren. Somit ist man in der ASCII Tabelle auf Pos 49 und somit bei
"1"
Auch Putty kann das... oder konnte es als der Code noch als
Bascom-Version lief.
Encoder_1_100=1;
Serial[0]=Encoder_1_100+48; // 1+48 = 49 ASCII Tabelle liefert 1 zurück
Serial[3]=Interm; // daraus folgt >> Serial[3]=-
Serial[7]=Term; // daraus folgt >> Serial[7]=;
An dieser Stelle muss ich mich wohl entschuldigen, da ich nicht alle
Relevanten Codezeilen gepostet habe!!
Tut mir Leid
Matthias
>>Serial[3]=-;>>Serial[7]=;;>>Guck dir mal an, wie in C Charakter-Konstanten aussehen.
Wobei die beiden Zeilen oben nie einen C Compiler gesehen haben können.
Der hätte alles vollgekotzt.
>Anbei die - meiner Meinung nach wichtigen Code Zeilen;
Zeige nie Code den du nachweislich NICHT verwendet haben kannst.
Und rück deinen Code mal vernünftig ein. Oder speicherst du deinen Code
noch auf Diskette? Ein paar Spaces oder Tabs würden die Lesbarkeit
deutlich erhöhen.
1
intmain(void)
2
{
3
Bier_aufmachen();
4
5
while(1)
6
{
7
if(Bier_is_alle()&&Bier_vorhanden())
8
{
9
Mach_neues_Bier_auf();
10
}
11
else
12
{
13
Wecker_stellen();
14
Schlafen_gehen();
15
}
16
}
17
}
Dann kann man deinen Code lesen wie eine Geschichte;)
@ Holger:
Danke für die Belehrung, ich werde versuchen mich in Zukunft daran zu
halten!!!
Anbei nochmals mein Source file... eingerückt und mit allen
Verbesserungen die ihr mir gennant habt; werde das dann morgen mal im
Labor testen!
Bis dahin vielen Dank an ALLE!!
Grüße
Matthias
EDIT: Das mit der Diskette hab ich jetzt nicht verstanden... Aber ist ja
auch egal! :-)
> if (PIND&(0<<PIND2)) Encoder_1_new |= (0 << Track0);
Das ist eine 0-Operation. Kannst du genauso gut auch einfach weglassen.
* so testet man nicht auf ein 0-Bit
* so werden Bits nicht auf 0 gesetzt
Bitmanipulation
Und nein, du darfst auf keinen Fall
* ein C Buch lesen
* anderer Leute C Code studieren
ansonsten bekommst du sofort Augenkrebs.
> volatile uint8_t Term=59; //Semikolon ist Sendeende
Warum schreibst du dann nicht ganz einfach
1
volatileuint8_tTerm=';';//Semikolon ist Sendeende
oder hier
> Serial[0]=Encoder_1_100+48;
1
Serial[0]=Encoder_1_100+'0';
schreib das, was du meinst und so dass es lesbar ist! Dein Compiler
kennt die ASCII Codes. Es gibt keinen Grund, warum du dir die Mühe
machen sollst und die raussuchen musst.
Ausser natürlich, man programmiert BASCOM. Aber das hier ist C.
Also ihr habt recht... ich werde nochmal zurück ans "Reißbrett" gehen
und mich genau in die Sprache C einlesen! Hab mir von meinen JAVA Skills
doch zuviel erhofft.
... meinst du garantiert nicht so. Lies nach, was es mit break auf sich
hat und warum du (meistens) in einem case einen brauchst.
Dein obiger Code mal bereinigt, bleibt übrig
1
if(Encoder_1_diff==2)
2
Encoder_1_value--;
und ich denke aus dem Bauch heraus nicht, dass das die Idee an dieser
Stelle war.
Karl Heinz Buchegger schrieb:> ... meinst du garantiert nicht so. Lies nach, was es mit break auf sich> hat und warum du (meistens) in einem case einen brauchst.
Stimmt, hab diesen Fehler heute Morgen noch gefunden... die Switch
anweisung schaut genau so aus wie in JAVA.
Trotz allem Funktioniert jetzt das Hauptprogramm!!! Also
Encoderauswertung und TIMER0 Interrupt!
Bevor ich mich an die Serielle Schnittstelle mache, muss ich wohl noch
lesen und lernen, aber jetzt sind ja eh erstmal 6 Wochen Ferien.
Trotz allem, vielen Dank für eure Ratschläge und Verbesserungen!
Beim nächsten mal denke ich nach ob und was ich poste.
Grüße
Matthias
Nochmal ich,
das Projekt funktioniert jetzt!!! Hatte UMSEL gesetzt.... habe das
deaktiviert und jetzt funktionierts wie es sein soll!! und jedemenge
anderer Fehler die Ihr gefunden habt!!
@Moderator:
1. wie kann ich bzw. darf ich den Thread schließen??
2. Besteht Interesse am Sourcecode?
Gruß
Matthias Lindner schrieb:> Beim nächsten mal denke ich nach ob und was ich poste.
Du sollst vor allen Dingen C lernen, ehe bzw. im Zuge dessen, was du
programmierst.
Allgemein wird empfohlen sich ein C-Buch zu besorgen und damit die
ersten Schritte auf einem PC(!) zu machen. Wenn du das C-Buch zu einem
guten Drittel durch hast, hast du das Rüstzeug um dir die Besonderheiten
der µC-Programmierung näher zu bringen.
Klar gehts auch so. Aber deine Frustschwelle muss um einiges höher sein.
Lernen und was damit zusammenhängt, seine ersten Fehler debuggen, geht
nun mal auf einem PC um Größenordnungen einfacher als am AVR.