Forum: Mikrocontroller und Digitale Elektronik ADC-Wert über RS232 übermitteln


von Fox (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Zusammen

Was möchte ich mache: ADC Signal auf den PC durch RS232 einspielen. Also 
den Bitwert übermitteln.

Was wurde gemacht:
1. ATMega8 und Übermittlung eines Zeichen x und weitere!
2. Zusammenbau eines Converters, welcher das Signal von Mikrokontroller 
auf RS232 umwandelt und dessen Übermittlung und Darstellung von x in 
Hyperterminal.
2. ADC Wandlung funktioniert (ADMUX = 0), schaltet LEDs an ab 800bit.

Was geht noch nicht:
Übermittlung des ADC-Wertes

wie kann ich das realisieren? Ich muss ja irgend wie den Bitwert 
auftrennen und einzeln übermittel. z.B. wenn ich Bitwert von 300habe 
dann übermittle ich zuerst das 3 dann die 0 und nochmals eine 0. und 
irgend ein Trennzeichen z.B. ; wäre gut.

Gruss Fox

von crazy horse (Gast)


Lesenswert?

printf() ist eine einfache Möglichkeit.

von rooot (Gast)


Lesenswert?

Hi,

puts(char *), putchar( char )

ist besser


prinf (scanf) sind zwar oft verwendet, aber sehr kompliziertesten 
Funktionen

printf (conio.h, stdio.h) braucht ca. 1k Speicher

Ich weis nicht ob das in diesem Projekt relevant ist (glaube eher 
nicht), vor allem bei µC Programmen ist auf solche dinge zu achten

mfg
rooot

von Fox (Gast)


Lesenswert?

Also die Buchstaben werden ja einzeln übermitteln.
1
    UDR = 'x';          // auch UDR = 0b00101000;
2
    while (!(UCSRA & (1<<UDRE))) {
3
  }

jetzt muss ich da putchar( char ) irgend etwas machen?

von Gast (Gast)


Lesenswert?

ReadChannel ist die Funktion aus dem AVR-Tutorial und es wird die RS232 
Lib von Fleury verwendet.
1
//var
2
3
char buffer[7];
4
uint16_t adcval;
5
6
//senden
7
8
adcval = ReadChannel(0);
9
itoa(adcval,buffer,10);
10
uart_puts(buffer);

Funktioniert einwandfrei bei mir...

von Fox (Gast)


Lesenswert?

Bekomme ein Error. wo muss ich das jetzt bei meinem Code einbauen?

von Fox (Gast)


Lesenswert?

Habe noch von hier (Schreiben von Zeichenkette:
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Der_interne_ADC_im_AVR


Das versucht:
1
int uart_putc(unsigned char c)
2
{
3
    while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich */
4
    {
5
    }                             
6
 
7
    UDR = c;                      /* sende Zeichen */
8
    return 0;
9
}

klappt aber leider nicht.

von ozo (Gast)


Lesenswert?

Na, dann lass uns doch nicht im Regen stehen. Was für ein Error kommt 
denn?

von Fox (Gast)


Angehängte Dateien:

Lesenswert?

So bekomme kein Error, jedoch sendet es mir nur eine 0!
Wo ist der Fehler?

Der wichtigste Ausschnitt:
1
char s[7];
2
int16_t i = value;
3
itoa( i, s, 10 );
4
UDR = s;

von Fox (Gast)


Lesenswert?

Vielleichts nochmals anders:

Wenn ich das hier habe, funktioniert es:
1
int senden(void)
2
{
3
4
5
    while (!(UCSRA & (1<<UDRE))) {
6
  }
7
8
    UDR = 't';

Wenn ich das hier mache:
1
int senden(void)
2
{
3
4
5
   char s[7];
6
   int16_t i = -12345;
7
   
8
   uart_init();
9
 
10
   itoa( i, s, 10 ); // 10 fuer radix -> Dezimalsystem
11
   uart_puts( s );

Es kommen die Errors:

../Projekt0006.c: In function 'main':
../Projekt0006.c:49: warning: implicit declaration of function 'senden'
../Projekt0006.c: In function 'senden':
../Projekt0006.c:62: warning: implicit declaration of function 
'uart_init'
../Projekt0006.c:65: warning: implicit declaration of function 
'uart_puts'
../Projekt0006.c:108: warning: no return statement in function returning 
non-void
avr-gcc.exe -mmcu=atmega8 -Wl,-Map=Projekt0006.map Projekt0006.o     -o 
Projekt0006.elf
Projekt0006.o: In function `senden':
C:\(Meine Daten)\Privat\(AVR 
Projekte)\Projekte\default/../Projekt0006.c:62: undefined reference to 
`uart_init'
C:\(Meine Daten)\Privat\(AVR 
Projekte)\Projekte\default/../Projekt0006.c:65: undefined reference to 
`uart_puts'
make: *** [Projekt0006.elf] Error 1
Build failed with 2 errors and 4 warnings...

von Karl H. (kbuchegg)


Lesenswert?

Du musst noch den Unterschied zwischen einem einzelnen Zeichen
und einem String verinnerlichen.
Ein einzelnes Zeichen ist einfach nur ein einzelnes Zeichen.
Ein char ist so etwas. Aber auch 'x' oder 'a' oder '8'.

Deine Funktion
1
int uart_putc(unsigned char c)
2
{
3
    while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich */
4
    {
5
    }                             
6
 
7
    UDR = c;                      /* sende Zeichen */
8
    return 0;
9
}

kann nur ein einzelnes Zeichen versenden.

Und jetzt kommt itoa ins Spiel und damit auch Strings. Strings
sind Abfolgen von Zeichen, wobei vereinbarungsgemäß das letzte
Zeichen des Strings das '\0' Zeichen ist.

Hmm. Ein String sind also mehrere Zeichen. uart_putc kann aber nur
ein einzelnes Zeichen versenden. Das passt nicht zusammen.

Also wirst du dir wohl eine Funktion basteln müssen, die einen
String (also eine Abfolge von mehreren Zeichen) versenden kann.
Die kann durchaus auf uart_putc zurückgreifen.

Hier ist zb eine
1
void uart_puts( char* String )
2
{
3
  while( *String != '\0' ) {
4
    uart_putc( *String );
5
    String++;
6
  }
7
}

und diese Funktion kannst du jetzt verwenden, wenn du einen String
versenden willst
1
  ...
2
  uart_init();
3
4
  uart_puts( "Hallo\n" );
5
6
  char s[7];
7
  int16_t i = -12345;
8
  itoa( i, s, 10 ); // 10 fuer radix -> Dezimalsystem
9
  uart_puts( s );


PS: Schön langsam wirds Zeit für dich, etwas Literatur zu besorgen
und zu lesen.

http://www.mikrocontroller.net/articles/FAQ#Wie_kann_ich_Zahlen_auf_LCD.2FUART_ausgeben.3F
http://www.mikrocontroller.net/articles/FAQ#Wie_funktioniert_String-Verarbeitung_in_C.3F

von Rüdiger K. (sleipnir)


Lesenswert?

Wenn Du Matlab oder den freien Clone "Octave" hast kannst Du die Werte 
auch binärcodiert übermitteln und so einfach erfassen:
fid=fopen("/dev/ttyS0","rb"); x=fread(fid,10240,"uchar"); fclose(fid); 
plot(x)

Wie die serielle Schnittstelle unter Windows angesprochen wird weiß ich 
jetzt allerdings nicht.

von Karl H. (kbuchegg)


Lesenswert?

> Es kommen die Errors:
>
> ../Projekt0006.c: In function 'main':
> ../Projekt0006.c:49: warning: implicit declaration of function 'senden'
> ../Projekt0006.c: In function 'senden':
> ../Projekt0006.c:62: warning: implicit declaration of function
> 'uart_init'
> ../Projekt0006.c:65: warning: implicit declaration of function
> 'uart_puts'
> ../Projekt0006.c:108: warning: no return statement in function returning
> non-void

Diese Warnungen/Fehler allerdings haben eine ganz andere Ursache.
Dein Compiler liest deinen Quellcode von oben nach unten. Und zwar
genau ein mal.

Wenn der Compiler oben anfängt, dann kennt er gerade mal die
C Schlüsselwörter. Jedes andere Wort ist ihm unbekannt. Zb. auch
die Namen von Funktionen.
Erst durch das Lesen des Quelltextes (von oben nach unten) wird dem
Compiler mitgeteilt, dass 'senden' kein Tippfehler ist, sondern
der Name einer Funktion und das daher der Aufruf einer derartigen
Funktion auch keinen Fehler darstellt, sondern dass es die Funktion
auch wirklich gibt.
Das geht aber nur dann, wenn man die Funktion deklariert, bevor
sie das erste mal aufgerufen wird. Wie gesagt: Der Compiler liest
nur einmal von oben nach unten. Kommt der Aufruf vor der Deklaration,
so wie hier
1
int main()
2
{
3
  senden();
4
}
5
6
void senden( void )
7
{
8
}
dann hat der Compiler beim Aufruf der Funktion ein Problem. Er weiss
ja nicht, dass es tatsächlich eine Funktion namens 'senden' gibt.
Er hat sie ja bisher noch nicht gesehen, denn soweit hat er ganz
einfach nicht gelesen.
Also muss man das ganze umdrehen (es gibt noch eine 2.te Möglichkeit,
aber darüber erzähle ich jetzt nichts)
1
void senden( void )
2
{
3
}
4
5
int main()
6
{
7
  senden();
8
}

Wenn man diesen Text von oben nach unten liest, dann taucht zuerst
die Vereinbarung für senden auf. Der Compiler registriert diese
und merkt sich, dass es eine Funktion dieses Namens gibt.
Wenn er dann weiter liest und den Aufruf der Funktion findet, geht
er seine internen Tabellen durch und findet dort, dass es tatsächlich
eine Funktion dieses Namens gibt.

PS: Sagte ich schon, dass es Zeit für ein Buch wird? Wenn nicht:
Es wird Zeit ein Buch über C zu lesen!

von crazy horse (Gast)


Lesenswert?

ich finde die 2.Möglichkeit aber besser :-)
Sonst man spätestens bei etwas komplexeren Programmen nur noch am 
umsortieren.

von Fox (Gast)


Lesenswert?

Ich habe den Code jetzt mal auf ein Minimum reduziert. Bitte helft mir, 
ich bin am verzweifeln!!!

Habe es genau so gemacht, wie im Tutorial. Bekomme aber ein Fehler beim 
Compilieren. Da stimmt was nicht mit:

../Projekt0006.c:26: warning: return type of 'main' is not 'int'
../Projekt0006.c: In function 'main':
../Projekt0006.c:49: warning: implicit declaration of function 
'uart_init'
../Projekt0006.c:52: warning: implicit declaration of function 
'uart_puts'
../Projekt0006.c:74: warning: 'return' with a value, in function 
returning void
../Projekt0006.c:77: error: expected declaration or statement at end of 
input
make: *** [Projekt0006.o] Error 1
Build failed with 1 errors and 4 warnings...

Ich glaub es hängt damit zusammen, dass das noch etwas von dem hier 
steht:
// hier uart_init, uart_putc, uart_puts (s.o.)
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <inttypes.h>
4
#include <stdlib.h>
5
6
#ifndef F_CPU
7
#define F_CPU 8000000L    // Systemtakt in Hz, das L am Ende ist wichtig, NICHT UL verwenden!
8
#endif
9
#include <util/delay.h>
10
#define BAUD 9600L          // Baudrate, das L am Ende ist wichtig,NICHT UL verwenden!
11
12
// Berechnungen
13
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
14
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
15
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD-1000) // Fehler in Promille
16
17
#if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))
18
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu
19
hoch!
20
#endif
21
22
/* sdsgsdfgdfg */
23
24
25
26
void main() {
27
28
29
    UCSRB |= (1<<TXEN);                // UART TX einschalten
30
    UCSRC |= (1<<URSEL)|(3<<UCSZ0);    // Asynchron 8N1 
31
 
32
    UBRRH = UBRR_VAL >> 8;
33
    UBRRL = UBRR_VAL & 0xFF;
34
35
36
37
38
  while (1)
39
  {
40
41
42
   char s[7];
43
   int16_t i = -12345;
44
   
45
   uart_init();
46
 
47
   itoa( i, s, 10 ); // 10 fuer radix -> Dezimalsystem
48
   uart_puts( s );
49
 
50
   // da itoa einen Zeiger auf den Beginn von s zurueckgibt verkuerzt auch:
51
   uart_puts( itoa( i, s, 10 ) );
52
 
53
   while (1) {
54
      ;
55
   }
56
57
58
return(0);
59
60
61
}

von Fox (Gast)


Lesenswert?

So habe noch int main(void) { geschrieben. daher nur noch 3 Fehler:

../Projekt0006.c:5:18: error: uart.h: No such file or directory
../Projekt0006.c: In function 'main':
../Projekt0006.c:47: warning: implicit declaration of function 
'uart_init'
../Projekt0006.c:50: warning: implicit declaration of function 
'uart_puts'
../Projekt0006.c:63: error: expected declaration or statement at end of 
input
make: *** [Projekt0006.o] Error 1
Build failed with 2 errors and 2 warnings...

von ozo (Gast)


Lesenswert?

Sag mal, willst du uns hier verarschen?
Karl heinz Buchegger hat dir doch mit Engelsgeduld alles erklärt?!

Ich darf dich mal zitieren:
---
Ich glaub es hängt damit zusammen, dass das noch etwas von dem hier
steht:
// hier uart_init, uart_putc, uart_puts (s.o.)
---

Und dann deinen Compiler:
---
../Projekt0006.c:47: warning: implicit declaration of function
'uart_init'
../Projekt0006.c:50: warning: implicit declaration of function
'uart_puts'
---

Klingelts?

von ozo (Gast)


Lesenswert?

Hier hast du, hoffe es geht. Sollte für nen mega16 sein...sollte :)
1
#define F_CPU 8000000UL // 8MHz
2
#include <avr/io.h>
3
#include <avr/delay.h>
4
5
6
void init_usart() {
7
  UBRRH=0;
8
  UBRRL=51; //9600 baud
9
  UCSRB = (1<<TXEN); //transmitter enable
10
  UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0); // 8data,2stop
11
}
12
13
14
void send_char(char c) {
15
  while (!(UCSRA & (1<<UDRE))) {}
16
  UDR=c;
17
}
18
19
void send_string(char* s) {
20
  while(*s) {
21
    send_char(*s);
22
    s++;
23
  }
24
}
25
26
int main(void) {
27
  init_usart();
28
  send_string("hallo welt!\n");
29
  while (1) {}
30
31
  return 0;
32
}

von Fox (Gast)


Angehängte Dateien:

Lesenswert?

So habs schon fast geschafft:

Kann jetzt ein String senden "Hallo !".

Wie kann ich jetzt ADCW anstatt Hallo übermitteln?

Das hier klappt nicht:   char c[] = ADCW;

Liegt glaub am Datentyp.

von Karl H. (kbuchegg)


Lesenswert?

Fox wrote:
> So habs schon fast geschafft:
>
> Kann jetzt ein String senden "Hallo !".
>
> Wie kann ich jetzt ADCW anstatt Hallo übermitteln?
>
> Das hier klappt nicht:   char c[] = ADCW;
>
> Liegt glaub am Datentyp.

???
Das hatten wir doch schon mal, so vor ungefähr 10 Postings.
Du bringst mich noch soweit, dass ich ein Merkbefreiungsformular
ausfülle.
1
  char s[10];
2
3
  itoa( ADCW, s, 10 );
4
  uart_puts( s );

PS: Ich weiß nicht ob ich es schon erwähnt habe, aber es wird
DRINGEND Zeit für ein C-Buch

von Fox (Gast)


Lesenswert?

Danke den Post. Ja habe ich schon hier, aber man braucht halt sehr viel 
Zeit für das Ganze. Bin auch erst am einsteigen. Weiss halt noch nicht 
was ich alles machen möchte. Muss mich mal herantasten.

Habe jetzt denne alle Funktionenen zusammen, die ich eigentlich brauche. 
Danach kann man ausbauen.

Habe
- C++ .Net, Ron Nanko
- Programmiertechniken für AVR-Mikrokontroller, Manfred Schwabl-Schmidt

Gruss Fox

von Fox (Gast)



Lesenswert?

Ja bin schon ein wenig müde...

Ja voll cool! Jetzt klappts! Vielen Dank! Ich bin sehr Glücklich!!!

Im Anhang noch den ganzen Code für den ATMega8.

Gruss Fox

von Karl H. (kbuchegg)


Lesenswert?

Fox wrote:

> Im Anhang noch den ganzen Code für den ATMega8.

Build succeeded with 5 Warnings...

Manchmal frag ich mich, wozu ich mir eigentlich den Mund
fusselig rede.

von Karl H. (kbuchegg)


Lesenswert?

Fox wrote:

> - C++ .Net, Ron Nanko

Aha. Und das ist jetzt beim Versuch C zu lernen genau wie hilfreich?

> - Programmiertechniken für AVR-Mikrokontroller, Manfred Schwabl-Schmidt

Schon besser. Dürfte aber immer noch um mindestens 2 Nummern
zu komplex in deiner gegenwärtigen Situation sein.

Es hilft nichts. Du brauchst ein Buch über C. Nicht C++, nicht C#,
sondern C. Und zwar Grundlagen, keine Programmiertechniken, Grundlagen
die bei 0 anfangen.

von Fox (Gast)



Lesenswert?

>Manchmal frag ich mich, wozu ich mir eigentlich den Mund
fusselig rede.

Das wir, welche nicht die grosse Ahnung haben, daraus etwas lernen! Also 
dass man sein Wissen weitergeben kann. Das ist doch auch schön...

Habe noch den Code durchgegangen. Konnte alle Warnungen beseitigen.

-------------------------------------------

Device: atmega8

Program:     390 bytes (4.8% Full)
(.text + .data + .bootloader)

Data:          0 bytes (0.0% Full)
(.data + .bss + .noinit)


Build succeeded with 0 Warnings...

von Gast (Gast)


Lesenswert?

Also ich weiß zwar nicht, wieso du dir die Mühe mit dem Semikolon 
machst, aber eine Frage habe ich: Wieso deklarierst du Funktionen in 
einer Funktion?

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.