- 12V Akku mit 280 Ah bauen         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 18

Thema: Einstieg in C für µC

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    10.04.2006
    Beiträge
    125

    Einstieg in C für µC

    Anzeige

    Praxistest und DIY Projekte
    Hey,

    ich beschäftige mich jetzt schon seit einem viertel jahr mit AVRs, erst mit Assembler und dann mit Bascom.

    Jetzt würde ich aber gern mal den einstieg in C wagen.

    Zu meinen C Kenntnissen, ich bekomme eine einfache konsolen Anwendung zum laufen. Also ich sag mal die untersten Grundkenntnisse müsste ich soweit haben.

    hab mich auch schon im Internet um geschaut nach Tutorials dazu aber irgendwie steig ich da nicht durch.

    Wenn ich jetzt eine ganze Einfache LED Blinkschaltung Programmieren will wie müsste da die Software ausschauen?

    Mein Problem dabei wäre jetzt nicht die Ports anzusprechen sondern das mit dem warten.

    Bei Bascom hat das der Compiler für mich erledigt. Einfach nur WaitMs 500 und gut war!

    Bei ASM hochzählen lassen.

    Wie löse ich das bei C? Wie bei ASM?
    Oder gibt es da eine schönere Lösung?

    Ich hoffe ihr versteht mein Problem, was kann ich da machen das ich da besser in C rein komme?

    Edit:
    Wie löse ich das Problem das er mir bei meiner main Funktion das Programm bei Return 0; bedendet?

    Hab das jetzt folgendermaßen gelöst, finde diese Lösung aber nicht schön!!
    Code:
    int main()
    {
    for(endlos = 1; endlos <= 2; endlos = endlos + 1)
    {
          ...
          ...
           endlos = endlos - 1;
    }
    return 0;
    }

  2. #2
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    12.11.2004
    Ort
    Hvalstad, Norwegen
    Beiträge
    140
    1. Möglichkeit:
    For-Schleife die nichts tut ausser hoch zählen (entspricht in etwa wait)
    2. Möglichkeit:
    EinenZähler starten, warten bis der überläuft oder einen bestimmten Wert erreicht (sog. Polling)
    3. Möglichkeit:
    Einen Zähler starten ebenfalls warten bis der überläuft oder einen bestimmten Wert erreicht und dabei einen Interupt auslöst und auf den mit einer Interupt-Routine reagieren

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    30.01.2006
    Ort
    Irgendwo im Nirgendwo
    Alter
    50
    Beiträge
    62
    Mojn,

    es gibt doch unter "\WinAVR\avr\include\util\" eine Headerdatei mit dem Namen "delay.h" - schau dir die mal an. Die musst du nur includen und dann solltest du die gewünschten Funktionen haben.

    Die Sache mit der Main machst du folgendermaßen:
    Code:
    int main(void) 
    { 
    
       // hier führst du Sachen aus, die nur einmal beim Start gemacht werden
       // müssen (z.B. Timer, Watchdog oder ADC initialisieren)
    
       for (;;) 
       {  
           // hier kommt dein Programmcode rein, der ständig durchlaufen
           // werden soll (hier und normalerweise nur hier sollte der Trigger
           // für den Watchdog rein)
        }
        
       return 0; 
    }

  4. #4
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    10.04.2006
    Beiträge
    125
    Danke, werde ich mir mal anschauen! =)

    So habe folgendes Problem, habe ein Lauflich Programmiert.
    folgende Fehler treten auf:
    Ich hab für meine verschiedenen LEDs Arrays verwendet und wenn die for-Schleife das Array 7 werden LED 4-8 angeschaltet und nicht LED 8 alleine wie es sein sollte, wenn ich, dann aber nur bis Array 6 laufen lasse funktioniert das ohne Probleme! Wo ist mein Fehler? Ich find den einfach nicht.

    Dann ein weiteres Problem, die folgende for-Schleife. Die wird immer übersprungen, und ich hab auch keine Ahnung wieso! Was mache ich da falsch, die ist doch wie jede andere for-Schleife auch! Oder übersehe ich da mal wieder was?



    Code:
    #include <avr/io.h>
    
    uint8_t led[7];
    uint8_t zaehler;
    uint8_t zaehler2;
    uint8_t endlos;
    uint8_t wait0;
    uint8_t wait1;
    uint8_t wait2;
    
    
    
    
    void warte()
    {
    	for(wait0 = 0; wait0 <= 254; wait0 = wait0 + 1)
    	{
    		for (wait1 = 0; wait1 <= 254; wait1 = wait1 + 1)
    		{
    			for(wait2 = 0; wait2 <= 5; wait2 = wait2 + 1)
    			{
    			}
    		}
    	}
    }
    
    int main()
    {
    	//Array Felder konfigurieren
    	led[0] = 0b11111110; 
    	led[1] = 0b11111101;
    	led[2] = 0b11111011;
    	led[3] = 0b11110111;
    	led[4] = 0b11101111;
    	led[5] = 0b11011111;
    	led[6] = 0b10111111;
    	led[7] = 0b01111111;
    
    	DDRB = 0xFF;		//PORTB als Ausgang
    	PORTB = 0xFF;
    	
    	for(endlos = 1; endlos <= 2; endlos = endlos + 1)
    	{
    		PORTB = 0xFF;
    		for(zaehler = 0; zaehler <= 6; zaehler = zaehler + 1)
    		{
    			PORTB = led[zaehler];
    			
    		
    		}
    		
    		for(zaehler2 = 6; zaehler2 ==1; zaehler2 = zaehler2 - 1)
    		{
    			PORTB = led[zaehler2];
    			warte();
    		}
    		
    		endlos = endlos - 1;
    	}
    
    	return 0;
    }

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    30.01.2006
    Ort
    Irgendwo im Nirgendwo
    Alter
    50
    Beiträge
    62
    1. Du musst oben in der Deklaration "uint8_t led[8];" statt "uint8_t led[7];" schreiben, da du 8 Speicherstellen haben willst und nicht 7! Gezählt wird dann nachher von 0 bis 7 - das ist richtig. In deinem Fall greifst du nun einfach auf eine Speicherstelle zu, die nicht mehr zu deinen Variabeln gehört...

    2. Die For-Schleife:
    Du testest auf "zaehler2 ==1". Mach da mal "zaehler2 >=1" - dann sollte es klappen!

    EDIT: Stell deine Main-For-Schleife mal um, so wie ich es dir gesagt hab. Das tut ja weh an den Augen mit dem komischen endlos-Zähler! *LOL*

    EDIT2: "zaehler = zaehler + 1;" macht man in C aber so: "zaehler++;" oder je nach Anwendungsfall "++zaehler;"

  6. #6
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    10.04.2006
    Beiträge
    125
    So... dieses Problem wäre jetzt auch gelöst...

    Man ich könnte mir gerade in den Hinternbeisen. Aber manchmal steht man nun mal auf der Leitung =)

    Vielen dank!! =)

    Ach zu meiner "endlosscheleife" mittel zum zweck, hat ja seinen zweck erfüllt

    Aber deine Lösung dazu ist natürlich schöner und hab ich jetzt auch gleich geändert. Du hattest vorhin gerade gepostet als ich beim Post schreiben war

    So jetzt werde ich mich mal an das delay machen...

  7. #7
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    10.04.2006
    Beiträge
    125
    So... nun ist mal wieder eine Frage beim Thema delay aufgetaucht.

    Und zwar habe ich mich natürlich im lib Manual von WinAVR informiert und das delay auch gleich eingebunden

    Code:
    #include <avr/io.h>
    #ifndef F_CPU
    #define F_CPU 8000000 //8MHz
    #endif
    #include <util/delay.h>
    Dann statt meiner Warte funktion das delay eingebaut:

    Code:
    	for(zaehler = 0; zaehler <= 7; zaehler = zaehler + 1)
    		{
    			PORTD = led[zaehler];
    			_delay_ms(250);
    		}
    Das ganze dann auf den Controller geladen, ich bekomm auch ein delay nur nicht das gewünschte würde ich behaupten, so wie ich das bei dem tutorial bei Mikrocontroller.net herraus interpretiert habe steht die zahl in Klammern für die Zeit(ms)

    Beispiel von denen: _delay_ms(100) // 100 ms

    Vielleicht könnte mir das mal einer erklären am besten mit Beispiel Code! =)

  8. #8
    Benutzer Stammmitglied
    Registriert seit
    30.01.2006
    Ort
    Irgendwo im Nirgendwo
    Alter
    50
    Beiträge
    62
    Hi!

    Versuch es mal mit "#include <USRLIB/delay.h>" statt mit #include <util/delay.h> - hab gesehen, dass ich die immer benutze. Den Unterschied hab ich mir nicht angesehen. Aber sollte sonst so klappen...

    EDIT: Hab gerade das hier in der "util/delay.h" gefunden:
    The maximal possible delay is 262.14 ms / F_CPU in MHz.
    Das heißt für dich, dass du nur 262.14 / 8 Millisekunden (also 32,7675ms) Verzögerung hattest...

  9. #9
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    10.04.2006
    Beiträge
    125
    Hab das gleich mal ausprobiert, aber irgendwie kennt der die include nicht!!

    Was kann ich da machen?

    ich hab auch meinen Kompletten PC durchsucht nach dieser datei. Kein Erfolg!

  10. #10
    Benutzer Stammmitglied
    Registriert seit
    30.01.2006
    Ort
    Irgendwo im Nirgendwo
    Alter
    50
    Beiträge
    62
    Oooops - I'm sorry! Die hatte ich wo anders gefunden - in dem Source für einen 1wire-Sensor. Ich denke mal, dass man die hier posten darf:

    delay.h
    Code:
    #ifndef _delay_h_
    #define _delay_h_
    
    #include <inttypes.h>
    #include <avr/io.h>
    
    /* delay function for microsec
       4 cpu cycles per loop + 1 cycles(?) overhead 
       when a constant is passed. */
    static inline void delayloop16(uint16_t count)
    {
    	asm volatile (  "cp  %A0,__zero_reg__ \n\t"  \
                         "cpc %B0,__zero_reg__ \n\t"  \
                         "breq L_Exit_%=       \n\t"  \
                         "L_LOOP_%=:           \n\t"  \
                         "sbiw %0,1            \n\t"  \
                         "brne L_LOOP_%=       \n\t"  \
                         "L_Exit_%=:           \n\t"  \
                         : "=w" (count)
    					 : "0"  (count)
                       );                            
    }
    // delayloop16(x) eats 4 cycles per x
    #define DELAY_US_CONV(us) ((uint16_t)(((((us)*1000L)/(1000000000/F_OSC))-1)/4))
    #define delay_us(us)	  delayloop16(DELAY_US_CONV(us))
    
    /* delay function for millisec
      (6 cycles per x + 20(?) overhead) */
    void delayloop32( uint32_t l); // not inline
    #define DELAY_MS_CONV(ms) ( (uint32_t) (ms*(F_OSC/6000L)) ) 
    #define delay_ms(ms)  delayloop32(DELAY_MS_CONV(ms))
    
    /* mth 9/04:
       Remark uSeconds:
       Main Oscillator Clock given by F_OSC (makefile) in Hz
       one CPU-Cycle takes 1/F_OSC seconds => 1000000/F_OSC uSeconds
       so: 1 uSecond takes F_OSC/1000000 CPU-Cyles. The following code
       is inspired by the avr-libc delay_loop2 function.
       This it not "that precise" since it takes at least 4 cycles
       but should be o.k. with any parameter (even 0).
       Call function with delayloop(DELAYUS(dt [in uSeconds])).
    */ 
    
    #endif
    delay.c
    Code:
    /* 
       Precise Delay Functions 
       V 0.5, Martin Thomas, 9/2004
       
       In the original Code from Peter Dannegger a timer-interrupt
       driven "timebase" has been used for precise One-Wire-Delays.
       My loop-approach is less elegant but may be more usable 
       as library-function. Since it's not "timer-dependent"
       See also delay.h.
       
       Inspired by the avr-libc's loop-code
    */
    
    #include <avr/io.h>
    #include <avr/io.h>
    #include <inttypes.h>
    
    #include "delay.h"
    
    void delayloop32(uint32_t loops) 
    {
      __asm__ volatile ( "cp  %A0,__zero_reg__ \n\t"  \
                         "cpc %B0,__zero_reg__ \n\t"  \
                         "cpc %C0,__zero_reg__ \n\t"  \
                         "cpc %D0,__zero_reg__ \n\t"  \
                         "breq L_Exit_%=       \n\t"  \
                         "L_LOOP_%=:           \n\t"  \
                         "subi %A0,1           \n\t"  \
                         "sbci %B0,0           \n\t"  \
                         "sbci %C0,0           \n\t"  \
                         "sbci %D0,0           \n\t"  \
                         "brne L_LOOP_%=            \n\t"  \
                         "L_Exit_%=:           \n\t"  \
                         : "=w" (loops)              \
    					 : "0"  (loops)              \
                       );                             \
        
    	return;
    }

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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

12V Akku bauen