Forum: Mikrocontroller und Digitale Elektronik Dezimalwert(1024) per UART empfangen WinAVR


von Robin T. (rotoe) Benutzerseite


Lesenswert?

Hi Leute,

hab da ein Problem was die Bandbreite von RS232 angeht.
Ich habe bereits ein Programm geschrieben welches Dezimalzahlen am UART 
empfängt und an OCR1 ausgibt. Funktioniert auch soweit ganz gut.
ABER: Wenn ich z.B. den 10-Bit PWM Mode benutze bekomme ich den Wert 
1024 nicht in einem Stück vom PC zum µC. Wie mache ich das am besten?

von crazy horse (Gast)


Lesenswert?

1024 brauchst du ja auch nicht :-)
Sende es einfach als Ascii-Zeichen und setz es im MC wieder zu einem 
Binärwert zusammen - wo ist das Problem?

von Robin T. (rotoe) Benutzerseite


Lesenswert?

crazy horse wrote:
> 1024 brauchst du ja auch nicht :-)
> Sende es einfach als Ascii-Zeichen und setz es im MC wieder zu einem
> Binärwert zusammen - wo ist das Problem?

Das Problem liegt im ASCII Zeichen zusammensetzen :)
Weiß nämlich net wie das geht. Aber ich guck nochmal im gcc-Tutorial.

von crazy horse (Gast)


Lesenswert?

atio ist dein Freund in diesem Fall.
Kannst es aber auch "zu Fuss" Zeichen für Zeichen machen.

von crazy horse (Gast)


Lesenswert?

atoi latürnich :-)

von Robin T. (rotoe) Benutzerseite


Lesenswert?

Wo finde ich den die Syntax zu diesem Befehl?
Gibts irgendwo ne komplette gcc-Referenz?

von Jörg X. (Gast)


Lesenswert?

Mal auf deinem Rechner geschaut?
->Pfad/zu deinem/winavr/doc/...

Da steht alles was man wissen muss (zu winavr zumindest) ;)
hth. Jörg

von Robin T. (rotoe) Benutzerseite


Lesenswert?

Boah. An dieser Anleitung verzweifel ich wirklich.
Da steht:

int atoi(const char * s)
Convert a string to an integer.
1
//Perfekt genau was ich will^^
The atoi() function converts the initial portion of the string pointed 
to by s to integer
1
//Ok auch verstanden
representation. In contrast to
(int)strtol(s, (char **)NULL, 10);
1
//Wasn das nu? Ich dachte es geht um atoi!
this function does not detect overflow (errno is not changed and the 
result value is
not predictable), uses smaller memory (flash and stack) and works more 
quickly.

Ich kann Englisch aber das check ich mal garnicht.

von Robin T. (rotoe) Benutzerseite


Lesenswert?

Wobei ich gerade gemerkt habe das ich diese atoi Funktion nicht brauche 
ich kann einfach vom Empfangenen Wert z.B. 50, 48 Abziehen dann habe ich 
ASCII(2). Aber ich weiß immernoch nicht wie ich die empfangenen Zeichen 
z.B. 1,0,2,4 zu 1024 zusammensetze.

von spess53 (Gast)


Lesenswert?

Hi

Wie wäre es mit 4+2*10+0*100+1*1000? Abgesehen davon dürfte dei Höchster 
Wert 1023 sein. 1024 sind schon 11 Bit.

MfG Spess

von Robin T. (rotoe) Benutzerseite


Lesenswert?

Sorry aber ich muss meine Frage mal neu Formulieren:

1. ASCII(0-1023) wird vom PC gesendet.     //Kann ich :)
2. µC soll z.B. 5,1,2  Empfangen           //Wie nacheinander 
abspeichern?
3. µC soll 5,1,2 zusammensetzen            //Kann ich auch nicht :(
4. Jetzt würde ich mich freuen^^

Also es können sowohl 3 stellige z.B. 512 wie auch 4 stellige Zahlen 
sein z.B. 1023.
Wie mache ich es das er die Zahlen in jeweils einer Variable abspeichert 
und am Ende zu einer zusammefügt?
Und wie erkennt er das kein weiteres Zeichen mehr kommt?

von Robin T. (rotoe) Benutzerseite


Lesenswert?

Hier mal mein aktueller Code der nur Dezimalzahlen von 0-255 empfängt.
Nicht dass ihr denkt ich tue nichts :)
1
//Includes der nötigen Libarys 
2
#include <avr/io.h>                //Standard Input/Output-Libary
3
#include <avr/interrupt.h>         //Libary für Interrupts
4
#include <stdint.h>
5
6
//Definitionen
7
#define F_CPU 8000000              //CPU Frequenz
8
#define BAUD 38400                 //Baudrate
9
#define UBRR_VAL ((F_CPU/(BAUD*16UL))-1)
10
11
12
void USART_Init()
13
{
14
  //Baudrate wird ins Register geschrieben
15
  UBRRL=UBRR_VAL;               //Low-Byte
16
  UBRRH=(UBRR_VAL>>8);         //High-Byte
17
  //1 Stop-Bit, Partitiy=none, 8-Bit
18
  UCSRC |= (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);  
19
  //Reciver und Transmitter aktivieren
20
  UCSRB |= (1<<RXEN)|(1<<RXCIE);
21
  //Global Interrupts einschalten
22
  sei();
23
}
24
25
ISR(USART_RXC_vect)
26
{
27
    //Variable Temp und A deklarieren
28
  int8_t Temp;
29
  //Empfangene Daten an Temp übergeben
30
  Temp=UDR;
31
  //Empfangene Daten aufs PWM Register ausgeben
32
  OCR1A=Temp;
33
}
34
35
void PWM_Init()
36
{
37
    //10-Bit Phase-Correct-PWM
38
  TCCR1A |= (1<<WGM10)|(1<<COM1A1);
39
  //Kein Prescaler
40
  TCCR1B |= (1<<CS10);
41
}
42
43
int main(void)
44
{
45
  USART_Init();
46
  PWM_Init();
47
  DDRB |= (1<<1);
48
  while(1)
49
  
50
  return(0);
51
}

von spess53 (Gast)


Lesenswert?

Hi

Zum Bleistift wenn generell 4 ASCII-Zeichen gesendet werden.

MfG Spess

von Johnny Maxwell (Gast)


Lesenswert?

Warum muss es unbedingt ASCII sein? Du kannst die Daten auch einfach 
binär übertragen. Da sparst du dir viel Aufwand.

von Robin T. (rotoe) Benutzerseite


Lesenswert?

Johnny Maxwell wrote:
> Warum muss es unbedingt ASCII sein? Du kannst die Daten auch einfach
> binär übertragen. Da sparst du dir viel Aufwand.

Da haste im Grunde genommen recht. Aber da ist immernoch das gleiche 
Problem mit den Zusammensetzen. Weils nicht mit einmal übertragen 
ankommt. Geht ja wie gesagt nur 8 Bit zu übertragen.

von STK500-Besitzer (Gast)


Lesenswert?

Ein Sting vom PC ist i.d.R. dann zuende, wenn man "Enter" drückt.
Von Terminalprogrammen wird dieses Zeichen auch übertragen.
Die einfachst Möglichkeit, ASCII-Zahlen einzulesen ist:

(Pseudocode)

ISR_USART_RECV
{
  temp = UDR;
  if ((temp>='0') && (temp<=9))
   {
     Zahl = Zahl * 10 + (temp-'0');
   }
   else
   zahlkomplett = true;
}

in der main fragt man dann "einfach" ab, ob zahlkomplett == true ist, 
und speichert sie zwischen, setzt zahlkomplett = false und setzt Zahl = 
0.
Oder behandelt die Sache noch irgendwie anders...
Man kann natürlich auch erst mal alle Ziffern einlesen und dann itoa 
drüberschicken...

von spess53 (Gast)


Lesenswert?

Hi

Dann halt 'Wert>>8' und 'Wert and $FF'.

Wenn ihr Programmieren von Unten an gelehrt hättet (Assembler), würden 
solche Fragen übehaupt nicht aufkommen.

MfG Spess

von crazy horse (Gast)


Lesenswert?

Binärübertragung hinkt immer ein wenig, da alle Bytes vorkommen können.
Damit wird es schwierig, eindeutige Informationen zu übermitteln (geht 
natürlich trotzdem, wenn ein Protokoll drüberliegt)
Mit Ascii ist das alles einfacher auf der Übertragungsstrecke (nebenbei 
kann man noch im Klartext mit einem Terminalprogramm mitlesen), 
effektive Datenrate halbiert sich allerdings in etwa. Aber das ist ja 
hier nicht das Problem :-)

von Johnny Maxwell (Gast)


Lesenswert?

> Da haste im Grunde genommen recht. Aber da ist immernoch das gleiche
> Problem mit den Zusammensetzen. Weils nicht mit einmal übertragen
> ankommt. Geht ja wie gesagt nur 8 Bit zu übertragen.

Problem beim Zusammensetzen?
1
var16 = low_byte + (high_byte << 8);

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
Noch kein Account? Hier anmelden.