Archiv verlassen und diese Seite im Standarddesign anzeigen : Signalzustand senden
Hallo,
schlage mich mal wieder mit C herum.
Nun habe ich das Problem, dass die Variable bPortD nicht korrekt gesendet wird.
Kann es daran liegen, dass dies eine int ist und das eine char gesendet wird?
#include <avr/io.h>
#include <stdint.h>
#include <util/delay.h>
#include <inttypes.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
int i;
uint8_t bPortD;
void string_senden (const char *string);
void usart_initial();
int main(void)
{
DDRD |= (1<<4) | (1<<5);
usart_initial();
while(1)
{
bPortD = PIND;
string_senden (bPortD);
string_senden ("\n\r");
if (PIND & (1<<PIND7)){
string_senden ("Taster nicht gedrueckt\r\n");
}
if ( !(PIND & (1<<PIND7))){
string_senden ("Taster gedrueckt\r\n");
}
for (i=0; i<100; i++)
{
_delay_ms(10);
}
}
}
//-----------------------------------------------------
void usart_initial()
{
UBRRH = 0;
UBRRL = 7;
UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
}
//-----------------------------------------------------
void string_senden (const char *string)
{
while (*string)
{
while (!(UCSRA & (1<<UDRE)))
{}
UDR = *string++;
}
}
//-----------------------------------------------------
Ja ist doch klar...
Gibt der Kompiler keine Warnung ?
Deine string_senden Funktion erwartet eine Zeiger auf const char
Du übergibst aber uint8_t oder unsigned char, das ist doch ein Unterschied oder ?
es müßte wirklich eine Warnung kommen...
mach das ganz einfach:
#include <stdlib.h>
irgendwo am Anfang von main
char puffer[5];
vor der ausgabe
itoa (bPortd,puffer,10);
stringsenden(puffer);
ond mach const weg.
Gruß Sebastian
Vielen Dank, nun funktioniert es O:)
Nach langer Suche (nun weiß man nach was man suchen musste - ist viel dazu im Forum schon gewesen 8-[ ) eine weitere Frage:
verkürzter Code:
uint8_t bPortD;
char puffer[8];
.....
bPortD = PIND;
utoa(bPortD,puffer,2);
string_senden(puffer);
das funktioniert einwandfrei.
Da Variable "puffer" ein String (char Array) ist, müsste ich doch einfach wie auf dem PC auf den Inhalt zugreifen können und ausgeben.
Wieso funktioniert das nicht:
string_senden (puffer[5]);
Da kommt nur Mist heraus :-k
Gruß
Stefan
Stefan,
liest Du überhaupt was man Dir schreibt?
Ich zitiere mich nochmal:
Deine string_senden Funktion erwartet eine Zeiger auf const char
Du übergibst aber uint8_t oder unsigned char, das ist doch ein Unterschied oder ?
und ? was ist bitte puffer[5] ?
Was meldet der Kompiler ?
Was möchtest Du erreichen ?
Oder anders gefragt, wenn Du ein uint8_t mit itoa/utoa behandelst, wieviel Platz wird im puffer belegt (mit '\0') und was steht sinnvolles bei puffer[5] ?
Dein String_senden erwartet ja einen Zeiger, also &puffer[5], aber Achtung, es wird solange was ausgegeben bis '\0' kommt ...
Gruß Sebastian
Also gut,
in C bin ich ein Noob und versuche mich hinein zufinden. Denke es klappt so gaanz langsam. Mit Zeiger habe ich mich noch nicht beschäftigt, will hier ja"nur" den Inhalt lesen.
Der Compiler gibt mir nach erfolgreichen compilieren diese 3 Warnungen:
c:17: warning: function declaration isn't a prototype
c: In function `main':
c:41: warning: passing arg 1 of `string_senden' makes pointer from integer without a cast
c: At top level:
c:49: warning: function declaration isn't a prototype
Kompletter Code:
#include <avr/io.h>
#include <string.h>
#include <stdint.h>
#include <util/delay.h>
#include <inttypes.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
int i;
uint8_t bPortd;
char puffer[8];
void string_senden (char *string);
void usart_initial();
int main(void)
{
DDRD |= (1<<2) | (1<<3) | (1<<4) | (1<<6) | (1<<7);
DDRA &= ~( (1<<PA0));
usart_initial();
while(1)
{
PORTD |= (1<<2) | (1<<3) | (1<<4) | (1<<6) | (1<<7);
bPortd = PIND;
utoa(bPortd,puffer,2);
string_senden(puffer);
string_senden ("\n\r");
if (PINA & (1<<PINA0)){
string_senden ("Taster nicht gedrueckt\r\n");
}
if ( !(PINA & (1<<PINA0))){
string_senden ("Taster gedrueckt\r\n");
}
for (i=0; i<100; i++)
{
_delay_ms(10);
}
string_senden (puffer[5]);
string_senden ("\n\r");
}
}
//-----------------------------------------------------
void usart_initial()
{
UBRRH = 0;
UBRRL = 7;
UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
}
//-----------------------------------------------------
void string_senden (char *string)
{
while (*string)
{
while (!(UCSRA & (1<<UDRE)))
{}
UDR = *string++;
}
}
//-----------------------------------------------------
(Benutze AVR Studio)
Ziel:
Bei einem PC-Beispiel
#include <stdio.h>
#include <stdlib.h>
char vari[] = { "Hallo" };
int main(void) {
int i;
printf("%c", vari[0]); /* H */
printf("%c'", vari[3]); /* l */
return EXIT_SUCCESS;
}
Also will ich einen einzelnen Portzustand aus diesem String erhalten.
ZB. mit puffer[5]: PinD5
Falls ich total auf dem Holzweg bin, kann Kritik einstecken. Bin halt noch sehr am Anfang der Programmierung (Mechanik ist mein Lieblingsgebiet).
Ok,
schön, jetzt weiß ich, was Du vor hast...
Ich find es auch gut, daß Du auf dem PC übst, so kommt man schneller ans Ziel, als nur mit dem µC.
Also was Dir fehlt, sind die Grundlagen(warum schreibt niemand einen tut!)
Fehler 1 Puffer ist zu klein!
Wenn Du ein uint8_t in Bits zerlegst, bekommst Du nach itoa/utoa ein Zeichenarray von 9 Bytes länge!
Beispiel
char puffer[] = {'0','0','0' ,'0' ,'0' ,'0' ,'0' ,'0' ,'\0'};
Man beachte dieses '\0' am Ende, damit wird signalisiert, daß der String zuende ist(deswegen 9 Bytes) klaro?
nun Deine sende_string Routine erwartet einen Zeiger auf ein char Array also übergibst Du der routine den Zeiger auf puffer[0].
puffer[0] ist aber kein Zeiger, sondern &puffer[0] wäre ein Zeiger und da sowas sehr oft bei C vorkommt kann man das ganze abkürzen und einfach puffer schreiben, klaro ?
was passiert jetzt in der sendestring Routine:
void string_senden (char *string)
{
while (*string)
{
while (!(UCSRA & (1<<UDRE)))
{}
UDR = *string++;
}
}
while(*string) bedeutet, solange ausführen bis das worauf string zeigt != 0 ist
wichtig ist hier * was bedeutet das worauf string zeigt (in diesem Fall puffer[0])
Dann wird das, worauf string zeigt in UDR geschrieben und Achtung der Zeiger um eins erhöht womit der Zeiger auf puffer[1] springt!
Zum Verständnis
UDR=*string++;
kann man auch
UDR=*string;
string++;
schreiben
Ich hoffe, jetzt wird klar, warum Dein vorhaben nicht funktionieren wird..
klar kannst Du
sende_string(&puffer[5]);
schreiben, was kommt dabei raus ?
Mein Vorschlag sende_string zegschlagen und zwar:
void string_senden (char *string)
{
while (*string)
sende_zeichen(*string++);
}
sende_zeichen(char zeichen){
while (!(UCSRA & (1<<UDRE)));
UDR = zeichen;
}
Damit kannst Du wie gewohnt mit string_senden("Hallo Welt");
Oder mit sende_zeichen(puffer[5]);
ein Zeichen senden, aber jetzt bitte keinen Zeiger!
Ich hoffe, daß Dir das weiterhilft...
Gruß Sebastian
P.S. Die andere Warnung kommt von dem Prototyp mit leeren Klammern schreib da ein void rein und weg ist die Warnung.
Puh.....
Vielen Dank izaseba, dass hat mir sehr geholfen.
Habe nun string_senden und zeichen_senden. Das passt sehr gut.
void string_senden (char *string)
{
while (*string)
{
while (!(UCSRA & (1<<UDRE)))
{}
UDR = *string++;
}
}
void zeichen_senden(char zeichen)
{
while (!(UCSRA & (1<<UDRE)));
UDR = zeichen;
}
Gibt auch keine Fehler oder Warnungen O:)
Werde mich nun wieder in die Tutorials vergraben 8-[
Gruß
Stefan
Es freut mich, daß ich alles nicht umsonst geschrieben habe (es ist nicht gerade einfach etwas in einem Post zu erklären, einfacher ist es am Schreibtisch bei einem Bier)
Spiel das am besten am PC durch, vor allem die Zeiger Geschichte...
Ja.
Vor allem im Forum können sehr schnell Missverständnisse auftreten, man redet aneinander vorbei oder der Wissensstand ist einfach zu unterschiedlich ausgeprägt ...
Was ich noch falsch hatte:
für PIND5 muss ich puffer[2] auslesen,
da puffer mir 11011111 (Ausgabe ist ja logisch) ausgibt, wenn ich PIND5 auf low setze.
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.