[Atmega32]UART sendet nicht

#1087204
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
Persönliche Seite #1087284
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.
#1087308
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
Persönliche Seite #1087322
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;
#1093193
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???
Persönliche Seite #1144166
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?
#1144741
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.
#1144749
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
}
Gast #1144922
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren