Hallo,
Ich bin gerade dabei, aus der Artikelsammlung das "mikrocontroller
verschickt SMS an Siemens-Handy"-Projekt nachzubauen. Hab auch alles
soweit, Handy geht, etc. jetzt schaue ich, dass ich den Code auf einen
ATmega8 abgespeckt bekomme.
Leider geht die printf-Funktion nicht, der µC sendet dabei nix über das
UART raus...Woran kann das liegen? Ich habe im Makefile schon
printf-options auf "minimalistic" eingestellt. Warum geht diese
printf-Variante nicht?
In meiner Hauptroutine steht jetzt zum Test:
1
uart_sends("hallo");//das funktioniert
2
printf("at+cclk?\r\n");//da kommt nix an
3
_delay_ms(2500);
4
sms_send("015781581259","Die Krümmung ist eine Größe der inneren Geometrie");
5
//da kommt auch nix an
Die wichtigsten Code-Schnipsel aus dem Artikel für die SMS-Funktionen
lauten so:
1
voidsms_init(void){
2
// Initialisierung der seriellen Schnittstelle Asynchron
3
uart_init();
4
// öffnet Kanal für printf
5
//stdout = &mystdout;
6
fdevopen(uart_sendc,uart_receive);
7
8
UCSRB&=~(1<<RXCIE);// UART Receive ISR ausstellen
9
10
printf("ATE0\r\n");// Echo off, reduce traffic
11
_delay_ms(200);
12
printf("AT+CPMS=\"ME\",\"MT\",\"MT\"\r\n");// Speicher von gelesenen, geschriebenen und empfangenen SMS auf Telefonspeicher stellen
13
_delay_ms(200);
14
printf("AT+CNMI=1,1,0,0,1\r\n");// new message indication --> "+CMTI:<mem>,<index>"
15
_delay_ms(200);
16
17
// Auslesen der ersten 5 Telefonnummern der SIM-Karte
18
chartelnr[SMS_TELNR_MAX_LEN+1];
19
uint8_ti=0;
20
intdummy;
21
printf("AT+CPBS=\"SM\"\r\n");// Telefonbuch auf SIM Karte umstellen
22
_delay_ms(200);
23
uart_clear();
24
for(i=0;i<SMS_TELNR_LIST_MAX;i++){
25
uart_clear();
26
printf("AT+CPBR=%i\r\n",i+1);
27
gets(telnr);
28
scanf("+CPBR: %i,\"%[^\"]",&dummy,telnr);
29
_delay_ms(400);// Rest der Antwort abwarten und verwerfen
30
if(strlen(telnr)>3){
31
strcpy(sms_telnr_list[i].telnr,telnr);// ausgelesene Telefonnummer in Struktur speichern
32
}
33
else{strcpy(sms_telnr_list[i].telnr,"noNR");}
34
}
35
uart_clear();
36
if(UART_ISR!=0){UCSRB|=(1<<RXCIE);}// UART Receive ISR wieder einstellen
37
}
und
1
voidsms_send(char*zielnr,char*nachricht)
2
{
3
uint8_tcnt_shiftzero=0;
4
uint8_tcnt_nr=0;// Zähler für Zielnummer, nach Umwandlung = Länge der Zielnummer
5
uint8_tcnt_txt=0;// Zähler für Nachricht, nach Umwandlung = Länge der Nachricht
M. G. schrieb:> In meiner Hauptroutine steht jetzt zum Test:> uart_sends("hallo"); //das funktioniert> printf("at+cclk?\r\n"); //da kommt nix an> _delay_ms(2500);> sms_send("015781581259","Die Krümmung ist eine Größe der inneren Geometrie");> //da kommt auch nix an
Kann ´ja auch nicht ohne vorher sms_init aufzurufen.
M. G. schrieb:> Hab auch alles> soweit, Handy geht, etc. jetzt schaue ich, dass ich den Code auf einen> ATmega8 abgespeckt bekomme.
Das geht eher nicht, selbst wenn du alle lcd routinen etc. rausnimmst
wird das kaum passen. Steht auch so im Artikel.
Na, sms_init ist natürlich aufgerufen, und Platz ist auch genug auf dem
µC (siehe unten), ich habe halt in der sms.c alle Funktionen
rausgenommen ausser sms_send und sms_init. Ich will auch nur diese zwei
Sachen erstmal machen!
Also die ganze Hauptroutine in main.c sieht halt so aus:
1
#include"main.h"
2
#include"uart.c"
3
#include"sms.c"
4
5
volatileuint8_ttimer_flag;
6
7
intmain(void){
8
9
DDRD=(1<<PD1)|(1<<PD2);
10
DDRB=0xFF;
11
PORTB=0;
12
13
sei();
14
sms_init();
15
uart_clear();
16
17
uart_sends("hallo");//geht
18
printf("at+cclk?\r\n");//geht nicht
19
20
21
22
23
24
while(1)//Ende
25
{
26
PORTB=(1<<PB0);
27
_delay_ms(250);
28
PORTB=(0<<PB0);
29
_delay_ms(250);
30
}
31
}
Ach ja, und der AVR ist halt bis zum Rand gefüllt:
M. G. schrieb:> #include "uart.c"> #include "sms.c"
Das sollte eher *.h heißen.
Am original Code brauchst du sicher keine Fehler suchen, der
funktioniert so wie er ist. Wurde schon dutzende Male erfolgreich
verwendet. Wahrscheinlicher ist, dass du etwas auskommentiert hast, was
du nicht hättest auskommentieren sollen (wie z.B. die header -Dateien)
M. G. schrieb:> Data: 1009 bytes (98.5% Full)> (.data + .bss + .noinit)
Also praktisch Null Platz für den Stack. Das funktioniert so sicher
nicht. Als erste Maßnahme solltest du mal die ganzen
printf-Formatstrings ins Flash verbannen und entsprechend printf_P
benutzen.
Ah,
das klingt nach der Lösung...
Also du meinst, man definiert für die AT-Commandostrings
Flash-Variablen?
etwa so:
1
charStringImFlash[]PROGMEM="at+cclk?\r\n";// im "Flash"
2
3
printf_P(StringImFlash);
oder etwa sowas wie
1
constcharIchbinimflash[]PROGMEM="%s";
2
3
printf_P(Ichbinimflash);
4
??????
(Kennt jemand eigentlich mal so eine Art Dokumentation zu diesen
merkwürdigen printf-Funktionen? Ich weiß eigentlich gar nicht genau, was
die machen...?!)
M. G. schrieb:> Also du meinst, man definiert für die AT-Commandostrings> Flash-Variablen?> etwa so:
1
charStringImFlash[]PROGMEM="at+cclk?\r\n";// im "Flash"
2
3
printf_P(StringImFlash);
>> oder etwa sowas wie
1
constcharIchbinimflash[]PROGMEM="%s";
2
3
printf_P(Ichbinimflash);
4
??????
Oder einfach so:
1
printf_P(PSTR("at+cclk?\r\n"));
> (Kennt jemand eigentlich mal so eine Art Dokumentation zu diesen> merkwürdigen printf-Funktionen? Ich weiß eigentlich gar nicht genau, was> die machen...?!)http://www.nongnu.org/avr-libc/user-manual/
Was ich mich frage ist: Wozu benötigt man hier überhaupt printf? Nur für
die Formatierte Ausgabe von ein paar Zahlen? Da könnte man durch eine
eigene Routine sicherlich auch noch etwas Platz sparen.
Läubi .. schrieb:> Was ich mich frage ist: Wozu benötigt man hier überhaupt printf? Nur für> die Formatierte Ausgabe von ein paar Zahlen? Da könnte man durch eine> eigene Routine sicherlich auch noch etwas Platz sparen.
Zitat aus Artikel:
"Die einzelnen Algorithmen sind dabei sehr einfach gehalten. Das
bedeutet, dass es sicherlich sehr viel kürzere Varianten gibt, um z. B.
einen Text in das PDU Format zu transformieren. Ich habe mich aber
lieber auf mehr und damit für andere auch verständlicheren Code
beschränkt. Das verbraucht zwar mehr Speicher, trägt aber meines
Erachtens zum Verständnis bei."
Platz sparen war hier nicht der Ansporn, sondern vielmehr das
Verständniß und printf kennt nun mal jeder. Der Anfänger muss siche eben
nicht mit dem UART rumschlagen.
SMS schrieb:> Platz sparen war hier nicht der Ansporn, sondern vielmehr> das Verständniß
Schon klar nur der TE scheint ja
a) Platz sparen zu wollen
b) mit printf auf dem Kriegsfuß zu stehen ;)