-         
+ Antworten
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 17

Thema: PWM mit ATMega8

  1. #1
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    22.07.2004
    Beiträge
    270

    PWM mit ATMega8

    Hallo,
    könnt ihr mir vielleicht sagen wie ich in Bascom ein PWM Signal erzeugen kann? Ich hab schon gesucht, aber nichts gefunden, was mir weiterhilft.
    Es gibt ja auch Hard- und Software-PWM...
    Gruß
    Spurius

  2. #2
    Administrator Robotik Einstein Avatar von Frank
    Registriert seit
    30.10.2003
    Beiträge
    4.943
    Blog-Einträge
    1
    Hi,

    wenn du unter Bascom programmierst geht das unter fast allen Atmel Controllern gleich. Du kannst dir also auch andere Beispiele anschaun. Hier z.B. das Programm zum Mega 16 (rn-control)
    Schau dir darin mal die Motorroutine an


    Code:
    '################################################### 
    'rncontroltest.BAS 
    'für 
    'RoboterNetz Board RN-Control 1.1 
    'Das neue preiswerte Controllerboard zum experimentieren 
    ' 
    'Aufgabe: 
    ' Dieses testprogramm testet gleich mehrere Eigenschaften auf dem Board 
    ' Den verschiedenen Tasten sind bestimmte Funktionen zugeordnet 
    ' Taste 1: Zeigt Batteriespannung über RS232 an 
    ' Taste 2: Angeschlossene Motoren beschleunigen und abbremsen 
    ' Taste 3: Einige male Lauflicht über LED´s anzeigen. Am I2C-Bus 
    '          darf in diesem Moment nichts angeschlossen sein 
    ' Taste 4: Zeigt analoge Messwerte an allen Port A PIN´s über RS232 an 
    ''Taste 5: Zeigt digitalen I/O Zustand von PA0 bis PA5 an 
    
    
    ' Ser gut kann man aus dem Demo auch entnehmen wie Sound ausgegeben wird, 
    ' wie Tasten abgefragt werden und wie Subroutinen und Funktionen angelegt werden 
    
    'Autor: Frank 
    'Weitere Beispiele und Beschreibung der Hardware 
    'unter http://www.Roboternetz.de oder robotikhardware.de 
    '####################################################### 
    
    
    Declare Sub Batteriespannung() 
    Declare Sub Motortest() 
    Declare Sub Lauflicht() 
    Declare Sub Showporta() 
    Declare Sub Showdigitalporta() 
    Declare Function Tastenabfrage() As Byte 
    
    
    $regfile = "m16def.dat" 
    
    Dim I As Integer 
    Dim N As Integer 
    dim Ton As Integer 
    
    
    $crystal = 16000000                                         'Quarzfrequenz 
    $baud = 9600 
    
    Config Adc = Single , Prescaler = Auto                      'Für Tastenabfrage und Spannungsmessung 
    
    Config Pina.7 = Input                                       'Für Tastenabfrage 
    Porta.7 = 1                                                 'Pullup Widerstand ein 
    
    
    Const Ref = 5 / 1023                                        'Für Batteriespannungsberechnung 
    
    Dim Taste As Byte 
    Dim Volt As Single 
    
    ' Für Motorentest 
    'Ports für linken Motor 
    Config Pinc.6 = Output                                      'Linker Motor Kanal 1 
    Config Pinc.7 = Output                                      'Linker Motor Kanal 2 
    Config Pind.4 = Output                                      'Linker Motor PWM 
    'Ports für rechten Motor 
    Config Pinb.0 = Output                                      'Rechter Motor Kanal 1 
    Config Pinb.1 = Output                                      'Rechter Motor Kanal 2 
    Config Pind.5 = Output                                      'Rechter Motor PWM 
    Config Timer1 = Pwm , Pwm = 10 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down 
    Pwm1a = 0 
    Pwm1b = 0 
    Tccr1b = Tccr1b Or &H02                                     'Prescaler = 8 
    
    
    
    
    
    I = 0 
    Sound Portd.7 , 400 , 450                                   'BEEP 
    Sound Portd.7 , 400 , 250                                   'BEEP 
    Sound Portd.7 , 400 , 450                                   'BEEP 
    Print 
    Print "**** RN-Control 1.1 *****" 
    Print "Das neue Experimentier- und Roboterboard" 
    Print 
    Do 
    
    
    
    
       Taste = Tastenabfrage() 
       If Taste <> 0 Then 
    
          Select Case Taste 
             Case 1 
                Call Batteriespannung                           'Taste 1 Zeigt Bateriespannung über RS232 an 
             Case 2 
                Call Motortest                                  'Taste 2 Motoren beschleunigen und abbremsen 
             Case 3 
                Call Lauflicht                                  'Einige male Lauflicht über LED´s anzeigen. Am I2C-Port darf in diesem Moment nichts angeschlossen sein 
             Case 4 
                Call Showporta                                  'Zeigt Messwerte an allen Port A PIN´s 
             Case 5 
                Call Showdigitalporta                           'Zeigt digitalen I/O Zustand von PA0 bis PA5 an 
    
    
    
          End Select 
          Sound Portd.7 , 400 , 500                             'BEEP 
       End If 
    
       Waitms 100 
    Loop 
    
    End 
    
    
    
    
    'Diese Unterfunktion fragt die Tastatur am analogen Port ab 
    Function Tastenabfrage() As Byte 
    Local Ws As Word 
    
       Tastenabfrage = 0 
       Ton = 600 
       Start Adc 
       Ws = Getadc(7) 
       If Ws < 1010 Then 
          Select Case Ws 
             Case 410 To 450 
                Tastenabfrage = 1 
                Ton = 550 
             Case 340 To 380 
                Tastenabfrage = 2 
                Ton = 500 
             Case 265 To 305 
                Tastenabfrage = 3 
                Ton = 450 
             Case 180 To 220 
                Tastenabfrage = 4 
                Ton = 400 
             Case 100 To 130 
                Tastenabfrage = 5 
                Ton = 350 
          End Select 
          Sound Portd.7 , 400 , Ton                             'BEEP 
       End If 
    
    End Function 
    
    
    
    'Diese Unterfunktion zeigt Bateriespannung an 
    Sub Batteriespannung() 
    Local W As Word 
       Start Adc 
       W = Getadc(6) 
       Volt = W * Ref 
       Volt = Volt * 5.2941 
       Print "Die aktuelle Spannung beträgt: " ; Volt ; " Volt" 
    
    End Sub 
    
    
    'Testet Motoren und Geschwindigkeitsreglung 
    Sub Motortest() 
       'Linker Motor ein 
       Portc.6 = 1                                              'bestimmt Richtung 
       Portc.7 = 0                                              'bestimmt Richtung 
       Portd.4 = 1                                              'Linker Motor EIN 
    
       'Rechter Motor ein 
       Portb.0 = 1                                              'bestimmt Richtung rechter Motor 
       Portb.1 = 0                                              'bestimmt Richtung rechter Motor 
       Portd.5 = 1                                              'rechter Motor EIN 
    
    
       I = 0 
       Do 
          Pwm1a = I 
          Pwm1b = I 
          Waitms 40 
          I = I + 5 
       Loop Until I > 1023 
    
       Wait 1 
       Do 
          Pwm1a = I 
          Pwm1b = I 
          Waitms 40 
          I = I - 5 
       Loop Until I < 1 
       Pwm1a = 0                                                'Linker Motor aus 
       Pwm1b = 0                                                'rechter Motor aus 
    End Sub 
    
    
    'Einige male Lauflicht über LED´s anzeigen. Am I2C-Port darf in diesem Moment nichts angeschlossen sein 
    Sub Lauflicht() 
    
       Config Portc = Output 
       Portd = 0 
       For N = 1 To 10 
          For I = 0 To 7 
             Portc.i = 0 
             Waitms 100 
             Portc.i = 1 
          Next I 
       Next N 
       Config Portc = Input 
    End Sub 
    
    
    'Zeigt Die Analogen Messwerte An Port A An 
    Sub Showporta() 
    Local Ws As Word 
    
       Config Porta = Input 
       For I = 0 To 5                                           ' Alle internen Pullup Widerständ ein,bis auf Batteriespannungsmessungsport 
          Porta.i = 1 
       Next I 
    
       Print 
       Print "Ermittelte Messwerte an Port A:" 
       For I = 0 To 7                                           ' Alle Eingäne inkl.messen 
          Start Adc 
          Ws = Getadc(i) 
          Volt = Ws * Ref 
          Print "Pin " ; I ; " ADC-Wert= " ; Ws ; " bei 5V REF waeren das " ; Volt ; " Volt" 
       Next I 
    End Sub 
    
    
    'Zeigt den Zustand einiger freier I/OI/O von Die Analogen Messwerte An Port A An 
    Sub Showdigitalporta() 
    Local Zustand As String 
       Config Porta = Input 
       For I = 0 To 5                                           ' Alle internen Pullup Widerständ ein,bis auf Batteriespannungsmessungsport 
          Porta.i = 1 
       Next I 
    
       Print 
       Print "Ermittelter I/O Zustand Port A:" 
       For I = 0 To 5                                           ' Alle Eingäne inkl.messen 
          If Pina.i = 1 Then 
             Zustand = "High" 
          Else 
             Zustand = "Low" 
          End If 
          Print "Pin " ; I ; " I/O Zustand= " ; Pina.i ; " " ; Zustand 
       Next I 
    End Sub
    Entscheident sind dabei folgende Zeilen:
    Code:
    Config Pind.4 = Output                                      'Linker Motor PWM 
    Config Pind.5 = Output                                      'Rechter Motor PWM 
    Config Timer1 = Pwm , Pwm = 10 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down 
    Pwm1a = 0 
    Pwm1b = 0 
    Tccr1b = Tccr1b Or &H02                                     'Prescaler = 8
    Nach der oberen Konfigurationsphase kannst du also einfach PWM regeln mit:

    Pwm1a = Geschwindigkeit 0 bis 1023
    Pwm1b = Geschwindigkeit 0 bis 1023

  3. #3
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    22.07.2004
    Beiträge
    270
    Hallo,
    kannst du mit das nochmal genauer erklären? Vor allem den 2ten Code.
    Es reicht schon ein Pin oder? Und wird das dann hardwaremäßig derzeugt?

  4. #4
    Administrator Robotik Einstein Avatar von Frank
    Registriert seit
    30.10.2003
    Beiträge
    4.943
    Blog-Einträge
    1
    PWM ist immer ein gepulstes Signal das an einer Portleitung ausgegeben wird.
    In dem Beispiel wurden zwei unabhängige PWM-Signal generiert um zwei Motoren in der Geschwindigkeit steuern zu können.
    An den Port muß in dem Fall natürlich noch eine Endstufe (im einfachsten Falle Transistor) angeschlossen werden.
    Das PWM-Signal wird über einen Timer generiert, das meinst du vermutlich mit "Hardware Pwm".
    Man könnte auch einen Interrupt erzeugen und darin einen Port ein und ausschalten. Das würdest du dann vermutlich als "Software-PWM"
    bezeichnen. Im Grunde ist beides das gleiche. Die Generierung mit Timer ist nur etwas genauer und benötigt weniger Rechenleistung.
    Was PWM genau ist, dazu findest du hier im Forum schon edliche Beiträge die versuchen dies zu erklären. Nimm am besten mal die Suchfunktion.

    Kurze Erläuterung zu den Zeilen
    Diese Beiden Zeilen schalten die entsprechend duch die Hardware vorgegebene Ports auf Ausgang um
    Config Pind.4 = Output 'Linker Motor PWM
    Config Pind.5 = Output 'Rechter Motor PWM
    Hier wird der PWM-Modus konfiguriert (Syntax der Anweisung findest du in Bascom Helpdatei)
    Dabei wird 10 Bit PWM genutzt, daher kann man später Werte von 0 bis 1023 einstellen. Oft wird auch der 8 Bit Modus benutzt, dann halt nur zwischen 0 und 255
    Config Timer1 = Pwm , Pwm = 10 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down
    Ein Register das die PWM-Bitzahl festlegt
    Tccr1b = Tccr1b Or &H02
    Ausgang wird erst mal ganz runtergeregelt
    Pwm1a = 0
    Pwm1b = 0

  5. #5
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    22.07.2004
    Beiträge
    270
    Hallo,
    sry wenn ich mich dumm anstelle, aber ich finde zu PWM keine Hilfe bei Bascom. Und ich hab leider noch nicht verstanden, wie ich ein bestimmtes Signal wie z.b. 10, 15 khz etc. erzeugen kann.
    Trotzdem Danke für die Hilfe
    Gruß
    Spurius

  6. #6
    Administrator Robotik Einstein Avatar von Frank
    Registriert seit
    30.10.2003
    Beiträge
    4.943
    Blog-Einträge
    1
    Die PWM-Frequenz hat bei der normalen Steuerung von Motoren eine untergeordnete Rolle. Sie wird bestimmt durch den Teiler (Prescaler) und die Auflösung des Timers.
    Dazu musst du unbedingt das Datenblatt des Mega8 heranziehen (die Register sind bei den Megas aber fast identisch).

    Vielleicht sollten wir doch noch einen Artikel über PWM bei den Megas schreiben. Leide rfehlt mir ein wenig die Zeit zu, aber vielleicht hat jemand anders Lust.

    Ich kopiere mir als Erinnerung gerne Bitbeschreibungen der Registe rin den Sourcecode, dann wird´s übersichtlicher.
    Zum Beispiel so:

    Code:
    'PWM Frequenz Initialisieren
    Tccr1a = &B10100010                                         '9 Bit PWM
    ' Bit 7/6 =  00  COM1A1/COM1A0  Pin OC1A nicht mit T/C1 verbunden
    ' Bit 7/6 =  01  COM1A1/COM1A0  Pin OC1A nicht mit T/C1 verbunden (wenn WGM13=0)
    ' Bit 7/6 =  10  COM1A1/COM1A0  bei Übereinstimmung OC1A LO beim Aufwärtszählen und Hi beim Abwärtszählen
    ' Bit 7/6 =  11  COM1A1/COM1A0  bei Übereinstimmung OC1A Hi beim Aufwärtszählen und Lo beim Abwärtszählen
    ' Bit 5/4 =  00  COM1B1/COM1B0  Pin OC1B nicht mit T/C1 verbunden
    ' Bit 5/4 =  01  COM1B1/COM1B0  Pin OC1B nicht mit T/C1 verbunden (wenn WGM13=0)
    ' Bit 5/4 =  10  COM1B1/COM1B0  bei Übereinstimmung OC1B LO beim Aufwärtszählen und Hi beim Abwärtszählen
    ' Bit 5/4 =  11  COM1B1/COM1B0  bei Übereinstimmung OC1B Hi beim Aufwärtszählen und Lo beim Abwärtszählen
    ' Bit 3/2 =      FOC1A/FOC1B    Neue Mega Bits - Bedeutung?
    ' Bit 1/0 =  00  WGM11/WGM10    PWM nicht aktiv
    ' Bit 1/0 =  01  WGM11/WGM10    8  Bit PWM
    ' Bit 1/0 =  10  WGM11/WGM10    9  Bit PWM
    ' Bit 1/0 =  11  WGM11/WGM10    10 Bit PWM
    
    Tccr1b = &B10000001
    ' Bit 7   =    1    INCNC1  Noise Channel
    ' Bit 6   =    0    ICES1   Fallende Flanke
    ' Bit 5   =         WGM13
    ' Bit 4   =         WGM12
    ' Bit 2/1/0 =  000  CS12/CS11/CS10  Stop Timer/Counter 1
    ' Bit 2/1/0 =  001  CS12/CS11/CS10  Voller Takt
    ' Bit 2/1/0 =  010  CS12/CS11/CS10  Takt/8
    ' Bit 2/1/0 =  011  CS12/CS11/CS10  Takt/64
    ' Bit 2/1/0 =  100  CS12/CS11/CS10  Takt/256
    ' Bit 2/1/0 =  101  CS12/CS11/CS10  Takt/1024
    ' Bit 2/1/0 =  110  CS12/CS11/CS10  Externer Takt an Pin T1, fallende Flanke
    ' Bit 2/1/0 =  111  CS12/CS11/CS10  Externer Takt an Pin T1, steigende Flanke
    In der Help-Datei von Bascom findet man schon was, du mußt nach Timer suchen, dann findest du das:

    Code:
    Action
    Configure TIMER1.
     
     
    Syntax
    CONFIG  TIMER1 = COUNTER | TIMER | PWM , 
    EDGE=RISING | FALLING ,   PRESCALE= 1|8|64|256|1024 , 
    NOISE CANCEL=0 |1,  CAPTURE EDGE = RISING | FALLING , 
    CLEAR TIMER = 1|0, 
    COMPARE A = CLEAR | SET | TOGGLE I DISCONNECT  , 
    COMPARE B = CLEAR | SET | TOGGLE I DISCONNECT  , 
    PWM = 8 | 9  10 , 
    COMPARE A PWM = CLEAR UP| CLEAR DOWN | DISCONNECT 
    
    COMPARE B PWM = CLEAR UP| CLEAR DOWN | DISCONNECT 
    
    
    Remarks
    The TIMER1 is a 16 bit counter. See the hardware description of TIMER1.
    It depends on the chip if COMPARE B is available or not.
    
    
    The syntax shown above must be on one line. Not all the options need to be selected.
    
    Here is the effect of the various options.
    
    EDGE	You can select whether the TIMER will count on the falling or rising edge. Only for COUNTER mode.
    CAPTURE EDGE	You can choose to capture the TIMER registers to the INPUT CAPTURE registers
    With the CAPTURE EDGE = FALLING/RISING, you can specify to capture on the falling or rising edge of pin ICP
    NOISE CANCELING	To allow noise canceling you can provide a value of 1.
    PRESCALE	The TIMER is connected to the system clock in this case. You can select the division of the system clock with this parameter.
    Valid values are 1 , 8, 64, 256 or 1024
    The TIMER1 also has two compare registers A and B
    When the timer value matches a compare register, an action can be performed
    
    COMPARE A	The action can be:
    SET will set the OC1X pin
    CLEAR will clear the OC1X pin
    TOGGLE will toggle the OC1X pin
    DISCONNECT will disconnect the TIMER from output pin OC1X
    And the TIMER can be used in PWM mode
    You have the choice between 8, 9 or 10 bit PWM mode
    Also you can specify if the counter must count UP or down after a match
    to the compare registers
    Note that there are two compare registers A and B
    
    
    PWM	Can be 8, 9 or 10.
    COMPARE A PWM	PWM compare mode. Can be CLEAR UP or CLEAR DOWN
    Using COMPARE A, COMPARE B, COMPARE A PWM or COMPARE B PWM will set the corresponding pin for output. When this is not wanted you can use the alternative NO_OUTPUT version that will not alter the output pin.
    For example : COMPARE A NO_OUTPUT , COMPARE A PWM NO_OUTPUT
    
    Example
    '-------------------------------------------------------------------
    '                       TIMER1.BAS  for the 8515
    '-------------------------------------------------------------------
    
    Dim W As Word
    
    'The TIMER1 is a versatile 16 bit TIMER.
    'This example shows how to configure the TIMER
    
    'First like TIMER0 , it can be set to act as a TIMER or COUNTER
    'Lets configure it as a TIMER that means that it will count and that
    'the input is provided by the internal clock.
    'The internal clock can be divided by 1,8,64,256 or 1024
    Config Timer1 = Timer , Prescale = 1024
    
    
    'You can read or write to the timer with the COUNTER1 or TIMER1 variable
    W = Timer1
    Timer1 = W
    
    
    'To use it as a COUNTER, you can choose on which edge it is triggered
    Config Timer1 = Counter , Edge = Falling, , Prescale = 1024
    'Config Timer1 = Counter , Edge = Rising
    
    'Also you can choose to capture the TIMER registers to the INPUT CAPTURE registers
    'With the CAPTURE EDGE = , you can specify to capture on the falling or rising edge of pin ICP
    Config Timer1 = Counter , Edge = Falling , Capture Edge = Falling , , Prescale = 1024
    'Config Timer1 = Counter , Edge = Falling , Capture Edge = Rising
    
    'To allow noise canceling you can also provide :
    Config Timer1 = Counter , Edge = Falling , Capture Edge = Falling , Noise Cancel = 1, , Prescale = 1024
    
    'to read the input capture register :
    W = Capture1
    'to write to the capture register :
    Capture1 = W
    
    
    
    
    
    'The TIMER also has two compare registers A and B
    'When the timer value matches a compare register, an action can be performed
    Config Timer1 = Counter , Edge = Falling , Compare A = Set , Compare B =
     Toggle, , Prescale = 1
    'SET , will set the OC1X pin
    'CLEAR, will clear the OC1X pin
    'TOGGLE, will toggle the OC1X pin
    'DISCONNECT, will disconnect the TIMER from output pin OC1X
    
    
    'To read write the compare registers, you can use the COMPARE1A and COMPARE1B variables
    Compare1a = W
    W = Compare1a
    
    
    'And the TIMER can be used in PWM mode
    'You have the choice between 8,9 or 10 bit PWM mode
    'Also you can specify if the counter must count UP or down after a match
    'to the compare registers
    'Note that there are two compare registers A and B
    Config Timer1 = Pwm , Pwm = 8 , Compare A Pwm = Clear Up , Compare B Pwm = Clear Down
    
    'to set the PWM registers, just assign a value to the compare A and B registers
    Compare1a = 100
    Compare1b = 200
    
    'Or for better reading :
    Pwm1a = 100
    Pwm1b = 200
    
    End
    Bruachst du überhaupt PWM? Oder verwechselst du das mit dem normalen Timer der auch Frequenzen erzeugen kann?
    Lade dir dazu mal das Programm hier runter:

    http://www.roboternetz.de/phpBB2/dlo...le&file_id=169

    Ich glaub das könnte was für dich sein.

    Gruß Frank

  7. #7
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    22.07.2004
    Beiträge
    270
    Hallo,
    ich glaub du hast recht, ich brauch kein PWM, sondern einfach eine Timerfrquenz. Vielen Dank für die Hilfe!
    Gruß
    Spurius

  8. #8
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    22.07.2004
    Beiträge
    270
    Hallo nochmal,
    ich hab mir das Programm runtergeladen und auch Code bekommen.
    Aber verstehen tu ichs nicht, kannst du mir erklären, wie das funktioniert?
    Und was der Timervorgabewert zu bedeuten hat? Ich habe bei 36 khz den Wert 145.

  9. #9
    Gast
    Du mußt nur den Code der im unteren Fenster erzeugt wird in dein Bascom Programm kopieren und compilieren. Der Code ist eigentlich dokumentiert.
    Ansonsten empfehle ich Dir auch ein Buch
    http://www.roboternetz.de/phpBB2/viewtopic.php?t=2060

  10. #10
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    22.07.2004
    Beiträge
    270
    Das ich den Code kopieren muss ist mir schon klar, nur ich verstehe das mit der Timervorgabe nicht und wüsste gern wie die Berechnung geht.

+ Antworten
Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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