Forum: Mikrocontroller und Digitale Elektronik Daten Senden Empfangen Pc -> Ic -> Pc


von knoddelpusch (Gast)


Lesenswert?

Hallo zusammen,

ich habe mir ein VB.Net Programm geschrieben wo ich an einen Ic 
(Atmega16) warte Zeiten ändern. Die Übertragung von VB zum Ic soll in 
Ascii code passieren. Die Umwandlung in VB funktioniert
super, lasse es mir in einer Textbox anzeigen.
Wenn ich im Ic die Variable x (als Char oder uint8_t) umwandle und damit 
z.B. eine warte Zeit einstellen möchte geht das nicht.
Ich habe mir auch schon die Variable x als Ascii wider an den Pc 
geschickt da kommen immer unterschiedliche Werte an. Selbst wenn ich 
direkt ein Ascii Variable schicke.
1
#include <avr/io.h>
2
#include <stdlib.h>
3
#include <inttypes.h>
4
#include <util/delay.h>
5
6
#define F_CPU 1000000 /* evtl. bereits via Compilerparameter definiert */
7
#define BAUD 9600UL // Baudrate
8
9
// Berechnungen
10
#define UBRR_VAL ((F_CPU+BAUD*/(BAUD*16)-1) // clever runden
11
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1))) // Reale Baudrate
12
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
13
14
15
static void Rot (void)
16
{
17
PORTB = (~(1<<PIN0) & ~(0<<PIN1) & ~(0<<PIN2) & ~(0<<PIN2) & ~(1<<PIN3) & ~(0<<PIN4) & ~(0<<PIN5) & ~(0<<PIN5) & ~(1<<PIN6) & ~(0<<PIN7));
18
}
19
20
//----------------------------------------------------------------------------------------------------
21
22
// UART konfig
23
24
void uart_init (void)
25
{
26
UBRRH = UBRR_VAL >> 8;
27
UBRRL = UBRR_VAL & 0xFF;
28
29
UCSRB |= (1<<TXEN) | (1<<RXEN); //UART TX und RX einschalten
30
UCSRC = (1<<URSEL) |(1<<UCSZ1) | (1<<UCSZ0); //Asynchron 8N1
31
}
32
33
//----------------------------------------------------------------------------------------------------
34
35
//Senden
36
int uart_putc(uint8_t z)
37
{
38
while (!(UCSRA & (1<<UDRE))) /* warten bis Senden moeglich */
39
{
40
}
41
UDR = z; /* sende Zeichen */
42
return 0;
43
}
44
45
//----------------------------------------------------------------------------------------------------
46
47
//Empfanen
48
uint8_t uart_getc(void)
49
{
50
while (!(UCSRA & (1<<RXC)))
51
;
52
return UDR;
53
}
54
55
//----------------------------------------------------------------------------------------------------
56
57
int main (void)
58
{
59
60
61
uint8_t x;
62
63
uint8_t c; //Ascii kommen
64
65
uint8_t z; //Ascii gehen
66
67
uint8_t t; //Variable für Zeitwert
68
69
//Ausgangs Port Festgelegt
70
DDRB = 0xFF;
71
PORTB = 0xFF;
72
73
uart_init(); //UART deklarit
74
75
while (1)
76
{
77
78
c = uart_getc(); //Variable c mpfange
79
x = atoi (c); //Ascii variable c in variable x umwandeln
80
81
itoa (65, z, 10); //65 in Ascii umwandeln entspricht A zum Testen
82
83
uart_putc(z); //variable z (65, A) an Pc senden
84
85
t = x * 100; //Auf sekungen umwandeln
86
87
PORTB = Rot; //Port B schalten
88
_delay_ms(t); //WarteZeit t
89
PORTB =0xFF; //Port B ausschalten
90
_delay_ms(t); //WarteZeit t
91
PORTB = Rot; //Port B schalten
92
_delay_ms(t); //WarteZeit t
93
PORTB =0xFF; //Port B ausschalten
94
}
95
96
return 0; // never reached
97
98
}

von Karl H. (kbuchegg)


Lesenswert?

knoddelpusch schrieb:

> c = uart_getc(); //Variable c mpfange
> x = atoi (c); //Ascii variable c in variable x umwandeln

Äh. Nein.
An dieser Stelle müsste dein Compiler schon Zeter und Mordio schreien.

> itoa (65, z, 10); //65 in Ascii umwandeln entspricht A zum Testen

und hier gleich noch einmal.

Dir scheint der Unterschied zwischen einem einzelnen Character und einem 
String komplett und völlig egal zu sein.

https://www.mikrocontroller.net/articles/String-Verarbeitung_in_C

Kauf dir ein C Buch und arbeite es zumindest bis zur Hälfte durch. Da 
gibt es noch viele Dinge, die du wissen und können musst, ehe du 
sinnvoll ein reales Programm schreiben kannst.

von knoddelpusch (Gast)


Lesenswert?

Hallo,
ich habe jezt mal im internet und auf dem link noch mehr informiert und 
hoffe das ich das jetzt etwas mehr verstanden habe.

Jetzt müsste ich doch wenn ich einen Wert x an den Controller sende der 
Wert in der Variable Line gespeicher sein oder?

Und mit dem "itoa (Line, Buffer, 10);" wandle ich den Wert x in ein 
Ascii zeichen um?

oder hab ich da nochmal was falsch verstanden
1
#include <avr/io.h>
2
#include <stdlib.h>
3
#include <inttypes.h>
4
#include <util/delay.h>
5
#include <string.h>
6
7
8
//#include "uart.h"
9
10
#define F_CPU 1200000   /* evtl. bereits via Compilerparameter definiert */
11
#define BAUD 9600UL      // Baudrate
12
 
13
// Berechnungen
14
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
15
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
16
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD)     // Fehler in Promille, 1000 = kein Fehler.
17
 
18
#include <util/setbaud.h>
19
20
//----------------------------------------------------------------------------------------------------
21
22
// UART konfig
23
24
void uart_init (void)
25
{
26
  UBRRH = UBRR_VAL >> 8;
27
  UBRRL = UBRR_VAL & 0xFF;
28
  
29
  UCSRB |= (1<<TXEN) | (1<<RXEN);    //UART TX und RX einschalten
30
  UCSRC = (1<<URSEL) |(1<<UCSZ1) | (1<<UCSZ0); // Einstellen des Datenformats: 8 Datenbits, 1 Stoppbit
31
}
32
33
//----------------------------------------------------------------------------------------------------
34
35
//Zeichen Senden
36
int uart_putc(unsigned char c)
37
{
38
  while (!(UCSRA & (1<<UDRE)))
39
  {
40
  }
41
  UDR = c;
42
  return 0;
43
}
44
45
//----------------------------------------------------------------------------------------------------
46
47
void uart_puts (char *s)
48
{
49
    while (*s)
50
    {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen(Terminator)" */
51
        uart_putc(*s);
52
        s++;
53
    }
54
}
55
56
57
//----------------------------------------------------------------------------------------------------
58
59
//Zeichen Empfanen 
60
uint8_t uart_getc(void)
61
{
62
  while (!(UCSRA & (1<<RXC)))  //warten bis Zeichen verfügbar 
63
  ;
64
  return UDR;    //Zeichen aus UDR an Aufrufer zurückgeben
65
}
66
67
//----------------------------------------------------------------------------------------------------
68
69
70
void uart_gets( char* Buffer, uint8_t MaxLen )
71
{
72
  uint8_t NextChar;
73
  uint8_t StringLen = 0;
74
 
75
  NextChar = uart_getc();         // Warte auf und empfange das nächste Zeichen
76
 
77
                                  // Sammle solange Zeichen, bis:
78
                                  // * entweder das String Ende Zeichen kam
79
                                  // * oder das aufnehmende Array voll ist
80
  while( NextChar != '\n' && StringLen < MaxLen - 1 ) {
81
    *Buffer++ = NextChar;
82
    StringLen++;
83
    NextChar = uart_getc();
84
  }
85
 
86
                                  // Noch ein '\0' anhängen um einen Standard
87
                                  // C-String daraus zu machen
88
  *Buffer = '\0';
89
}
90
91
92
//----------------------------------------------------------------------------------------------------
93
94
int main (void) 
95
{
96
  
97
  DDRB = 0xFF;
98
  PORTB = 0xFF;
99
100
int Line [8];      //Array vom Typ int
101
102
char Buffer[9];      //String mit maximal 8 zeichen
103
104
uart_init();      // UART einstellen
105
  
106
    while (1)
107
     {
108
109
110
  if ( (UCSRA & (1<<RXC)))      //überprüfen ob neue Zeichen vorhanden sind
111
  {                  //Zeichen wurden empfangen, jetzt abholen
112
    uart_gets (Line, sizeof(Line));
113
114
    itoa (Line, Buffer, 10);
115
    uart_puts(Buffer);
116
  }
117
  else
118
  {
119
  
120
121
    PORTB = 0b00000000;    //Port B schalten
122
    _delay_ms(1000);  //WarteZeit t
123
    PORTB =0b11111111;    //Port B ausschalten
124
    _delay_ms(1000);    //WarteZeit t
125
    PORTB = 0b00000000;    //Port B schalten
126
    _delay_ms(1000);    //WarteZeit t
127
    PORTB =0b11111111;    //Port B ausschalten
128
  }
129
   }
130
 
131
   return 0; // never reached 
132
133
 
134
}

von Karl H. (kbuchegg)


Lesenswert?

knoddelpusch schrieb:

> Jetzt müsste ich doch wenn ich einen Wert x an den Controller sende der
> Wert in der Variable Line gespeicher sein oder?

Du sendest keinen 'Wert'.
Du sendest einen String! EInen Text.
An dieser Stelle gibt es noch keinen Unterschied, ob dieser Text "123" 
oder "Hugo" beinhaltet. Text ist erst mal Text.

(UNd die Empfangsroutine erwartet, dass der Text mit einem Carriage 
Return abgeschlossen ist. Denn woher soll diese Routine denn sonst 
wissen, dass du nach "Hugo" nicht noch ein weiteres Zeichen senden 
willst?)

Wenn du weisst, das dein Text eben nicht "Hugo" lautet, sondern "123", 
dann kannst du die Funktion atoi benutzen, um aus diesem Text eine Zahl 
mit dem Zahlenwert von 123 machen zu lassen. Erst dann hast du einen 
Wert mit dem du zb auch rechnen kannst oder was auch immer du damit 
machen willst.


Die umgekehrte Übertragungsrichtung lautet dann so:
du hast eine Zahl, die in einer int Variablen vorliegt. Da du sie 
textuell (also in Form von ASCII Zeichen) übertragen willst, musst du 
erst mal aus dieser Zahl einen entsprechenden String generieren lassen. 
Das erledigt itoa. Es erzeugt aus der Zahl 123 den String "123". Wieder: 
dieser String könnte prinizpiell auch "Hugo" oder "Anna" sein, das wäre 
der String Sende Funktion völlig gleichgültig. Nur ist den String eben 
nicht "Hugo", sondern "123". Ein Text wie jeder andere auch.

> Und mit dem "itoa (Line, Buffer, 10);" wandle ich den Wert x in ein
> Ascii zeichen um?

Nein. Nicht in 1 ASCII Zeichen.
1 ASCII Zeichen ist 1 Buchstabe. Wobei unter Buchstaben auch Dinge wie 
'=' oder '0' oder '7' oder ',' fallen. Den Begriff Buchstaben da jetzt 
nicht zu wörtlich nehmen. Wichtig ist: es wäre genau 1ner.

Das kannst du aber nicht brauchen. Denn der String "Hugo" besteht aus 4 
Buchstaben! Oder der String "123" - der besteht aus 3 Buchstaben- Oder 
"65320", der besteht aus 5 Buchstaben.

Ein String ist also eine Abfolge von meheren Einzelbuchstaben. Um einen 
String zu übertragen muss man daher Buchstabe für Buchstabe einzeln 
übertragen. genau das macht die uart_puts.

Disclaimer: In C sind Strings immer um genau 1 Zeichen länger als sie 
lesbare Buchstaben haben. Denn ganz zum Schluss kommt immer ein 
Buchstabe mit dem ASCII Codewert von 0. Der String "Hugo" hat also in C 
nicht 4 Buchstaben, sondern deren 5.

von knoddelpusch (Gast)


Lesenswert?

Das heist ich muss wenn ich vom Pc auf Ic "123" senden will danach noch 
ein "\n" dranhängen?
Auch wenn mein Array gößer ist, ist dann die "Empfangsroutine" 
abgeschlossen und mein Array ist dann halt nicht ganz gefüllt?

Mit "a=atoi(Line)"
weiße ich meiner variable a den Wert 123 zu.
Geht das auch wenn ich schon mit einem Ascii zeichen z.B. "A" rüberkomme 
das ich die Zahl 65 bekomme?
Habe das irgendwo mal gelesen das ich mit der Funktion "atoi" einen 
Ascii Zeichen wider in einen Wert umwandeln kann.
Oder ist die atoi funktion nicht direkt auf die Ascii-Tabelle bezogen.

Und mit "itoa (a, Buffer, 10)" erstelle ich mir wider einen String 
(Buffer) der den Text "123" bzw das was in der Variable a steht.
Mit dem itoa bekomme ich ja dann schon einen Null-Terminierten string 
zurück?
1
// UART konfig
2
3
void uart_init (void)
4
{
5
  UBRRH = UBRR_VAL >> 8;
6
  UBRRL = UBRR_VAL & 0xFF;
7
  
8
  UCSRB |= (1<<TXEN) | (1<<RXEN);    //UART TX und RX einschalten
9
  UCSRC = (1<<URSEL) |(1<<UCSZ1) | (1<<UCSZ0); // Einstellen des Datenformats: 8 Datenbits, 1 Stoppbit
10
}
11
12
//----------------------------------------------------------------------------------------------------
13
14
//Zeichen Senden
15
int uart_putc(unsigned char c)
16
{
17
  while (!(UCSRA & (1<<UDRE)))
18
  {
19
  }
20
  UDR = c;
21
  return 0;
22
}
23
24
//----------------------------------------------------------------------------------------------------
25
26
void uart_puts (char *s)
27
{
28
    while (*s)
29
    {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen(Terminator)" */
30
        uart_putc(*s);
31
        s++;
32
    }
33
}
34
35
36
//----------------------------------------------------------------------------------------------------
37
38
//Zeichen Empfanen 
39
uint8_t uart_getc(void)
40
{
41
  while (!(UCSRA & (1<<RXC)))  //warten bis Zeichen verfügbar 
42
  ;
43
  return UDR;    //Zeichen aus UDR an Aufrufer zurückgeben
44
}
45
46
//----------------------------------------------------------------------------------------------------
47
48
49
void uart_gets( char* Buffer, uint8_t MaxLen )
50
{
51
  uint8_t NextChar;
52
  uint8_t StringLen = 0;
53
 
54
  NextChar = uart_getc();         // Warte auf und empfange das nächste Zeichen
55
 
56
                                  // Sammle solange Zeichen, bis:
57
                                  // * entweder das String Ende Zeichen kam
58
                                  // * oder das aufnehmende Array voll ist
59
  while( NextChar != '\n' && StringLen < MaxLen - 1 ) {
60
    *Buffer++ = NextChar;
61
    StringLen++;
62
    NextChar = uart_getc();
63
  }
64
 
65
                                  // Noch ein '\0' anhängen um einen Standard
66
                                  // C-String daraus zu machen
67
  *Buffer = '\0';
68
}
69
70
71
//----------------------------------------------------------------------------------------------------
72
73
int main (void) 
74
{
75
  
76
  DDRB = 0xFF;
77
  PORTB = 0xFF;
78
79
int Line [8];      //Array vom Typ int
80
81
char Buffer[9];      //String mit maximal 8 zeichen
82
83
int a;
84
85
uart_init();      // UART einstellen
86
  
87
    while (1)
88
     {
89
90
91
  if ( (UCSRA & (1<<RXC)))      //überprüfen ob neue Zeichen vorhanden sind
92
  {                  //Zeichen wurden empfangen, jetzt abholen
93
    uart_gets (Line, sizeof(Line));
94
95
    a=atoi(Line);          //aus Text eine Zahl machen
96
  
97
    itoa (a, Buffer, 10);      // Aus der Variablen a ein Text erstellen
98
99
    uart_puts(Buffer);      //Senden Text aus Buffer
100
101
  }
102
  else
103
  {
104
  ...

von Axel S. (a-za-z0-9)


Lesenswert?

knoddelpusch schrieb:
> ich habe ein Programm geschrieben wo ich an einen Ic warte Zeiten ändern.

Welche Sprache ist das? Deutsch wohl nicht.

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.