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
Druckbare Version
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
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
Entscheident sind dabei folgende Zeilen: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 "**** RN-CONTROL 1.1 *****"
Print "Das neue Experimentier- und Roboterboard"
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 "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 "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
Nach der oberen Konfigurationsphase kannst du also einfach PWM regeln mit: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
Pwm1a = Geschwindigkeit 0 bis 1023
Pwm1b = Geschwindigkeit 0 bis 1023
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?
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
Hier wird der PWM-Modus konfiguriert (Syntax der Anweisung findest du in Bascom Helpdatei)Zitat:
Config Pind.4 = Output 'Linker Motor PWM
Config Pind.5 = Output 'Rechter Motor PWM
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
Ausgang wird erst mal ganz runtergeregeltZitat:
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
Zitat:
Pwm1a = 0
Pwm1b = 0
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
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:
In der Help-Datei von Bascom findet man schon was, du mußt nach Timer suchen, dann findest du das: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
Bruachst du überhaupt PWM? Oder verwechselst du das mit dem normalen Timer der auch Frequenzen erzeugen kann?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
Lade dir dazu mal das Programm hier runter:
https://www.roboternetz.de/phpBB2/dl...le&file_id=169
Ich glaub das könnte was für dich sein.
Gruß Frank
Hallo,
ich glaub du hast recht, ich brauch kein PWM, sondern einfach eine Timerfrquenz. Vielen Dank für die Hilfe!
Gruß
Spurius
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.
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
https://www.roboternetz.de/phpBB2/viewtopic.php?t=2060
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.