- Labornetzteil AliExpress         
Seite 1 von 3 123 LetzteLetzte
Ergebnis 1 bis 10 von 25

Thema: PWM Frage und Interrupt mit Tasten?

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    03.10.2004
    Alter
    57
    Beiträge
    50

    PWM Frage und Interrupt mit Tasten?

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hallo Forum,

    Bin schon den ganzen Tag am basteln.
    Jetzt ist es so weit euch mal zu fragen.
    Ich habe ein Board USC08 mit dem Atmega8 mit 14,7456 MHZ und ein SN754410.
    Der Port PB1 ist der PWM OC1A geht auf den SN754410,
    Die Ports PD5 und PD6 gehen auch an den SN754410.

    Nun wollte ich erst einmal anfangen, ganz klein.
    Es sollte über einen Interrupt drei Tasten abgefragt werden.
    Taste1 "PB3" soll den Motor mit 50% nach links laufen lassen.
    Taste2 "PB4" soll den Motor mit 50% nach rechts laufen lassen.
    Taste3 "PB5" soll den Moter auf 100% beschleunigen.

    Hier mein Script.
    Der Motor läuft nicht.


    Code:
    #include <avr/io.h>
    #include <stdint.h>
    
    void pwminit()
    {
    DDRD = (1<<PD5);
    TCCR1A = (1<<COM1B1)|(1<<WGM10)|(1<<WGM12);
    TCCR1B = (1<<CS10);
    OCR1B = 128; 
    }
    
    
    void main (void)
    {
    DDRB=0x38;            // Port B  als Eingang
    PORTB=0x38;            // Pull-ups auf Port B ein
    DDRB = 0b11111111;
    
    
    while(1);
    
    if ( PINB & ( 1<<PINB3 ) )     
          {
    	     PORTD |= (1<<PD5);       
    		 pwminit();
             for( ; ; ){};
          }
    
    }
    Vom vielen testen weiß ich nicht mehr aus noch ein.
    Wäre jemand so nett mir dabei zu helfen.

    mfg
    Enterprise

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    02.11.2005
    Alter
    48
    Beiträge
    1.146
    Ich habe jetzt nicht alles überprüft, aber der entscheidene Fehler ist auf jeden Fall der hier:
    Code:
    while(1);
    Wenn Du hinter dem while(1) direkt ein Semikolon hast, ist die while-Schleife leer. Und da Du eine 1 als Laufbedingung hast, bleibt der Controller auf Ewig in dieser leeren Schleife gefangen.

    Richtig wäre:
    Code:
    while(1)
    {
    if (...)
    }
    Gruß,
    askazo

    [edit]
    Ich sehe gerade noch was ganz schlimmes...
    [code]for( ; ; ){};[code]
    Ich habe noch nie eine leere for-Schleife verwendet, aber das dürfte auch in einer Endlosschleife resultieren. D.h. hier würde Dein Controller schon wieder stecken bleiben. Was wolltest Du damit bezwecken?

    Und noch was: Interrupts hast Du hier bisher noch nicht verwendet... aber das solltest Du auch erst mal ohne machen.
    [/edit]

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    03.10.2004
    Alter
    57
    Beiträge
    50
    Danke für das schnelle Antworten.

    Hat nicht funktioniert.

    mfg
    Enterprise

  4. #4
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    02.11.2005
    Alter
    48
    Beiträge
    1.146
    Oh, jetzt warst Du aber sehr schnell mit antworten...
    Siehe edit im letzten Posting...

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    03.10.2004
    Alter
    57
    Beiträge
    50
    Sorry habe das Edit zu spät gesehen.

    Habe die Interrupts erstmal weggelassen. da es erstmal mit Tasten drücken funktionieren soll.

    Die Endlos schleife kam vom kopieren.

    Danach hat es auch nicht funktioniert.

    Hier jetzt der code ohne ; und ohne For schleife.

    Code:
    #include <avr/io.h>
    #include <stdint.h>
    
    void pwminit()
    {
    DDRD = (1<<PD5);
    TCCR1A = (1<<COM1B1)|(1<<WGM10)|(1<<WGM12);
    TCCR1B = (1<<CS10);
    OCR1B = 128; 
    }
    
    
    void main (void)
    {
    DDRB=0x38;            // Port B  als Eingang
    PORTB=0x38;            // Pull-ups auf Port B ein
    DDRB = 0b11111111;
    
    
    while(1)
    
    if ( PINB & ( 1<<PINB3 ) )     
          {
    	     PORTD |= (1<<PD5);       
    		 pwminit();
              }
    
    }
    mfg
    Enterprise

  6. #6
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    52
    Beiträge
    2.236
    Hallo,
    Code:
    DDRB=0x38;            // Port B  als Eingang 
    PORTB=0x38;            // Pull-ups auf Port B ein 
    DDRB = 0b11111111;
    Hast Du schon überlegt was in den 3 Zeilen passiert ?

    in der etsten Zeile machst Du PINB3 PINB4 und PINB5 zum Ausgang.
    in der zweiten Zeile Schaltest Du sie alle HIGH
    in der dritten Zeile machst Du dann den ganzen Port zum Ausgang.

    War das so gedacht ? Scheinbar nicht, sonst würdest Du PINB3 nicht abfragen wollen
    Schlimmer noch, soltest Du den Taster auf PB3 gegen GND schalten, baust Du Dir immer einen Kurzschluß...

    Mach das bitte so:
    Code:
    ...
    DDRB &=~(1<<PB3);
    PORTB |=(1<<PB3);
    
    while(1) { 
       if ( ~PINB & ( 1<<PINB3 ) )      
            { 
            PORTD |= (1<<PD5);        
           pwminit(); 
            } 
    ...
    Gruß Sebastian
    Software is like s e x: its better when its free.
    Linus Torvald

  7. #7
    Benutzer Stammmitglied
    Registriert seit
    03.10.2004
    Alter
    57
    Beiträge
    50
    Danke Sebastian,

    Ja die dritte Zeile war Mumpitz, auch nicht gewollt.

    Nun habe ich es geändert und eine Kontroll LED eingebaut.

    Die LED geht an aber der Motr will nicht laufen.

    Code:
    #include <avr/io.h>
    #include <stdint.h>
    
    void pwminit()
    {
    // DDRD = (1<<PD5);
    TCCR1A = (1<<COM1B1)|(1<<WGM10)|(1<<WGM12);
    TCCR1B = (1<<CS10);
    OCR1B = 128; 
    }
    
    
    void main (void)
    {
    DDRD=0x0c;             // Port PD2 u. PD3 auf Port D als Ausgang
    PORTD=0x0c;            // Pins PD2 u. PD3 auf Port D auf low
    
    DDRB &=~(1<<PB3);
    PORTB |=(1<<PB3);
    
    // DDRB=0x38;             // Port B  als Eingang
    // PORTB=0x38;            // Pull-ups auf Port B ein
    // DDRB = 0b11111111;
    
    
    while(1)
    
    if ( PINB & ( 1<<PINB3 ) )     
          {
    	     PORTD |= (1<<PD5);
    		 PORTD |= (1<<PD2);  	// LED ein "Test"    
    		 pwminit();
              }
    	else
        	{
          	PORTD &= ~(1<<PD2);		// LED aus "Test"
       	}     
    
    }
    mfg
    Enterprise

  8. #8
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    20.05.2006
    Ort
    Lippe
    Alter
    54
    Beiträge
    524
    Hallo,

    Code:
    DDRB=0x38;            // Port B  als Eingang
    PORTB=0x38;            // Pull-ups auf Port B ein
    DDRB = 0b11111111;
    Was möchtest du damit erreichen?


    Der Port PB1 ist der PWM OC1A geht auf den SN754410, ...
    Code:
    OCR1B = 128;
    Hm,..

    while ohne Klammer


    Von den Ungereimtheiten im Code mal abgesehen. Du weißt, dass pwminit wieder und wieder durchlaufen wird, bis PB3 auf GND gezogen wird?

    Schreib doch einmal genau, was du mit dem Programm erreichen möchtest. Sonst ist es sehr schwer Vorschläge zu machen.

    Gruß

    Jens

    Edit: Na da bin ich ja mal richtig lahm gewesen
    Edit: Wenn die Led leuchtet, wird die init immer angesprungen. Es liegt in der Natur einer anständigen Init, das diese nur einmal initalisieren sollte. Daher darf die LED nicht anbleiben.

  9. #9
    Benutzer Stammmitglied
    Registriert seit
    03.10.2004
    Alter
    57
    Beiträge
    50
    Hallo McJenson,

    Es sollte über einen Interrupt drei Tasten abgefragt werden.
    Taste1 "PB3" soll den Motor mit 50% nach links laufen lassen.
    Taste2 "PB4" soll den Motor mit 50% nach rechts laufen lassen.
    Taste3 "PB5" soll den Moter auf 100% beschleunigen.

    Nun das script erst ohne Interrupts, nur mal mit einer Taste.
    Die LED geht an aber nder Motor läuft nicht.


    Code:
    #include <avr/io.h>
    #include <stdint.h>
    
    void pwminit()
    {
    // DDRD = (1<<PD5);
    TCCR1A = (1<<COM1B1)|(1<<WGM10)|(1<<WGM12);
    TCCR1B = (1<<CS10);
    OCR1B = 128; 
    }
    
    
    void main (void)
    {
    DDRD=0x0c;             // Port PD2 u. PD3 auf Port D als Ausgang
    PORTD=0x0c;            // Pins PD2 u. PD3 auf Port D auf low
    
    DDRB &=~(1<<PB3);
    PORTB |=(1<<PB3);
    
    // DDRB=0x38;             // Port B  als Eingang
    // PORTB=0x38;            // Pull-ups auf Port B ein
    // DDRB = 0b11111111;
    
    
    while(1)
    
    if ( PINB & ( 1<<PINB3 ) )     
          {
    	     PORTD |= (1<<PD5);
    		 PORTD |= (1<<PD2);  	// LED ein "Test"    
    		 pwminit();
              }
    	else
        	{
          	PORTD &= ~(1<<PD2);		// LED aus "Test"
       	}     
    
    }
    mfg
    Enterprise

  10. #10
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    52
    Beiträge
    2.236
    Hallo, so wie ich sehe möchtest Du Timer1 in 8 Bit Fast PWM Mode betreiben und Dein Takt auf OC1B ausgeben, den mußt Du aber auch noch als Ausgang konfigurieren.
    Der liegt an PB2 also würde ich aus
    Code:
    DDRB &=~(1<<PB3);
    Code:
    DDRB = (1<<PB2);
    machen.

    Übrigens,
    Code:
    TCCR1B = (1<<CS10);
    Damit läuft der Timer mit µC Takt, ist das nicht was schnell ?

    Gruß Sebastian

    P.S.

    Hm,..

    while ohne Klammer
    @McJenso,
    das hab ich mir auch gedacht, aber das dürfte hier sogar funktionieren
    trotzdem hab ich in meinem Vorschlag lieber die Klammern drum gemacht \/
    Software is like s e x: its better when its free.
    Linus Torvald

Seite 1 von 3 123 LetzteLetzte

Berechtigungen

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

MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad