- LiTime Speicher und Akkus         
Ergebnis 1 bis 10 von 10

Thema: Signalzustand senden

  1. #1
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    17.08.2005
    Alter
    39
    Beiträge
    685

    Signalzustand senden

    Anzeige

    LiFePo4 Akku selber bauen - Video
    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?

    Code:
    #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++; 
         }
    } 
    
    //-----------------------------------------------------

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    52
    Beiträge
    2.236
    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
    Software is like s e x: its better when its free.
    Linus Torvald

  3. #3
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    17.08.2005
    Alter
    39
    Beiträge
    685
    Vielen Dank, nun funktioniert es

  4. #4
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    17.08.2005
    Alter
    39
    Beiträge
    685
    Nach langer Suche (nun weiß man nach was man suchen musste - ist viel dazu im Forum schon gewesen ) eine weitere Frage:

    verkürzter Code:
    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:
    Code:
    string_senden (puffer[5]);
    Da kommt nur Mist heraus

    Gruß
    Stefan

  5. #5
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    52
    Beiträge
    2.236
    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
    Software is like s e x: its better when its free.
    Linus Torvald

  6. #6
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    17.08.2005
    Alter
    39
    Beiträge
    685
    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:

    Code:
    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:
    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
    Code:
    #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).

  7. #7
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    52
    Beiträge
    2.236
    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:
    Code:
    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:
    Code:
    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.....
    Software is like s e x: its better when its free.
    Linus Torvald

  8. #8
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    17.08.2005
    Alter
    39
    Beiträge
    685
    Vielen Dank izaseba, dass hat mir sehr geholfen.

    Habe nun string_senden und zeichen_senden. Das passt sehr gut.
    Code:
    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


    Werde mich nun wieder in die Tutorials vergraben

    Gruß
    Stefan

  9. #9
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    52
    Beiträge
    2.236
    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...
    Software is like s e x: its better when its free.
    Linus Torvald

  10. #10
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    17.08.2005
    Alter
    39
    Beiträge
    685
    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.

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

LiTime Speicher und Akkus