Forum: Mikrocontroller und Digitale Elektronik UART Problem mit String


von Jörn (Gast)


Lesenswert?

Hy

Habe folgendes zusammengeschustert aber irgendwie will er mir nix 
ausgeben !! Mega8l & MyAVR Board 1.5

Es soll über den AD die Spannung vom Poti eingelesen werden. Der Wert 
wird per PWM an den Summer geschlossen

Das klappt wunderbar.

Aber die Ausgabe per R232 will einfach nicht!!

wo liegt der Fehler??

hier das Programm

#define   F_CPU 3686400
#define BAUD    9600
#define UBRR_BAUD  ((F_CPU/(16*BAUD))-1)
#include  <avr/io.h>

int zeichen(unsigned char c)
{
  while(!(UCSRC & (1 << UDRE)));   // Abfrage ob senden möglich
  UDR = c;        // Senderegister
  return 0;
}

void string(char *s)
{
  while (*s)
  {
    zeichen(*s);
    s++;
  }
}

int main (void)
{

  DDRB = 0xFF;
  int b = 0;
  ADCSRA = _BV(ADEN) | _BV(ADPS1) | _BV(ADPS2);

  for (;;)
  {
    ADMUX = 0;
    ADCSRA |= _BV(ADSC);
    while (ADCSRA & _BV(ADSC) )
    {}
    b = ADCW;
    b = ~b>>2;
    TCCR1A = (1<<COM1A1) | (1<<WGM11) | (1<<WGM10);
    TCCR1B = (1<<CS11);
    OCR1A = (b/30);
    DDRB = 0x02;  //Summer Ausgabe
    UBRRH = (UBRR_BAUD>>8);
    UBRRL = UBRR_BAUD;
    string(b);

  }

}

von Karl H. (kbuchegg)


Lesenswert?

Deine RS232 ist ja gar nicht initialisiert.
Schau mal ins AVR-Gcc Tutorial. Da sind alle Schritte
drin, die du machen musst um eine RS232 in Betrieb zu nehmen.

Weiters:
Initialisiert wird eine Baugruppe nur einmal.
Es ist daher nicht so gut, wenn du das in der for-Schleife
immer und immer wieder machst. Im besten Fall passiert
dabei gar nichts und du verplemperst nur Zeit. Im schlimmsten
Fall würgt dir die erneute Initialisierung eine laufende
Operation auf dieser Baugruppe ab.

von Jörn (Gast)


Lesenswert?

ok danke für den Tip.

Ich hab die Initialisierung oben vor die Schleife gepackt und zur 
Einfachheit erstmal nur ein Zeichen zur Ausgabe in die Mainfunktion 
gepackt.

Nutze das Program Terminal. Verbindung 9600, Data Bits 8, Parity none, 
handshake none.

leider kommt nix trotz dem dauersenden der for schleife nix an?

#define   F_CPU 3686400
#define BAUD    9600
#define UBRR_BAUD  ((F_CPU/(16*BAUD))-1)
#include  <avr/io.h>

int zeichen(unsigned char c)
{
 while(!(UCSRC & (1 << UDRE)));   // Abfrage ob senden mšglich
 UDR = c;        // Senderegister
 return 0;
 }

 void string(char *s)
 {
 while (*s)
 {    zeichen(*s);
     s++;

 }
 }

 int main (void){
 DDRB = 0xFF;
 int b = 0;
 ADCSRA = _BV(ADEN) | _BV(ADPS1) | _BV(ADPS2);

 UCSRB |= (1<<TXEN);
 UCSRC |= (1<<URSEL)|(3<<UCSZ0);
 UBRRH = (UBRR_BAUD>>8);
 UBRRL = UBRR_BAUD;

 for (;;)
 {
 ADMUX = 0;
 ADCSRA |= _BV(ADSC);
 while (ADCSRA & _BV(ADSC) )
 {}
 b = ADCW;
 b = ~b>>2;
 TCCR1A = (1<<COM1A1) | (1<<WGM11) | (1<<WGM10);
 TCCR1B = (1<<CS11);
 OCR1A = (b/30);
 DDRB = 0x02;  //Summer Ausgabe
 zeichen('a');
 }
}

von Karl H. (kbuchegg)


Lesenswert?


>  while(!(UCSRC & (1 << UDRE)));

Das UDRE Bit ist im Register UCSRA, nicht UCSRC

Anbei ein auf einem Mega8 getestetes Pgm.

#define F_CPU    3686400UL

#include <avr/io.h>
#include <inttypes.h>

#define BAUD     19200UL
#define UBRR_BAUD  ((F_CPU)/(16*(BAUD))-1)

int uart_putc(unsigned char c)
{
  while (!(UCSRA & (1<<UDRE)))
    ;

  UDR = c;
  return 0;
}

uint8_t uart_getc(void)
{
  while (!(UCSRA & (1<<RXC)))
    ;
  return UDR;
}

void uart_puts( char* str )
{
  while( *str )
    uart_putc( *str++ );
}

int main(void)
{
  UCSRB   |= (1 << TXEN) | ( 1 << RXEN );  // UART TX, RX einschalten
  UCSRC   |= ( 1 << URSEL )|( 3<<UCSZ0 );  // Asynchron 8N1
  UBRRH  = (uint8_t) (UBRR_BAUD>>8);  // USART Baud
  UBRRL  = (uint8_t) UBRR_BAUD;

  uart_puts( "\r**** ATMega8 ****\r" );
  uart_puts( "Hallo World\r" );

  while( 1 ) {
    char c = uart_getc();

    if( c == 0x08 ) {
      uart_putc( 0x08 );
      uart_putc( ' ' );
      uart_putc( 0x08 );
    }
    else {
      uart_putc( c );
    }
  }
}

von Jörn (Gast)


Lesenswert?

mhhh vielen Dank für den Script...

leider gibt er das nie aus:

uart_puts( "\r**** ATMega8 ****\r" );
  uart_puts( "Hallo World\r" );

Wenn ich was sende, kommt es auch zurück das klappt teils gut

h,i,j,k,m,l,werden richtig übertragen
a,b,g,o nur zeichen

liegt das evtl an nicht 100% rrichtiger interer Frequenz?

von Jörn (Gast)


Lesenswert?

ok die Fehlerhaften zeichen lagen an der Frequenz einstellung im 
Programm...

Aber

1. das NUR senden klappt nicht!!

2. wie kann die int Zahl vom AD in den char für die R232 umwandeln?

von Winfried J. (Firma: Nisch-Aufzüge) (winne) Benutzerseite


Lesenswert?

b.s=itoa(a.int)

von Karl H. (kbuchegg)


Lesenswert?

void uart_putint( int num )
{
  unsigned char buffer[10];

  itoa( num, buffer, 10 );
  uart_puts( buffer );
}

von Stefan (Gast)


Lesenswert?

unsigned char buffer[7]; müsste doch für 'int num' reichen?

Max. 5 Zeichen für die Dezimalzahl und ein Zeichen für's abschliessende 
Nullbyte sowie ggf. ein Zeichen für's Vorzeichen.

von Karl H. (kbuchegg)


Lesenswert?

Bei solchen Sachen dimensioniere ich meist
grosszügig. Ob da jetzt temporär am Stack
7 oder 10 chars reserviert werden, spielt keine
Rolle.
Ich hab allerdings schon genügend Programme gesehen,
bei denen sich der Programmierer knausrig gezeigt
hat, manchmal auch zu knausrig, und das Array überlaufen
hat.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

> Ob da jetzt temporär am Stack 7 oder 10 chars reserviert
> werden, spielt keine Rolle.

Es sei denn, der läuft dadurch über ...

von Joe (Gast)


Lesenswert?

itoa kann ebenso zur Basis 2 ausgeben => 16 Byte. Es gibt Compiler die 
auch ein Array dieser Größe erwarten obwohl Basis 10 gewählt wurde. Das 
macht dann besonders viel Spaß ;-))

von Karl H. (kbuchegg)


Lesenswert?

>> Ob da jetzt temporär am Stack 7 oder 10 chars reserviert
>> werden, spielt keine Rolle.
>
> Es sei denn, der läuft dadurch über ...

:-) OK. Wenn es knapp wird und man die 3 Bytes nicht mehr hat, ...

von Jörn (Gast)


Lesenswert?

und in welcher Libary ist die funktion itoa enthalten?

von Karl H. (kbuchegg)


Lesenswert?

#include <stdlib.h>

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.