Forum: Mikrocontroller und Digitale Elektronik ATMEL UART @ 2313


von Klaus (Gast)


Lesenswert?

Hallo!

Ich würde gerne in ein programm eine Routine implementieren, die einen
string über die UART schickt, dabei habe ich mich am tutorial
"orientiert", allerdings bläht sich der hex code auf 8,81kb auf...ich
vermute, die "art und weise" der programmierung ist nicht sehr gut,
evtl kann mir mal jemand ein paar tips geben? und: ich programmiere in
C, auch wenn das natürlich mehr als suboptimal ist, aber für die
anfänge bequem und eine nachträgliche optimierung anhand des assembly
dump bring immer viel...also evtl eine kurze C Routine um zB "hello
world" über die uart zu senden? Initialisierung ist soweit klar.

Danke, Klaus. (Hierher verwiesen von spotlight.de)

von Benedikt (Gast)


Lesenswert?

Poste mal deinen Code, oder suche in der Codesammlung nach fertigen
Routinen.

von Klaus (Gast)


Lesenswert?

#include <avr/io.h>
#include <stdio.h>
#include <avr/signal.h>
#include <avr/interrupt.h>

#define SIG_INTERRUPT0 _VECTOR(1)

#ifndef F_CPU
#define F_CPU 4000000;
#endif
#define UART_BAUD_RATE 9600  // 9600 Baud

//int phone_alarm();
//int uart_init();

/*int uart_putc(unsigned char c)              //Experimentalteil UART 
ANFANG
{
    while(!(USR & (1 << UDRE)));               //UART Bereit? Prüfen von 
UDRE
    UDR = c;                        //Zeichen in Sendepuffer UDR
    return 0;
}

void uart_puts (char *s)                  //Ruft uart_putc auf, bis 
*s=NULL
{
    while (*s)
    {
        uart_putc(*s);
        s++;
    }
}

int uart_init (){

  UBRR = 25;                        //Initialisiert UART mit 9600baud 
bei 2313 mit
4MHz
  UCR |= (1<<TXEN);                    //Transmit enable

  }

int phone_alarm (){

  uart_init();
  fdevopen(uart_putc, NULL, 0);
  printf("%s: Hier AT Befehle einfügen!\n", _FUNCTION_);//Zu
sendender string

  }                            //Experimentalteil UART ENDE*/



phone_alarm wird dabei im main aufgerufen und soll den string auf der
uart ausgeben. zeitkritisch ist das ganze nicht. die c funktionen
verstehe ich soweit, kein problem, aber ich vermute das problem in den
includes o.ä....ich würde ja fast mal versuchen, die ganze routine "zu
deuniversalisieren" aber damit auch einfacher zu machen...

in der code sammlung finde ich nur ellenlange asm beispiele...

Klaus.

von Klaus (Gast)


Lesenswert?

Klaus.

von Klaus (Gast)


Lesenswert?

Hi!

habe mal weiter getestet, erstmal nur ein zeichen zu verschicken:

int uart_init (void){

  UCR |= (1<<TXEN);                    //Transmit enable Bit setzen -> 
UART aktiv
  UBRR = 25;                        //Initialisiert UART mit 9600baud 
bei 2313 mit
4MHz
  }


int phone_alarm (void){

  uart_init();
  while (!(USR & (1<<UDRE)));               /* warten bis Senden 
moeglich
            */
    UDR = 'x';                                 /* schreibt das Zeichen x 
auf
die Schnittstelle */
  if(TXC) cbi(PORTB, 0);
  cbi(USR, TXC);

  }

das klappt auch einwandfrei, TXC wird auch gesetzt, was ja bedeuten
SOLLTE (soweit ich das datenblatt verstehe), dass auf TXD am µC was
passiert...und jetzt ratet mal? genau: nichts...hmmm?!

Gruß, Klaus.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Der Grund für das Aufblähen des erzeugten Binärcodes ist die Verwendung
der Funktion printf(). Wenn das nicht unumgänglich ist, sollte man was
anderes verwenden.

von Klaus (Gast)


Lesenswert?

ich werds nur mit einem pointer und ner zeichenkette erledigen! oder so
:)

Klaus.

von crazy horse (Gast)


Lesenswert?

die Grösse der Hex-Datei ist nicht entscheidend, in etwa kann man 1:3
rechnen. Bei vielen unvollständigen Zeilen kann das Verhältnis aber
noch grösser werden - prinzipiell ist es nicht verboten, für jedes
Datenbyte eine eigene Zeile zu verwenden - das macht dann 1:11 :-)

Der Grund liegt für dein Problem liegt, wie schon gesagt, an printf().
Schöne bequeme Sache, hat aber seinen Preis (Codegrösse). Ich kenne den
Compiler nicht, vielleicht lassen sich ein paar Optionen von printf
abschalten, das kann allerhand bringen.
Aber es gibt keine Notwendigkeit, printf zu benutzen, passt es in den
Speicher - warum nicht. Reicht der Platz nicht abspecken. Man kann es
auch ganz zu Fuss mit putchar() lösen oder ewas komfortabler mit itoa()
o.ä.

von Klaus (Gast)


Lesenswert?

ich wollte auf putchar ausweichen, printf() wird hier im tutorial für
die uart benutzt, sollte man evtl mal drauf hinweisen! so, ich versuchs
erstmal und melde mich dann evtl nochmnals...mit einem zeichen tuts ja
schon, da ist der weg nicht mehr weit.

Gruß & N8, Klaus.

von Klaus (Gast)


Lesenswert?

Hier mal der aktuelle Code, das senden eines strings scheinbt zu
klappen, muss es noch mit einem terminalprogramm testen...

int uart_init (void){

  UCR |= (1<<TXEN);                    //Transmit enable Bit setzen -> 
UART aktiv
  UBRR = 25;                        //Initialisiert UART mit 9600baud 
bei 2313 mit
4MHz
  return 0;
  }


int phone_alarm (char *string){              //phone_alarm übernimmt
string[10]

  uart_init();

  while(*string){                    //Prüft, ob Zeichenkette komplett 
gesendet
    while (!(USR & (1<<UDRE)));             //warten bis Senden moeglich
    UDR = (char)*string;                         //schreibt das Zeichen 
von
*string auf die Schnittstelle
    string++;                      //Pointer + 1 (nächstes Zeichen)
    }

  if(TXC) PORTB ^= 1<<PB0;                //Zu Testzwecken
  cbi(USR, TXC);
  phone=0;                        //Verriegelung damit phone_alarm nur 
einmal aktiv
wird
  return 0;

  }

woher weiß ich, ob der controller nun 8N1 sendet? das wäre wichtig zu
wissen, aber von einer "initialisierung des formats" wird nirgends
gesprochen? oder ist das "standardmäßig gesetzt"?

kann ich davon ausgehen, dass wenn TXC gesetzt ist, das senden
funktioniert hat?

Gruß, Klaus.

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.