Forum: Compiler & IDEs [Atmega32]UART sendet nicht


von Markus F. (pippo)


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:
1
#define BAUD_RATE 9600UL    //Baud Rate für die serielle Schnittstelle
2
#define SYSCLK 8000000
3
#define UBRR_BAUD   ((SYSCLK/(16UL*BAUD_RATE))-1)
4
#define USR UCSRA
5
#define UCR UCSRB
6
//#define UBRR UBRRL
7
...
8
9
#include <avr/io.h>
10
#include <stdint.h>
11
#include <stdio.h>
12
#include <ctype.h>
13
#include <stdlib.h>
14
#include <stdbool.h>
15
16
int main() {
17
18
  char pdu[PDU_MAX];
19
20
  DDRA = (1 << DDB0);
21
  DDRB = (1 << DDB0) | (1 << DDB1);
22
23
24
  encoding_pdu(pdu, "HANDYNUMMER", "test-sms 123");
25
  send_sms(pdu);
26
27
28
  while(1) {
29
;
30
  }
31
32
  return 0;
33
}
34
35
36
void send_sms(char *pdu) {
37
38
  uint8_t bytes=0;
39
40
  //PORTA|=(1<<PA0);  //Ausgangspin setzen
41
42
  for(; *pdu!='\0'; pdu++, bytes++) ;  //Länge des PDU-Strings ohne SMSC bestimmen
43
  bytes-=pdu[0];
44
45
  initialize_handy();
46
47
  uart_puts("AT+CVIB=0");
48
49
  uart_puts("AT+CMGF=0");
50
51
  uart_puts("AT+CMGS=");
52
53
  uart_putc(bytes);
54
55
  uart_puts(pdu);
56
57
  uart_putc(0x1a);
58
59
}
60
61
void initialize_handy(void) {
62
63
UBRRH=0;
64
UBRRL=51;
65
//8N1 Daten
66
UCSRC|=0x86;
67
//Empfangen und Senden
68
UCSRB=0x18;
69
70
//Baudrate einstellen (Normaler Modus)
71
    UBRRH = (uint8_t) (UBRR_BAUD>>8);
72
    UBRRL = (uint8_t) (UBRR_BAUD & 0x0ff);
73
74
    // Aktivieren von receiver und transmitter
75
    UCSRB = (1<<RXEN)|(1<<TXEN);
76
77
    // Einstellen des Datenformats: 8 Datenbits, 1 Stoppbit
78
    UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
79
80
}
81
82
83
void uart_puts(char *string){
84
85
uint8_t i=0;
86
  
87
  while (*string){ //solange bis ´\0´ das Ende markiert
88
     
89
        while(!(USR & (1 << UDRE))) //warten, bis UDR bereit ist
90
   // while ( !( UCSRA & (1<<UDRE)) );
91
//   while(bit_is_clear(UCSRA,UDRE)); //warten auf Datenregister empty
92
93
      UDR = *string;
94
      string++;
95
    i++;
96
    if(i==10000) fault();
97
    }
98
}
99
100
101
void uart_putc(char c){
102
103
  while(!(USR & (1<<UDRE)));
104
//  while ( !( UCSRA & (1<<UDRE)) );
105
//while(bit_is_clear(UCSRA,UDRE)); //warten auf Datenregister empty
106
107
  UDR = c;
108
}


Vielen Dank

von Stefan B. (stefan) Benutzerseite


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.

von rüdiger (Gast)


Lesenswert?

PRR ... POWER REDUCTION REGISTER  beachten !  siehe datasheet !

von Markus F. (pippo)


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

von Stefan B. (stefan) Benutzerseite


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;

von Markus F. (pippo)


Lesenswert?

@ rüdiger

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

von Markus F. (pippo)


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.

von Simon K. (simon) Benutzerseite


Lesenswert?

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

von Markus F. (pippo)


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???

von Falk B. (falk)


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_Checkliste#UART.2FUSART

von Markus F. (pippo)


Angehängte Dateien:

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

von Johannes M. (johnny-m)


Lesenswert?


von Stefan B. (stefan) Benutzerseite


Lesenswert?

Quellcode?

Ist http://www.mikrocontroller.net/articles/AVR_Checkliste#UART.2FUSART 
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?

von Karl H. (kbuchegg)


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.

von Karl H. (kbuchegg)


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 :-)
1
void uart_puts(char *string)
2
{
3
  uint16_t i=0;
4
  
5
  while (*string) { //solange bis ´\0´ das Ende markiert
6
    uart_putc( *string );
7
    string++;
8
    i++;
9
    if( i == 10000 )
10
      fault();
11
  }
12
}

von Michael Wilhelm (Gast)


Lesenswert?

In dem Scope ist i doch 16 bit breit.

MW

von holger (Gast)


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.

von Karl H. (kbuchegg)


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.

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.