www.mikrocontroller.net

Forum: Compiler & IDEs [Atmega32]UART sendet nicht


Autor: Markus F. (pippo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo erstmal! Ich hab mich jetz ewig hier im Forum und in Tutorials 
umgesehen, aber ich find meinen Fehler nicht. Dachte zuerst immer ich 
empfange nichts, weil vielleicht der Max3232 defekt ist, aber mit einem 
Oszi konnte ich mich überzeugen, dass der Uart garnicht sendet. 
Folgenden Code hab ich an den Atmega geschickt, ansonsten nur noch das 
Fusebit für den externen Quarz aktiviert.
Das Programm jetzt erstmal ein Handy ansteuern.

Vielleicht fällt hier ja jemandem was auf:
#define BAUD_RATE 9600UL    //Baud Rate für die serielle Schnittstelle
#define SYSCLK 8000000
#define UBRR_BAUD   ((SYSCLK/(16UL*BAUD_RATE))-1)
#define USR UCSRA
#define UCR UCSRB
//#define UBRR UBRRL
...

#include <avr/io.h>
#include <stdint.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdbool.h>

int main() {

  char pdu[PDU_MAX];

  DDRA = (1 << DDB0);
  DDRB = (1 << DDB0) | (1 << DDB1);


  encoding_pdu(pdu, "HANDYNUMMER", "test-sms 123");
  send_sms(pdu);


  while(1) {
;
  }

  return 0;
}


void send_sms(char *pdu) {

  uint8_t bytes=0;

  //PORTA|=(1<<PA0);  //Ausgangspin setzen

  for(; *pdu!='\0'; pdu++, bytes++) ;  //Länge des PDU-Strings ohne SMSC bestimmen
  bytes-=pdu[0];

  initialize_handy();

  uart_puts("AT+CVIB=0");

  uart_puts("AT+CMGF=0");

  uart_puts("AT+CMGS=");

  uart_putc(bytes);

  uart_puts(pdu);

  uart_putc(0x1a);

}

void initialize_handy(void) {

UBRRH=0;
UBRRL=51;
//8N1 Daten
UCSRC|=0x86;
//Empfangen und Senden
UCSRB=0x18;

//Baudrate einstellen (Normaler Modus)
    UBRRH = (uint8_t) (UBRR_BAUD>>8);
    UBRRL = (uint8_t) (UBRR_BAUD & 0x0ff);

    // Aktivieren von receiver und transmitter
    UCSRB = (1<<RXEN)|(1<<TXEN);

    // Einstellen des Datenformats: 8 Datenbits, 1 Stoppbit
    UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);

}


void uart_puts(char *string){

uint8_t i=0;
  
  while (*string){ //solange bis ´\0´ das Ende markiert
     
        while(!(USR & (1 << UDRE))) //warten, bis UDR bereit ist
   // while ( !( UCSRA & (1<<UDRE)) );
//   while(bit_is_clear(UCSRA,UDRE)); //warten auf Datenregister empty

      UDR = *string;
      string++;
    i++;
    if(i==10000) fault();
    }
}


void uart_putc(char c){

  while(!(USR & (1<<UDRE)));
//  while ( !( UCSRA & (1<<UDRE)) );
//while(bit_is_clear(UCSRA,UDRE)); //warten auf Datenregister empty

  UDR = c;
}


Vielen Dank

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Räume in diesem Gemetzel mal auf:

        while(!(USR & (1 << UDRE))) //warten, bis UDR bereit ist
   // while ( !( UCSRA & (1<<UDRE)) );
//   while(bit_is_clear(UCSRA,UDRE)); //warten auf Datenregister empty

      UDR = *string;

Und du wirst sehen, dass der Code nicht der Logik des Sendecodes im 
AVR-GCC-Tutorial entspricht. Tipp: Es fehlt ein entscheidendes ;

ADD 1: Brauchen die Strings an das Handy kein Zeilenendezeichen \n oder 
\r? Kenne mich da nicht aus. Datenblatt/Manual/Tutorial solcher 
Handy-Kommunikation wäre hilfreich.

ADD 2: UCSRA war richtig. Datenblatt Seite 147

ADD 3: Vergiss ADD 2, du hast dir ja USR definiert.

Autor: rüdiger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
PRR ... POWER REDUCTION REGISTER  beachten !  siehe datasheet !

Autor: Markus F. (pippo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke schonmal, ich wüsst aber nicht auf welches ; zu anspielst. Der 
Compiler meldet mir keinen Fehler. Das ganze mach ich mit AVR-Studio 4 
und dem GCC-Compiler.

Was die Ansteuerung des Handys anbelangt, so ist das für mich erstmal 
nebensächlich. Damit will ich mich erst rumschlagen, wenn aus dem USART 
mal paar 1en und 0en rauskommen :)

Das Gemetzel ist deshalb noch drin, weil ich etwas rumprobiert habe und 
zeigen wollte, womit es ebenfalls nicht funktioniert hat

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Markus F. wrote:
> Danke schonmal, ich wüsst aber nicht auf welches ; zu anspielst. Der
> Compiler meldet mir keinen Fehler. Das ganze mach ich mit AVR-Studio 4
> und dem GCC-Compiler.

Durch die Kommentare etc. bist du worres. Das:

        while(!(USR & (1 << UDRE))) //warten, bis UDR bereit ist
   // while ( !( UCSRA & (1<<UDRE)) );
//   while(bit_is_clear(UCSRA,UDRE)); //warten auf Datenregister empty

      UDR = *string;

ist identisch zu dem:

        while(!(USR & (1 << UDRE)))
            UDR = *string;

Also du lässt den Atmega32 senden, wenn die UART nicht bereit ist. Dem 
Compiler ist das egal, es ist ja legales C. Nur nicht sinnvoll bzgl. 
UART.

Sinnvoll wäre:

        while(!(USR & (1 << UDRE)))
            ;
        UDR = *string;

Autor: Markus F. (pippo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ rüdiger

Wür schön, wenns so einfach wär, aber Atmega32 hat kein PRR

Autor: Markus F. (pippo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan, du bist a Hund. Des wär mir garnet aufgefallen. Hab den Code 
einfach dumm aus nem Tut rauskopiert. Dann werd ich mal schaun, dass 
ichs heut Abend testen kann.

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Übrigens heißt "Handy" nicht "Handy" auf englisch/amerikanisch, sondern 
"cellphone" oder "mobile".

Autor: Markus F. (pippo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich weiß :) es heisst mobile phone :D

Es war übrigens nicht der Fehler, nach wie vor kommt aus dem USART 
nichts raus. Könnte hier ein Hardwaredefekt vorliegen?

Wenn ich im AVR-Studio similiere, so wird der USART richtig siumuliert. 
Kann man da vielleicht auch noch den USART selbst simulieren und seien 
es nur Pegeländerungen???

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Markus F. (pippo)

>Wenn ich im AVR-Studio similiere, so wird der USART richtig siumuliert.
>Kann man da vielleicht auch noch den USART selbst simulieren und seien
>es nur Pegeländerungen???

Vergiss die Simulation, die reale Hardware muss laufen.

http://www.mikrocontroller.net/articles/AVR_Checkl...

Autor: Markus F. (pippo)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Der uC sendet leider immer noch nicht. Hab mir jetzt mal ne 2. Platine 
gemacht, vielleicht sieht ja jemand nen Fehler. Hab auch wieder den 
obigen Code verwendet

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Quellcode?

Ist http://www.mikrocontroller.net/articles/AVR_Checkl... 
abgearbeitet und was ist rausgekommen?

Kann der AVR mit dem PC kommunizieren?

Kann das Handy (Welcher Hersteller? Welches Modell?) mit dem PC 
kommunizieren?

Kommt das Handy einfachem 3-Wire RS232 ohne Hardware-Handshake zurecht?

RXD und TXD Leitung vom Handy sind identifiziert? Per Schaltplan oder 
nachgemessen?

Liefert Handy an seiner Schnittstelle bereits RS232-konforme Pegel oder 
sind TTL-Pegel vorhanden und im "Datenkabel" ist ein Pegelwandler? 
Richtiges Datenkabel vorhanden?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dass deine seriellen Leitung noch durch die Gatter-Geschichte mit den 
UND-Gattern und dementsprechend PB0 bzw. PB1 mit beeinflusst werden, ist 
dir aber schon aufgefallen?

Ich seh nur in deinem Code nicht, wo du PB0 oder PB1 mal auf 1 setzen 
würdest. Solange alle beide auf 0 sind, kann dein µC über TxD senden bis 
er schwarz wird, die Gatter lassen nichts durch.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan B. wrote:

> Sinnvoll wäre:
>
>         while(!(USR & (1 << UDRE)))
>             ;
>         UDR = *string;

Sinnvoll wäre gewesen die uart_putc Funktion wiederzuverwenden :-)
(und sich zu überlegen, ob eine uint8_t Variable überhaupt bis 10000 
hoch zählen kann :-)
void uart_puts(char *string)
{
  uint16_t i=0;
  
  while (*string) { //solange bis ´\0´ das Ende markiert
    uart_putc( *string );
    string++;
    i++;
    if( i == 10000 )
      fault();
  }
}

Autor: Michael Wilhelm (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In dem Scope ist i doch 16 bit breit.

MW

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Der uC sendet leider immer noch nicht. Hab mir jetzt mal ne 2. Platine
>gemacht, vielleicht sieht ja jemand nen Fehler. Hab auch wieder den
>obigen Code verwendet

Hat mit dem senden zwar nix zu tun, aber auch
das empfangen dürfte schwer werden wenn die
Ausgänge von IC3A und IC3D zusammengeschaltet sind.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael Wilhelm wrote:
> In dem Scope ist i doch 16 bit breit.
>
> MW

Ja, jetzt.
Weil ich den uint8_t durch einen uint16_t ausgetauscht habe.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.