- Labornetzteil AliExpress         
Seite 3 von 3 ErsteErste 123
Ergebnis 21 bis 24 von 24

Thema: Programm wird nur einmal durchlaufen

  1. #21
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.214
    Anzeige

    E-Bike
    Mein Ziel wäre es eben schlussendlich ein Servo ansteuern zu können
    Dazu wäre der Timer 1 der ATMEGA's meiner Meinung nach optimal geeignet.
    Du lässt der Controller mit 8MHz Taktfrequenz laufen und stellst den Prescaler des Timers 1 auf 8.
    Somit entspricht ein inkrement des Timers 1 genau 1µs.

    Du gibst nun die beiden Comparematch Interrupts des Timers frei.

    Der Comparematch Interrupt A löst einen Interrupt aus.
    Die Routine in diesem Interrupt zählt zum augenblicklichen Zählerstand des Timers 1 die gewünschte Impulslänge, also z.B. 1500 für 1,5ms dazu und speichert diesen Wert im Comparematch B Register ab.
    Gleichzeitig wird ein Port auf High geschaltet.

    Der Controller läuft nun weiter bis der Comparematch B erreicht ist.
    Die Interruptroutine hier drin zählt zum aktuellen Zählerstand des Timers 1 die gewünschte Pausenzeit hinzu z.B. 19000 für 19ms.
    Dieser Wert wird dann im Comparematch A Register abgespeichert.
    Gleichzeitig wird der in der Comparematch A gesetzte Ausgang wieder auf 0 gesetzt.

    Somit läuft die komplette Impulserzeugung im Interrupt des Controllers ab.
    Die gewünschten Servoimpulslängen können direkt im Comparematch A aus Hilfsregistern übernommen werden.

    Eine Erweiterung der möglichen Servokanäle auf ca 8...9 sollte problemlos möglich sein. Man braucht ja nur in der Comparematch A Routine eine Hilfsvariable einsetzen, die bei jedem Durchlauf hochgezählt wird und jeweils einen anderen Servoausgang aktiviert.

    Im Comparematch B muss bei mehreren Kanälen die Pausenzeit verkürzt werden, damit man wieder auf eine Refreshrate von ca. 20ms pro Servoausgang kommt. Praktischerweise würde ich im Comparematch B immer alle benutzten Servoausgänge auf 0 setzen.
    Nimmt man dafür einen komplatten Port, geht das mit einem Kommando.

    Da der Zählerstand von TCNT1 bei dieser Methode nicht beinflusst wird, kann man den Timer 1 auch noch zusätzlich für Zeitmessungen o.Ä. verwenden.

  2. #22
    Neuer Benutzer Öfters hier
    Registriert seit
    23.03.2009
    Beiträge
    10
    Hallo.
    Danke für die ausführliche Antwort. Also:
    Den Prescaler müsste ich einstellen mit:
    TCCR1B = (1<<CS11)
    ?
    Und damit die Comparematch Interrupts des Teimers frei werden und OC1 auf high gesetzt wird müsste ich das ungefähr so machen:
    TCCR1A = (1<<COM1A1) | (1<<COM1A1)
    ?

    Und jetzt sollte das eigentlich mit dem Vergleichswert verglichen werden und sobald diese dann gleich sind ein Interrupt ausgelöst werden? Stimmt das?

    Karl

  3. #23
    Neuer Benutzer Öfters hier
    Registriert seit
    23.03.2009
    Beiträge
    10
    Achja zur Servoansteuerung:

    Ich hab mich da mal im Wiki umgesehen und dieses Programm gefunden:
    Code:
    #define SERVOPIN 7
    #define SERVOPORT PORTD
    #define DDRSERVO DDRD
    
    volatile unsigned char servopos;
    
    void servo_init()
    {
    	TIMSK|=(1<<OCIE2);
    	TCCR2 |= (1<<WGM21) | (1<<CS20);	//Prescale=1, CTC mode
    	OCR2 = F_CPU/100000;			//alle 10µS ein IRQ
    	DDRSERVO|=(1<<SERVOPIN);
    };
    
    ISR(TIMER2_COMP_vect)
    {
    	static int count;
    	if(count>servopos)SERVOPORT&=~(1<<SERVOPIN);
    	else SERVOPORT|=(1<<SERVOPIN);
    	if(count<2000+servopos)count++;
    	else count=0;
    };
    Ist mit diesem Programm die Funktion ISR () definiert?
    Mit Servo_init () wird zwar hier der Timer initialisiert.

    Und könnte ich mit diesem Programm anschliessend an ISR ()
    int main (void) schreiben
    und nun die Funktion ISR benutzten?

    Oder hab ich da was falsch verstanden?

    Grüsse!

  4. #24
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.214
    Hier die Einstellungen für einen ATMEGA 16 bei 8MHz

    Code:
    // Timer/Counter 1 initialization
    // Clock source: System Clock
    // Clock value: 1000,000 kHz
    // Mode: Normal top=FFFFh
    // OC1A output: Discon.
    // OC1B output: Discon.
    // Noise Canceler: Off
    // Input Capture on Falling Edge
    // Timer 1 Overflow Interrupt: Off
    // Input Capture Interrupt: Off
    // Compare A Match Interrupt: On
    // Compare B Match Interrupt: On
    TCCR1A=0x00;
    TCCR1B=0x02;
    TCNT1H=0x00;
    TCNT1L=0x00;
    ICR1H=0x00;
    ICR1L=0x00;
    OCR1AH=0x00;
    OCR1AL=0x00;
    OCR1BH=0x00;
    OCR1BL=0x00;
    
    // Timer(s)/Counter(s) Interrupt(s) initialization
    TIMSK=0x18;
    Und hier die dazugehörigen Interruptroutinen für 4 Kanäle

    Code:
    // Timer 1 output compare A interrupt service routine
    interrupt [TIM1_COMPA] void timer1_compa_isr(void)
    {
    PORTC=0; // Port C abschalten = alle Ausgänge aus
    
    }
    
    // Timer 1 output compare B interrupt service routine
    interrupt [TIM1_COMPB] void timer1_compb_isr(void)
    {
    switch(uc_channel)
    {
        case 0:
        PORTC.0=1;           // Kanal 1 ein
        OCR1A=ui_pwm[0];
        break;
        
        
        case 1:
        PORTC.1=1;           // Kanal 2 ein
        OCR1A=ui_pwm[1];
        break;
        
        case 2:
        PORTC.2=1;           // Kanal 3 ein
        OCR1A=ui_pwm[2];
        break;
        
        case 3:
        PORTC.3=1;           // Kanal 4 ein
        OCR1A=ui_pwm[3];
        break;
    }; 
    TCNT1=0;
    uc_channel++;
    if ( uc_channel>3){uc_channel=0;};
    }
    Ich hab die Routinen noch nicht mit Servos getestet, man möge mir also Fehler verzeihen, wenn was nicht stimmt.

    Die Codes sind für Codevision AVR, sollten sich aber leicht für andere Compiler umschreiben lassen.

Seite 3 von 3 ErsteErste 123

Berechtigungen

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

fchao-Sinus-Wechselrichter AliExpress