Verständnissfrage Serielles Senden - UDR Register

OP #3260021
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_t Send=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!!
Angehängte Dateien:
Gast #3260077
>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.
#3260088
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.
OP #3260105
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
OP #3260134
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
Gast #3260137
>>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
int main(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;)
OP #3260192
@ 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! :-)
Angehängte Dateien:
#3260275
>    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.
#3260276
> volatile uint8_t Term=59;                       //Semikolon ist Sendeende

Warum schreibst du dann nicht ganz einfach
1
volatile uint8_t Term = ';';                       //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.
OP #3260755
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.
1
int main(void)
2
{
3
  
4
  while(1)
5
  {
6
    if(C_Buch_gelesen() && Code_Samples_durchforstet() && Problem() )
7
    {
8
      Nochmal_fragen();
9
    }
10
    else
11
    {
12
      Nochmal_nachlesen();
13
      Probieren();
14
    }
15
  }
16
}
Sorry das ich eure Zeit verschwendet habe!!!
#3260921
Wenn wir schon dabei sind

das hier ....
1
     switch(Encoder_1_diff)
2
     {
3
        case 1:Encoder_1_value++;
4
      case 2:Encoder_1_value--;
5
      }
... 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.
OP #3261204
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
OP #3261293
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ß
#3261295
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.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 13 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.