hallo,
ich hab da ein problemchen, und zwar giebt mein uart erst mist aus, dann
aber stimmts, also muss es am code liegen. Ich und mein c- mentor finden
aber keinen, vielleicht kann mir ja einer von euch spezialisten helfen.
Ich probiere ein steuerzeichen zu senden, die Schnittstelle giebt aber
nur [ACK][ACK], also [$06] [$06],aus.
als IDE benutze ich VMLAB, gut zum simulieren.
Das ganze soll einfach einen string an ein TP EA eDIP240 senden
clock und baudrate stimmt
relevanter code (nicht komplett):
1
2
#include<avr\io.h>
3
#include<stdlib.h>
4
#include<math.h> // Most basic include files Add the necessary ones
5
#include<avr\signal.h>
6
#include<String.h> // here
7
#include"uart1.h"
8
9
#ifndef F_CPU
10
#define F_CPU 4000000UL
11
#endif
12
13
/* 9600 baud */
14
#define BAUDRATE 9600UL //Definition als unsigned long, sonst gibt es Fehler in der Berechnung
holger hat schon einen Fehler.
Hier ist der nächste
1
voiduart_puts(constchar*s)
2
{
3
do
4
{
5
uart_putc(*s);
6
}
7
while(*s++);
8
}
anders rum
1
voiduart_puts(constchar*s)
2
{
3
while(*s)
4
{
5
uart_putc(*s++);
6
}
7
}
und das nächste Problem
1
voidpunkt_machen(intx,inty)
2
{
3
chartext[3];
4
uart_puts(0x11);
5
uart_puts("2");
6
uart_puts("#gp");
7
itoa(x,text,10);
das nenn ich mutig, davon auszugehen, dass die Textrepräsentierung von
sowohl x als auch y einen maximalen String mit 2 Zeichen ergibt. Vor
allen Dingen da hier
xcord += 119 ;
die berechnete x Koordinate für positive xcord schon mal kräftig
angehoben wird.
Du solltest deinen C-Mentor wechseln, wenn er solche Sachen nicht sieht.
vielen danke für die korekturen, display und uc verstehen sich jetzt,
mehr oder weniger.
zu diesm part:
1
voiduart_puts(constchar*s)
2
{
3
do
4
{
5
uart_putc(*s);
6
}
7
while(*s++);
8
}
ich verstehe den fehler nicht ganz, das ist doch eine do-schleife, die
das gleich macht wie ne while-schleife ausser das sie min. einmal
durchläuft, insofern sinnvoll da eigntlich wenn die funktion aufgerufen
wird i.d.R. auch etwas gesendet werden will.
zu dem part:
1
voidpunkt_machen(intx,inty)
2
{
3
chartext[3];
4
uart_puts(0x11);// neu: uart_putc(0x11)
5
uart_puts("2");
6
uart_puts("#gp");
7
itoa(x,text,10);
mmh.. ein berechtigter einwand...
aber irgendwo hab ich glelesen das C ja keine strings kennt, sondern nur
char-arrays, sprich die variabel text[3] ist nicht null terminiert, also
effektiv drei zeichen lang.
Wassmer Marco schrieb:
> ich verstehe den fehler nicht ganz, das ist doch eine do-schleife, die> das gleich macht wie ne while-schleife ausser das sie min. einmal> durchläuft, insofern sinnvoll da eigntlich wenn die funktion aufgerufen> wird i.d.R. auch etwas gesendet werden will.
"i.d.R." ist aber nicht das gleiche wie "garantiert immer". Was ist,
wenn die Funktion doch mal mit einem leeren String aufgerufen wird?
Möchtest du, dass dann eine Null gesendet wird?
> mmh.. ein berechtigter einwand...> aber irgendwo hab ich glelesen das C ja keine strings kennt, sondern nur> char-arrays, sprich die variabel text[3] ist nicht null terminiert, also> effektiv drei zeichen lang.
Die Variable text ist natürlich nicht "von Natur aus" null-terminiert.
Aber itoa erzeugt eine Null-Terminierung (ansonsten würde ja auch das
folgende "uart_puts (text)" gar nicht funktionieren), also muss in text
auch Platz für diese Terminierung sein.
Eine C-Zeichenkette (Beispiel "test") ist immer nullterminiert,
benötigt also immer 5 Bytes.
Wenn s also ein Zeiger auf dieses "test" ist, passiert folgendes:
1. uart_putc (*s)
*s dereferenziert den Zeiger und ergibt das Byte 't'. Dieses wird
ausgegeben.
2. while (*s++);
Die Schleife wird ab "do" wiederholt, wenn das Zeichen an *s (also
das 't') nicht 0 ist. Nach diesem Vergleich und vor dem Sprung nach "do"
wird s noch um eine Speicherposition erhöt.
3. uart_putc (*s)
Jetzt wird das 'e' gesendet.
4. ....
5. while (*s++);
Es wird auf 't' (das letzte in "test") geprüft. Es ist wieder nicht
null, also weiter bei "do".
6. uart_putc (*s);
Jetzt kommt das Problem. s zeigt jetzt auf das Byte nach "test", und
zwar auf die Nullterminierung. Diese Null wird gesendet.
7. while (*s++);
Jetzt trifft die Bedingung "Zeichen an Zeigerposition s nicht null"
nicht mehr zu, die Schleife ist beendet.
holger schrieb:
>>text[3] also effektiv drei zeichen lang.>> Nö, zwei Zeichen mit /0 am Ende.> Für drei Zeichen brauchst du text[4].
@Marco
Wobei es an solchen Stellen praktisch IMMER kontraproduktiv ist, zu
knausrig zu sein. Irgendwann wird deine Zahl nämlich größer und sei es
nur weil beim testen nicht alles auf Anhieb funktioniert.
Wenn du das Array in dieser Funktion größer machst, dann kostet dir das
praktisch nichts, kann dich aber zumindest am Anfang vor seltsamen
Problemen bewahren. Ein int kann per Definition auf deinem µC von -32768
bis 32767 gehen. Das macht maximal 6 Zeichen, dazu noch die obligate
'\0'-Terminierung macht 7 Positionen. Darauf würde ich das auslegen
(oder der Einfachheit halber gleich mal 10 nehmen)
>Darauf würde ich das auslegen (oder der Einfachheit halber gleich mal 10 >nehmen)
FULL ACK!!
"Speichersparen" kann man dann wenn man fertig ist, vorher (wie Karl
heinz schon geschrieben hat) machts speziell für Anfänger nicht viel
Sinn.
mfg
Ber