[GCC] Timer0 CTC Problem

Kani

Neues Mitglied
07. Jan. 2009
339
0
0
Spenge
Sprachen
[EDIT] Verdammt, wieso kann man den Namen des Themas nicht ändern. Ich war doch noch garnicht fertig. =(

Hallo Leute,
ich habe mal eine Frage:



CodeBox c

#define F_CPU 1000000UL


#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>



int main (void)
{

DDRA = 0b11111111;
PORTA = 0b00000000;

// Timer 0 initialisieren

sei();

TIMSK |= (1<<OCIE0);

OCR0 = 128+1;

TCCR0 |= (1<<WGM01);
TCCR0 &= ~(1<<WGM00);

TCCR0 &= ~(1<<CS02);
TCCR0 |= (1<<CS01);
TCCR0 |= (1<<CS00);






}


ISR (TIMER0_COMP_vect)
{

PORTA = 0b11111111;

_delay_ms(500);

PORTA = 0b00000000;
}


Berechnung:
1000000 / 64 = 15625 / 1000 = 15,625ms
=> Alle 15,625ms zählt TCNT0 + 1.

2000ms / 15,625ms = 128 => Wenn der Zähler auf TCNT0 = 128 steht, sind 2
Sekunden vergangen.

Der Interrupt kommt also alle 2ms. Die LEDs an PORTA schalten an und
alles wird für 0,5s lahm gelegt => bleiben also leuchten. (Ich weiß,
delay() ist nicht schön -> aber schnell ;-) )
Danach wieder aus und das gleiche nach den nächsten Zwei sekunden.

So die Theorie!

Woran kann das liegen, dass es nicht funktioniert?

Liebe Grüße,
Finn
 
Hallo Finn,

in main() fehlt die Endlosschleife.


Code:
int main(void)
{

  // hier Initialisierungen

  while(1)
  {

    // mache was

  }

  return 0;  // wird nie ausgeführt
}
ISR so kurz wie möglich halten. Es ist zwar möglich ein delay zu verwenden, aber dann sind ggf. alle anderen ISRs blockiert. Wenn du schon ein delay verwendest, dann irgendwo in der Endlosschleife innerhalb main(), dann kannst du aber auch die ISR weglassen.

Interrupts global immer erst freigeben, wenn diese initialisiert sind und wenn in deinem Fall der Timer läuft.

(Die Timerinitialisierung habe ich jetzt nicht überprüft)

Vielleicht hilft dir das schon mal weiter.

Grüße,
Dirk
 
Hi Finn,

na das ist ja ne Überraschung ;) Schön das du mal wieder vorbeischaust.
So wie es aussieht kommst du auch nicht mehr von den Käfern los :D :rolleyes:

[EDIT] Verdammt, wieso kann man den Namen des Themas nicht ändern. Ich war doch noch garnicht fertig. =(
Ich hab das Thema mal umbenannt ... ich hoffe der Name paßt so ...

Gruß
Dino
 
Hi Leute,
wir haben das heute mal ausprobiert.
Also wir den Port getoggled haben, konnten wir eine Schaltzeit von ca. 1,8 - 1,9ms vom Oszi lesen.
Liegt also an der Berechnung sehr nah.

Jetzt habe ich mal weitergespielt. Jedoch leuchten die LEDs mal wieder nur vor sich hin.

Code:
#define F_CPU 1000000UL


#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdint.h>

//    Globale Variable definieren

unsigned int flash_step_counter = 0;

int main (void)
{

    //    Ausgänge setzen

    DDRA = 0b11111111;
    PORTA = 0b00000000;

    //    Timer 0 initialisieren

    TIMSK |=  (1<<OCIE0);

    OCR0 = 128+1;

    TCCR0 &= ~(1<<CS02);
    TCCR0 |=  (1<<CS01);
    TCCR0 |=  (1<<CS00);

    TCCR0 |=  (1<<COM01);
    TCCR0 &= ~(1<<COM00);

    while(1)
    {

        sei();

        if (flash_step_counter > 1000 )
        {
            flash_step_counter = 0;
        }

        if(flash_step_counter < 500 )
        {
            PORTA = 0b11111111;
        }
        else
        {
            PORTA = 0b00000000;
        }    
    }
    
return 0;
}



ISR(TIMER0_COMP_vect)
{

    flash_step_counter++;
}

M.E. nach sollten die LEDs jede Sekunde den Zustand wechseln.
Wo liegt jetzt schon wieder der Fehler?

Danke!

Liebe Grüße,
Finn
 
Hallo Finn,

also deine Timerberechnung aus dem ersten Beitrag stimmt irgendwie nicht, bzw. verstehe ich nicht...
Berechnung:
1000000 / 64 = 15625 / 1000 = 15,625ms
=> Alle 15,625ms zählt TCNT0 + 1.

Der Systemtakt ist 10MHz, der Prescaler ist 64. Ich komme dann auf 6,4us Timertakt (also 156250Hz).

Der CompareInterrupt soll alle 1ms auftreten, nehme ich an?

Grüße,
Dirk
 
Hi,
das Interne-Quarz hat doch eine Taktfrequenz von 1 Mhz. Oder irre ich mich da?

Wie schnell kann ich denn eine Variable durch eine ISR hochzählen lassen.
Packt die Software, jede Ms die Variable um 1 hochzuzählen?
Nicht das er sich da irgendwo verschluckt.
Liebe Grüße,
Finn
 
Es ist ein RC Oszillator. Mit welcher Frequenz der läuft, ist abhängig vom Mikrocontroller. -> Datenblatt

Wenn ich mal überschlage ... bei der Aufgabe die du beschreibst, ist ein AVR mit 16MHz Systemtakt grob zu 1/1.000 ausgelastet.

Dirk
 
Hallo,

so ich konnte den RC Osz. umstellen.
Steht jetzt laut AVR Studio auf:
Int. RC Osc. 8MHz; Start-up time; 6CK + 64ms

Im Datenblatt finde ich nur die Info, dass er bis zu 16Mhz getaktet werden kann. Wie schnell intern weis ich nicht.

Ich wusste garnicht, dass der 8515-16D sogar 8Mhz intern hat. Da stelle ich mir aber die Frage, wieso manche in ihrer Schaltung dann trotzdem einen externen 8Mhz nehmen.

So jetzt nochmal!

Code:
/* Auto-LED-Blitzer
Version: 0.1
Datum: 027.02.2009
Autor: Finn Schürmann
Target: ATMega 8515
Osc: Int. Osc. 8MHz
*/


#define F_CPU 1000000UL

#include <avr/io.h>
#include <util/delay.h>
#include <avr/eeprom.h>
#include <avr/interrupt.h>
#include <inttypes.h>

    
volatile unsigned int flash_step_counter = 0;

ISR ( TIMER0_COMP_vect )
{
    flash_step_counter++;
}

int main (void)
{
    DDRA = 0b11111111;        // Port A auf Ausgang
    PORTA = 0b00000000;        // Port A aus
    
    OCR0 = 124;                //    Timer zählt bis 2 = 2ms

    // Timer0 initialisieren
    TCCR0 |=  (1<<COM01);    //    Hier wird der Timer    
    TCCR0 &= ~(1<<COM00);    //    auf CTC-Modus gestellt

    TCCR0 |=  (1<<CS02);    //    Prescaler auf clock / 1024
    TCCR0 &= ~(1<<CS01);    //    1.000.000 / 1024 = 976,56 Hz
    TCCR0 |=  (1<<CS00);    //    976,56 Hz / 1000 = 0,98 ms



    TIMSK |=  (1<<OCIE0);    //    Interrupt für Compare Match erlauben

    sei();                    //    Globale Interrupts aktivieren

    unsigned char programm = 1;
//    unsigned char letzterzustand;

    // Programm Start
    while (1)
    {


/*        // Programm weiter
        if ( letzterzustand == 0 )
        {
            if ( (PINB & (1<<PB0) ))
            {
                letzterzustand = 1;
                programm++;
            }
        }

        if ( letzterzustand == 1 )
        {
            if ( ! (PINB & (1<<PB0) ))
            {
                letzterzustand = 0;
                programm++;
            }
        }

        // Programm-Begrenzung
        if ( programm > 4 )
        {
            programm = 1;
        }                                
*/

        if( flash_step_counter > 2000 )
        {    
            flash_step_counter = 0;
        }
    

        // Programm 1
        if( programm == 1 )
        {

            if( flash_step_counter < 1000 )
            {
                PORTA = 0b11111111;
            }
            if(flash_step_counter > 1000 )
            {
                PORTA = 0b00000000;
            }
                
        }    

    }
}
8.000.000Hz / 64 = 125.000 Hz => 1 / 125.000 Hz = 0,000.008 s => Ein Takt
0,000.008 s * 124 (=> OCR0 ) = 0,000.992 s ~ 1ms

Demnach müsste jede ms die Variable flash_step_counter um 1 hochgezählt werden. Macht also 2.000ms = 2 s. Bei der hälfte der Zeit, wird die LED ja umgeschaltet => 0,5 Hz (1s an <-> 1S aus)
Ich habe eben mal gemessen, er blinkt jedoch im moment mit ca. 5 Hz (4,98Hz).

Wieso?
 
Hi
Hi,
das Interne-Quarz hat doch eine Taktfrequenz von 1 Mhz. Oder irre ich mich da?

Wie schnell kann ich denn eine Variable durch eine ISR hochzählen lassen.
Packt die Software, jede Ms die Variable um 1 hochzuzählen?
Nicht das er sich da irgendwo verschluckt.
Liebe Grüße,
Finn
Solche Prüfungen kannst du selbst durchführen. Nimm den Taschenrechner und errechne den Kehrwet von 1000000 oder im Kopf: 1/1000000=0,000001 Sekunde
Also hast du jede µSek. einen Takt. In der Regel braucht ein Befehl 2 Takte.
Wenn du in deiner Timer-ISR alle msk. eine Variale hochzählst, dann sieht das etwa so aus:
Code:
LDS   Reg_A, Zaehler
INC   Reg_A
STS  Zaehler, Reg_A
Das sind grad mal ca. 6 µSek. Dazu kommen noch die in einer ISR üblichen Push und POP-Befehle, aber wie du siehst, bist du noch weit vom "Überholen" entfernt. In C oder BASCOM kann es durch die zusätzlichen PUSH und POP etwas größere Durchlaufzeit geben, aber wenn nicht allzuviel in der ISR bearbeitet wird, ist auch das kein Thema. Auch wenn dein Programm sehr umfangreich ist, die ISR wird auf jeden Fall im mSek. Takt aufgerufen, unter Umständen auch mehrmals im Programmzyklus. Das bedeutet, du bekommst die Einzelschritte nicht mehr mit, sondern dein Zähler scheint zu "stolpern".
Gruß oldmax
 
Hallo Finn,

in diesem Thread http://www.mikrocontroller.net/topic/208957 wird das selbe Thema behandelt, vielleicht findest du dort ja Hilfe.

Dirk


Jap, das war ein Thread von mir.

-----------------------------------------------

Ja, die Frequenz kann ich ausrechnen, andersrum auch die Periodendauer.
Ich versuche nur zu verstehen, wieso die LED mit Faktor 10 blinkt.

Blinkt mit 5Hz, errechnet 0,5Hz.
 
Finn,

der Prescaler in deinem Programm stimmt nicht, du hast noch 1024 gewählt.

Du hast auch keinen CTC Mode gewählt. Du musst WGM01 im Register TCCR0 setzen und nicht COM01. (Das hattest du schon mal richtig :rolleyes:)

Bei 8MHz Systemtakt, Prescaler=64 und OCR=124 erreichst du übrigens exakt 1ms CompareEvent-Zeit.

Dirk
 
Hallo Finn,

Im Datenblatt finde ich nur die Info, dass er bis zu 16Mhz getaktet werden kann. Wie schnell intern weis ich nicht.

Ich wusste garnicht, dass der 8515-16D sogar 8Mhz intern hat. Da stelle ich mir aber die Frage, wieso manche in ihrer Schaltung dann trotzdem einen externen 8Mhz nehmen.
intern läuft bei den Chips eigentlich immer ein 8MHz RC-Oszillator. Also ein
Oszillator der mit einer Widerstands-Kondensator-Schaltung den 8MHz-Takt
erzeugt. Das läuft, ist aber recht ungenau und nicht stabil bei Schwankungen
der Temperatur. Versuch damit mal ne Uhr zu programmieren. Die kannst du
ein paar mal am Tag neu stellen :eek: :D :rolleyes:
Mit der "CKDIV8" Fuse wird der Takt dann durch 8 geteilt und du hast die
1MHz mit denen manche frisch aus der Fabrik laufen. Also ohne externen
Takt kannst du dich zwischen 1MHz und 8MHz entscheiden. Mehr nicht.

Mit dem externen Quarz bekommst du eine wirklich genaue und stabile
Taktbasis für dein Programm. Wobei Uhrenquarze gegenüber normalen
Quarzen noch stabiler bei Temperaturänderungen ihre Frequenz halten.
ppm/°C --> ppm = Parts per Million (Teile einer Million)
% --> Teile von Hundert
also alles recht genau.
Wenn du was ganz genaues haben willst, dann mußt du einen Quarzoszillator
mit stabilisierter Spannung betreiben und zusätzlich noch die Schaltung in
eine temperaturisolierte Box (nennt man Quarzofen) mit einer stabilen
Temperatur betreiben. Dann wird das ganze noch vorgealtert und dann ist
es wirklich ziemlich stabil ;) aber auch ziemlich teuer :p

Gruß
Dino
 
Hi Leute, danke, das hat geholfen.
Da ich nur 3-4 Zeiteinheiten brauche, z.B.:
T(lang); T(kurz), T(mittel)

möchte ich diese global festlegen.
Damit ich in meinem Programm...
Code:
        if( programm == 2 )
        {
            if( flash_step_counter > 800 )
            {    
                flash_step_counter = 0;
            }

            if( flash_step_counter >= 0 && flash_step_counter < 50 ) 
            {
                PORTA = 0b00000001;
            }
            if(flash_step_counter >= 50 && flash_step_counter < 150 )
            {
                PORTA = 0b00000000;
            }
            if(flash_step_counter >= 150 && flash_step_counter < 200)
            {
                PORTA = 0b00000001;
            }
            if(flash_step_counter >= 200 && flash_step_counter < 700 )
            {
                PORTA = 0b00000000;
            }
            if( flash_step_counter >= 700 && flash_step_counter < 750 ) 
            {
                PORTA = 0b00000100;
            }
            if(flash_step_counter >= 750 && flash_step_counter < 850 )
            {
                PORTA = 0b00000000;
            }
            if(flash_step_counter >= 850 && flash_step_counter < 900)
            {
                PORTA = 0b00000100;
            }
            if(flash_step_counter >= 900 && flash_step_counter < 1000 )
            {
                PORTA = 0b00000000;
            }                
        }
...nicht alle Zahlen neu "Berechnen" muss, wenn ich nur eine Zeit änder.

Wie kann ich das abfragen?
Ich muss ja irgendwie den aktuellen wert von flash_step_counter auslesen. Und darüber dann eine Zeit variabel festlegen.

Liebe Grüße,
Finn
 
Hallo Finn,

wenn ich das Fragment richtig verstehe, brauchst Du 2 verschiedene, pulsbreitenmodulierte Takte. So was kann man mit PWM lösen. Da könntest Du Dir die ganze Rchnerei sparen und läßt das einfach den Käfer machen.

Übrigens in Deinem letzten Codebeispiel dürften die letzten 3 Abfragen unwirksam sein, da Du bereits bei 800 nullst (am Anfang).

Was soll das denn eigentlich werden? Mach doch mal eine Skizze der benötigten Signalverläufe an den beiden Ausgängen.

Michael
 
Hi,

das soll einfach nur eine Blitzabfolge sein.
Doppelzblitz Links, doppelblitz rechts.
Den Fehler hatte ich schon bemerkt.
 
Hallo Finn,

mmmh einen 8515-16D verwendest Du. Der kann nur einen Ausgang bedienen. Man müßte überlegen, ob man es nicht mit PWM hinbekommt - zumindest die Taktfolge damit generiert und in der ISR dann die Ausgänge schaltet. Ich nehme an, dass die ganze Sache synchronisiert ablaufen soll. Demnach scheiden 2 getrennte PWMs aus.
Ich hab leider noch nicht so viel mit PWM gemacht (außer Hintergrunddimmung für LCD). Vielleicht gibt es jemand im Forum, der sich da besser auskennt.

Michael
 
Hallo Fin,

erfahrungsgemäß hat mir Dein Problam keine Ruhe gelassen. Da ich noch einen Atmega8 rumzuliegen hatte, habe ich mich mal dran gemacht und das Problem per PWM gelöst. Ich benutze den 16er Timer1, den hat Dein Käfer auch.

Erster Schritt war, einen Grundtakt zu erzeugen nach dem Muster 2xein mit mittlerer Pause, dann lange Pause und dann Wiederholung. Die Länge des Signale und Pausen kann man mit 3 Variablen tunen - die Grundfrequenz wird durch den prescaler eingestellt. In meinem beispiel hab ich die Werte so berechnet, dass Sie auf dem Logiport gut zu sehen sind.
Aber zunächst der Code:
Code:
// defines
// berechnet auf Takt 14.7456 MHz
#define KURZ 	36		// ca 5ms
#define MITTEL	144		// ca 10ms
#define LANG	720		// ca 50ms

// Prototypen
void initTimer1();						// Timer 1 für PWM-Erzeugung

// Globale
volatile short counter = 0;
volatile short ausgang = 0;
volatile short pulsCounter = 0;
volatile short flanke = 0;

volatile int kurz = KURZ;
volatile int mittel = MITTEL;
volatile int lang = LANG;



///////////////////////////////////////////////////////////
int main( void )						// Hauptprogramm
{
	// Setup PortB
	PORTB = 0x00;
	DDRB  = 0x00;
	DDRB  = (1<<DDB0) | (1<<DDB1) | (1<<DDB2) | (1<<DDB3);

	// Setup PortC
	PORTC = 0x00;
	DDRC = 0x00;

	// Setup PortD
	PORTD = 0x00;
	DDRD  = 0x00;

	counter = 0;
	ausgang = 0;
	flanke = 0;
	pulsCounter = 0;

	PORTB &= ~(1<<PB3);

	// Timer für PWM
	initTimer1();
	


	sei();                	// enable interrupts

	

	// Mainloop
	do
	{
		
	}	
	while(1);

}

//--------------------------------------------------------------------
// TIMER1_COMPA_vect - Timer1 Interrupt bei Vergleichswert
//--------------------------------------------------------------------
ISR(TIMER1_COMPA_vect)
{
	
	// toggle Flanke
	flanke ^= 1;
	// Pulszähler bei fallender Flanke erhöhen
	if(flanke == 0)
		pulsCounter++;
	
	
	if(ausgang == 0)
	{
		// Toggle Ausgang 1
		PORTB ^= ( 1 << PB0 );
	}
	else
	{
		// Toggle Ausgang 2
		PORTB ^= ( 1 << PB2 );
	}
	
	// toggle Ausgang, wenn 2 Pulse vorbei sind
	if(pulsCounter == 2)
	{
		ausgang ^= 1;
		pulsCounter = 0;
	}

	
}

//--------------------------------------------------------------------
// TIMER1_OVF_vect - Timer1 Interrupt bei Überlauf
//--------------------------------------------------------------------
ISR(TIMER1_OVF_vect)
{
	counter++;
	if(counter == 1)
	{
		// Pausenzähler auf lange Pause setzen
		ICR1 = lang;
		PORTB |= (1<<PB3);	// Kontrollsignal an PB3
	}
	else
	{
		if(counter == 2)
		{
			// lange Pause ist vorbei
			PORTB &= ~(1<<PB3);	// Kontrollsignal an PB3 
			ICR1 = mittel;	// Pausenzähler wieder auf normal setzen
			counter = 0;
		}
	}
	
	
}


/////////////////////////////////////////////
//----------------------------------------------------------------------
// Titel	: C Funktion zur Initialisierung des Timer1
//----------------------------------------------------------------------
// Funktion	: ...Timer für PWM
// IN 		: ...
// OUT		: ...
//----------------------------------------------------------------------
void initTimer1()
{
	TCCR1A = (1<<COM1A1);				// Toggle an OC1A / PB1
	TCCR1A |= (1<<WGM11) | (1<<WGM12);	//FAST PWM Mode 14
	TCCR1B = (1<<WGM13);
	TCCR1B |= (1<<CS10) | (1<<CS12); 	// Teiler 1/1024
 	OCR1A = kurz; 	// Signalbreite 
	ICR1 = mittel;	// Pausenbreite
	
 	TIMSK = (1<<OCIE1A) | (1<<TOIE1); 	// Interrupt bei Vergleichswert und Überlauf 
	TIFR = (1<<OCF1A) | (1<<TOV1);
}
Die Ausgabe des Grundtaktes an PB1 dient nur der Kontrolle, ebenso wie die Ausgabe an PB3 für den Überlaufinterrupt. Enstcheidend sind letzendlich nur die beiden Ausgänge.
Die Zeiten kannst Du über die Konstanten verändern bzw. auch während der Laufzeit. Ansonsten ist das Ganze auf Dein Muster ausgelegt (2links, 2 rechts).
Im Anhang findest Du einen Plot vom Logiport.

Ich hoffe, das das auch Deinem Käfer läuft.
Viel Spaß damit.

Michael
 

Anhänge

  • pwm.JPG
    pwm.JPG
    68,2 KB · Aufrufe: 6
Hi,
danke für deine Hilfe.
Ich habe auch ein bisschen weitergebastelt. Ich versuche am WE mal dein Programm zu verstehen.

Ich habe bei mir folgendes Problem:
Ich habe ein Relais das PB0 auf Masse zieht.
Das Relais wird von einer Funk-Platine angesteuert als Stromstoßschaltung.
Wenn ich die Abfrage von PB0 etc. rausnehme und die Variable für die Programmwahl ( 1, 2, 3) manuell einstelle, läuft alles super.
Nehm ich die Pin-Abfrage wieder rein, stimmt das Programm völlig.
Z.B. leuchten alle LEDs halb und ein Programm gleichzeitig mit voller Helligkeit darüber liegend.
Oder der Controller leuchtet bei dem Doppelblitz nur auf einer LED die ganze Zeit.
Umschalten läuft allerdings, nur die Programme laufen nicht mehr.

Woran könnte das liegen? Das Signal vom Relais ist sauber.
Code:
/* Auto-LED-Blitzer
Version: 0.1
Datum: 027.02.2009
Autor: Finn Schürmann
Target: ATMega 8515
Osc: Int. Osc. 8MHz
*/


#define F_CPU 8000000UL

#include <avr/io.h>
#include <util/delay.h>
#include <avr/eeprom.h>
#include <avr/interrupt.h>
#include <inttypes.h>

    
volatile unsigned int flash_step_counter = 0;

ISR ( TIMER0_COMP_vect )
{
    flash_step_counter++;
}

int main (void)
{
    DDRA    = 0b11111111;    // Port A auf Ausgang
    PORTA    = 0b00000000;    // Port A aus

    
    DDRB    = 0b00000000;    //    PORT auf Eingang
    PORTB    = 0b11111111;    //    Interne Pull-Ups aktivieren
    
    OCR0 = 124;                //    TCI = 1ms

    // Timer0 initialisieren
    TCCR0 |=  (1<<WGM01);    //    Hier wird der Timer    
    TCCR0 &= ~(1<<WGM00);    //    auf CTC-Modus gestellt

    TCCR0 &= ~(1<<CS02);    //    Prescaler auf clock / 64                                        
    TCCR0 |=  (1<<CS01);    //    8.000.000 / 64 = 125.000 Hz
    TCCR0 |=  (1<<CS00);    //    1 / 125.000 Hz = 0,008 ms * 124 = 0,992 ms



    TIMSK |=  (1<<OCIE0);    //    Interrupt für Compare Match erlauben

    sei();                    //    Globale Interrupts aktivieren

    unsigned char programm = 1;
    unsigned char letzterzustand = 0;



    // Programm Start
    while (1)
    {

            volatile unsigned int entprellcounter ;

        

        // Programm weiter
        if ( letzterzustand == 0 )
        {
            if ( (PINB | (1<<PB0)))
            {
                entprellcounter++;
            }
            else
            {
                entprellcounter = 0;
            }

            if( entprellcounter > 20)
            {
                letzterzustand = 1;
                programm++;
            }
        }

        if ( letzterzustand == 1 )
        {
            if ( (PINB & (1<<PB0)))
            {
                entprellcounter++ ;
            }            
            else
            {
                entprellcounter = 0;
            }

            if( entprellcounter > 20)
            {
                letzterzustand = 0;
                programm++;
            }
        }

        // Programm-Begrenzung
        if( programm == 4 )
        {
            programm = 1;
        }                                


        // Programm 1
        if( programm == 1 )
        {
            PORTA = 0b11111111;    
        }
    
        // Programm 2
        if( programm == 2 )
        {
            if( flash_step_counter > 700 )
            {    
                flash_step_counter = 0;
            }

            if( flash_step_counter >= 0 && flash_step_counter < 100 ) 
            {
                PORTA = 0b11111111;
            }
            if(flash_step_counter >= 100 && flash_step_counter < 200 )
            {
                PORTA = 0b00000000;
            }
            if(flash_step_counter >= 200 && flash_step_counter < 300)
            {
                PORTA = 0b11111111;
            }
            if(flash_step_counter >= 300 && flash_step_counter < 700 )
            {
                PORTA = 0b00000000;
            }
                
        }
        
        // Programm 3
        if( programm == 3 )
        {
            if( flash_step_counter > 1100 )
            {    
                flash_step_counter = 0;
            }

            if( flash_step_counter >= 0 && flash_step_counter < 100 ) 
            {
                PORTA = 0b00000001;
            }
            if(flash_step_counter >= 100 && flash_step_counter < 200 )
            {
                PORTA = 0b00000000;
            }
            if(flash_step_counter >= 200 && flash_step_counter < 300)
            {
                PORTA = 0b00000001;
            }
            if(flash_step_counter >= 300 && flash_step_counter < 500 )
            {
                PORTA = 0b00000000;
            }
            if( flash_step_counter >= 500 && flash_step_counter < 600 ) 
            {
                PORTA = 0b00000100;
            }
            if(flash_step_counter >= 600 && flash_step_counter < 700 )
            {
                PORTA = 0b00000000;
            }
            if(flash_step_counter >= 700 && flash_step_counter < 800)
            {
                PORTA = 0b00000100;
            }
            if(flash_step_counter >= 800 && flash_step_counter < 1100 )
            {
                PORTA = 0b00000000;
            }                
        }


    }
}
 
Hallo Finn,

nur mal ein kurzer Hinweis zu deinem letzten Programm:

Der Entprellcounter wird aktuell sicher zu schnell inkrementiert, Einfluß auf die Zeit hat im Prinzip dein restliches Programm. Ich schätze mal, du entprellst hier im Mikrosekunden-Bereich, besser wäre Millisekunden. Die Variable Entprellcounter brauchst du im Moment auch nicht als "volatile" deklarieren.

Dirk
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)