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
intmain(){
17
18
charpdu[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
return0;
33
}
34
35
36
voidsend_sms(char*pdu){
37
38
uint8_tbytes=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
voidinitialize_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
voiduart_puts(char*string){
84
85
uint8_ti=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
voiduart_putc(charc){
102
103
while(!(USR&(1<<UDRE)));
104
// while ( !( UCSRA & (1<<UDRE)) );
105
//while(bit_is_clear(UCSRA,UDRE)); //warten auf Datenregister empty
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.
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
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;
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.
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???
@ 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
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
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?
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.
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
voiduart_puts(char*string)
2
{
3
uint16_ti=0;
4
5
while(*string){//solange bis ´\0´ das Ende markiert
>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.