PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : PWM Frequenz berechnen



Barthimaeus
02.02.2008, 12:39
In Bascom kann man einem PWM Ausgang ja nur einen Wert von 0 bis 255 übergeben. Wenn ich jedoch die genaue Frequenz des Controllers (dank Quarz) weiss müsste ich doch auch die Frequenz den PWM Ausgangs ausrechnen können - und umgekehrt. Wie geht das?
Lange Rede kurzer Sinn: Wie errechne ich bei einer AVR Frequenz von 8Mhz den Wert (0-255), den ich am PWM Ausgang einstellen muss, um eine Frequenz von 36Khz zu erhalten?

Danke für eure Hilfe

Sauerbruch
02.02.2008, 13:20
Ich nehme mal an, dass Du mit "Ausgang" das Output-Compare-Register meinst und PWM im "CTC"-Modus laufen lassen möchtest.

Für 36 KHz muss der Output-Compare-Pin alle 1/(2*36000) Sekunden getoggelt werden. Um zu wissen wie weit der Zähler in dieser Zeit zählt, musst Du nur schauen, wie oft eine Takt-Periode in diesen Zeitraum passt:

(1/72000) / (1/8000000) oder 80000000 / 72000 = 111,111... mal.

Die Formel für "andersrum" heißt: PWM-Frequenz = Quarzfrequenz / (2 * OCR). In diesem Fall also 8000000 / 222 = 36036,036 Hz. Für exakte 36 KHz bräuchtest Du ein Quarz, dessen Frequenz ein ganzzahliges Vielfaches von 36kHz ist.

sechsrad
09.02.2008, 13:45
ch nehme mal an, dass Du mit "Ausgang" das Output-Compare-Register meinst und PWM im "CTC"-Modus laufen lassen möchtest.

Für 36 KHz muss der Output-Compare-Pin alle 1/(2*36000) Sekunden getoggelt werden. Um zu wissen wie weit der Zähler in dieser Zeit zählt, musst Du nur schauen, wie oft eine Takt-Periode in diesen Zeitraum passt:

(1/72000) / (1/8000000) oder 80000000 / 72000 = 111,111... mal.

Die Formel für "andersrum" heißt: PWM-Frequenz = Quarzfrequenz / (2 * OCR). In diesem Fall also 8000000 / 222 = 36036,036 Hz. Für exakte 36 KHz bräuchtest Du ein Quarz, dessen Frequenz ein ganzzahliges Vielfaches von 36kHz ist.


sieht schon mal gut aus die lösung.

nun möchte ich das signal als ausgang nehmen für eine ir-diode bzw für das modluierte signal für den tsop mit 36khz.

beim rc5 signal ist eine 1 889µs den port auf 0 und 889µs den port mit 36khz toggeln. bei einer 0 889µs mit 36khz toggeln und 889 µs port auf 0.

vorher noch 2 startbits auf 1.

wie läuft das ganze jetzt in bascom ab, dieses rc5-signal von hand?
bei mir sendet die ir-diode nicht, bzw der tsop1736 emfängt kein signal.

wenn ich die demo von bascom nehme, läuft es, also die verbindung stimmt.



$regfile = "m32def.dat"
$framesize = 32
$swstack = 32
$hwstack = 64

Config Timer1 = Timer , Prescale = 1 , Compare A = Toggle , Capture Edge = Rising , Clear Timer = 1

Declare Sub Rc5out(adre As Byte , Command As Byte)
Declare Sub Bitlow()
Declare Sub Bithigh()

Dim Adre As Byte
Dim Command As Byte
Dim Togglebit As Byte
Dim I As Byte

Config Pind.5 = Output
Enable Interrupts
start timer1

Compare1a = 110

Adre = 0
Command = 19
Togglebit = 0

Waitms 255

Do

Call Rc5out(adre , Command)
Waitms 255

Loop

End

Sub Rc5out(adre As Byte , Command As Byte)

Call Bithigh()

Call Bithigh()

If Togglebit = 1 Then
Call Bithigh()
Else
Call Bitlow()
End If

For I = 0 To 4
If Adre.4 = 1 Then
Call Bithigh()
Else
Call Bitlow()
End If
Shift Adre , Left , 1
Next

For I = 0 To 5
If Command.5 = 1 Then
Call Bithigh()
Else
Call Bitlow()
End If
Shift Command , Left , 1
Next

End Sub

Sub Bitlow()
Ddrd.5 = 1
Waitus 889
Ddrd.5 = 0
Waitus 889
End Sub

Sub Bithigh()
Ddrd.5 = 0
Waitus 889
Ddrd.5 = 1
Waitus 889
End Sub

Sauerbruch
09.02.2008, 15:03
Warum machst Du es nicht ganz simpel mit dem Bascom-Befehl RC5SEND? Der erzeugt die 36kHz-Trägerfrequenz automatisch und gibt das fertig modulierte Signal (Togglebit, Address und Command) am OC1A-Pin aus.
Ist zwar nicht ganz so "sportlich" wie selbst programmiert, funktioniert aber zumindestens bei mir einwandfrei...

sechsrad
09.02.2008, 15:36
....Ist zwar nicht ganz so "sportlich" wie selbst programmiert, funktioniert aber zumindestens bei mir einwandfrei....

das wollte ich mal vermeiden.
mal eine neue sportart ausprobieren.
ganz möchte ich mich dem bascom nicht unterwerfen.

vielleicht hat das einer schon mal so geproggt?

stefan_Z
09.02.2008, 16:40
Such mal hier im Forum, da hat jemand ne ganze Code-Sammlung für IR reingepostet...

PicNick
09.02.2008, 18:21
@6-rad: Ich würde vermuten, daß Bascom seinen Befehls-overhead bei seinen Routinen ausgleicht, durch Einrechnen der zusätzlichen Maschinenbefehle in die Waitschleifen.
Bei 8 MHZ macht ja der AVR "nur" 8 Zyklen in einer µS und du weisst, bei Bascom kommt schon was zusammen.

sechsrad
10.02.2008, 10:31
ist denn wenigstens der grundaufbau für das toggeln mit 36khz richtig?
bzw werden die daten so am pind.5 erscheinen, wie ich das mir so denke in meinem code

also die 889µs stimmen sehr genau in bascom.
habe im avrstudio die zeit gemessen, es sind 889,13 µs die mir dort angezeigt werden.

vielleicht nimmt die sprungroutine zuviel zeit weg?oder.



Config Timer1 = Timer , Prescale = 1 , Compare A = Toggle , Capture Edge = Rising , Clear Timer = 1

Compare1a = 110

Sub Bitlow()
Ddrd.5 = 1
Waitus 889
Ddrd.5 = 0
Waitus 889
End Sub

Sub Bithigh()
Ddrd.5 = 0
Waitus 889
Ddrd.5 = 1
Waitus 889
End Sub

PicNick
10.02.2008, 12:01
Der Ablauf an sich scheint mir ja richtig.

Ich werd' deinen Code mal mit Bascom übersetzen, analysieren und gucken, was der Schlingel da alles treibt.

Ich weiss auch nicht, wie heikel das mit der Genauigkeit bei RC5 ist.
Ich weiss nur, dass es einige Überraschungen birgt, wenn man das Assembler-Bitgefummel auf die Hochsprache übertragen will

sechsrad
10.02.2008, 17:24
habe schon asm-schnippsel mit reingebracht beim rc5-senden. jetzt geht es mit dem empfängerprogramm welches im anhang ist (aus diesem forum). irgendwie muss ich jetzt noch eine asm-schleife finden für die (5bit) adresswerte und die (6bit) command-werte.

der Getrc5(address , Command) von basocm ist ein bisschen eirig, also selbst proggen ist machmal besser in bascom.
aber das selbsterstellte einleseprogramm vom rc5-code ist super , übersetzt den code fehlerfrei.




$regfile = "m32def.dat"
$framesize = 32
$swstack = 32
$hwstack = 64
$crystal = 8000000

Config Timer1 = Timer , Prescale = 1 , Compare A = Toggle , Clear Timer = 1

Declare Sub Rc5out()

Dim Adre As Byte
Dim Command As Byte
Dim Togglebit As Byte

Enable Interrupts

Compare1a = 111

Do

Adre = 13
Togglebit = 0
Command = 37
Call Rc5out()

Waitms 500

Loop

End

Sub Rc5out()
' 2x hi
!Call Bit_hi
!Call Bit_hi

' toglebit
lds r17,{togglebit}
sbrs r17,0
!call bit_lo
sbrc r17,0
!call bit_hi

' 5x adresse
lds r17,{adre}
sbrs r17,4
!call bit_lo
sbrc r17,4
!call bit_hi

sbrs r17,3
!call bit_lo
sbrc r17,3
!call bit_hi

sbrs r17,2
!call bit_lo
sbrc r17,2
!call bit_hi

sbrs r17,1
!call bit_lo
sbrc r17,1
!call bit_hi

sbrs r17,0
!call bit_lo
sbrc r17,0
!call bit_hi

' 6x command
lds r17,{command}
sbrs r17,5
!call bit_lo
sbrc r17,5
!call bit_hi

sbrs r17,4
!call bit_lo
sbrc r17,4
!call bit_hi

sbrs r17,3
!call bit_lo
sbrc r17,3
!call bit_hi

sbrs r17,2
!call bit_lo
sbrc r17,2
!call bit_hi

sbrs r17,1
!call bit_lo
sbrc r17,1
!call bit_hi

sbrs r17,0
!call bit_lo
sbrc r17,0
!call bit_hi

!Call Ende_rc5

Bit_hi:
Config Timer1 = Timer , Prescale = 1 , Compare A = Clear , Clear Timer = 1
Waitus 889
Config Timer1 = Timer , Prescale = 1 , Compare A = Toggle , Clear Timer = 1
Waitus 889
ret

Bit_lo:
Config Timer1 = Timer , Prescale = 1 , Compare A = Toggle , Clear Timer = 1
Waitus 889
Config Timer1 = Timer , Prescale = 1 , Compare A = Clear , Clear Timer = 1
Waitus 889
ret


Ende_rc5:
Config Timer1 = Timer , Prescale = 1 , Compare A = Clear , Clear Timer = 1
Waitms 50
End Sub



empfängerprogramm :


$regfile = "m32def.dat"
$framesize = 32
$swstack = 32
$hwstack = 64
$crystal = 8000000
$baud = 19200

Config Lcdpin = Pin , Db4 = Portc.2 , Db5 = Portc.3 , Db6 = Portc.4 , Db7 = Portc.5 , E = Portc.6 , Rs = Portc.7
Config Lcd = 20 * 2

Config Portd.2 = 0
Input_pin Alias Pind.2 'Pin für TSOP1736

Config Timer0 = Timer , Prescale = 8
On Timer0 Timer_irq
Const Timervorgabe = 78 'Timeraufruf alle 178µs (10 Samples = 1 Bit = 1,778ms)
Enable Timer0
Enable Interrupts

'Timing für 10 Samples Per Bit = 1,778ms
Const Samples_early = 8 'Flanke Frühestens Nach 8 Samples
Const Samples_late = 12 'Flanke Spätestens Nach 12 Samples
Const Samples_min = 3 'Flanke Vor 3 Samples - > Paket Verwerfen

'Variablen der ISR
Dim Sample As Byte 'eigentlich Bit, spart aber 46Byte ROM
Dim Ir_lastsample As Byte 'zuletzt gelesenes Sample
Dim Ir_bittimer As Byte 'zählt die Aufrufe von Timer_IRQ
Dim Ir_data_tmp As Word 'Bitstream
Dim Ir_bitcount As Byte 'Anzahl gelesener Bits


'Rückgabewerte der ISR
Dim Address_rc5 As Byte
Dim Command_rc5 As Byte
Dim Rc5_flag As Bit

Cls
Lcd "test"
Do
If Rc5_flag = 1 Then
Reset Rc5_flag
Cls
'Print "toggle:" ; Command_rc5.7;
'clear the toggle bit
Command_rc5 = Command_rc5 And &B01111111
Lcd " Adr:" ; Address_rc5 ; " Code:" ; Command_rc5
End If
'Waitms 100
Loop

End


Timer_irq:
Timer0 = Timervorgabe
Sample = Not Input_pin

'bittimer erhöhen (bleibt bei 255 stehen)
If Ir_bittimer < 255 Then Incr Ir_bittimer

'flankenwechsel erkennen
If Ir_lastsample <> Sample Then

If Ir_bittimer <= Samples_min Then
'flanke kommt zu früh: paket verwerfen
Ir_bitcount = 0
Else
'nur Flankenwechsel in Bit-Mitte berücksichtigen
If Ir_bittimer >= Samples_early Then
If Ir_bittimer <= Samples_late Then
'Bit speichern
Shift Ir_data_tmp , Left , 1
Ir_data_tmp = Ir_data_tmp + Sample
Incr Ir_bitcount
Else
'Flankenwechsel zu spät: Neuanfang mit gemessener Flanke
Ir_bitcount = 1
Ir_data_tmp = Sample
End If
'bittimer zurücksetzen wenn Timer > Samples_early
Ir_bittimer = 0
End If
End If

'Kontrolle des Startbits auf 1
If Ir_bitcount = 1 Then Ir_bitcount = Ir_data_tmp.0

'Alle 14 Bits gelesen?
If Ir_bitcount >= 14 Then
Command_rc5 = Ir_data_tmp 'Bit 6 und 7 siehe unten
Shift Ir_data_tmp , Right , 6
Address_rc5 = Ir_data_tmp And &B00011111
'For extended RC5 code, the extended bit is bit 6 of the command.
Command_rc5.6 = Not Ir_data_tmp.6
'The toggle bit is stored in bit 7 of the command
Command_rc5.7 = Ir_data_tmp.5
'Paket erfolgreich gelesen
Set Rc5_flag
'paket zurücksetzen
Ir_bitcount = 0
End If

End If
'sample im samplepuffer ablegen
Ir_lastsample = Sample

Return

sechsrad
12.02.2008, 18:15
jetzt läuft das sendeprogramm vom rc5-code super.
ist ziemlich kurz und ist mit asm-code gemischt :



$regfile = "m32def.dat"
$framesize = 32
$swstack = 32
$hwstack = 64
$crystal = 8000000

Config Timer1 = Timer , Prescale = 1 , Compare A = Toggle , Clear Timer = 1

Declare Sub Rc5out()

Dim Adre As Byte
Dim Command As Byte
Dim Togglebit As Byte
Dim Z As Byte

Enable Interrupts

Compare1a = 111

Do

For Z = 1 To 5
Adre = 20 + Z
Togglebit = 0
Command = 50 + Z
Call Rc5out()

Waitms 500
Next

Loop

End

Sub Rc5out()
!Call Bit_lo
' 2x hi
!Call Bit_hi
!Call Bit_hi

' toglebit
lds r17,{togglebit}
sbrs r17,0
!call bit_lo
sbrc r17,0
!call bit_hi

' 5x adresse
ldi r18,5
Wgloop1:
lds r17,{adre}
sbrs r17,4
!call bit_lo
sbrc r17,4
!call bit_hi
lsl r17
sts {adre},r17
dec r18
brne wgloop1

' 6x command
ldi r18,6
Wgloop2:
lds r17,{command}
sbrs r17,5
!call bit_lo
sbrc r17,5
!call bit_hi
lsl r17
sts {command},r17
dec r18
brne wgloop2

!Call Ende_rc5

Bit_hi:
Config Timer1 = Timer , Prescale = 1 , Compare A = Clear , Clear Timer = 1
Waitus 889
Config Timer1 = Timer , Prescale = 1 , Compare A = Toggle , Clear Timer = 1
Waitus 889
ret

Bit_lo:
Config Timer1 = Timer , Prescale = 1 , Compare A = Toggle , Clear Timer = 1
Waitus 889
Config Timer1 = Timer , Prescale = 1 , Compare A = Clear , Clear Timer = 1
Waitus 889
ret

Ende_rc5:
Config Timer1 = Timer , Prescale = 1 , Compare A = Clear , Clear Timer = 1
Waitms 50
End Sub