- Labornetzteil AliExpress         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 17

Thema: Mehrere Software Pwm auf einem µC

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    22.03.2005
    Beiträge
    91

    Mehrere Software Pwm auf einem µC

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hallo!

    Ich habe folgende Problematik, ich benötige 4 in der Frequenz frei skalierbare PWMs. Soweit habe ich es auch schon, der Bereich geht von 50Hz bis 250Hz. Dazu muss ich schon 2 timer verbraten (Timer0 und Timer1), weil Bascom immernoch den bug hat, das ich zumindest bei den mega 32 und mega 16 in meinem µC Programm den Prescaler nicht verändern kann...also man kann schon wie es sich gehört, alles programmieren, aber der µC ändert später nichts. Das muss ich nochmals an Mark schreiben. Wenn das nicht bald behoben wird muss ich Bascom in Rente schicken...

    So nun zur eigentlichen Frage die momentan 4 synchron laufenden PWM Ausgänge meiner Sofr-PWM, sollen nun um unterschiedliche Verzögerungszeiten zu Kanal 1 laufen. Jeweils alle mit der selben Frequenz und Tastverhältnis, nur halt versetzt. Mit 5 Timern wüsste ich, wie man dem Ganzen beikommen könnte, aber mit den Voraussetzungen auf dem Chip hm...ehrlichgesagt, keine Ahnung.

    Eine etwas aufwändiger Methode schwirrt mir noch im Kopf herum, einen Master mit 4 Slaves aufzubauen, der dann die anderen µC synchronisiert, oder halt versetzt startet und über SPI mit Daten versorgt... Ist halt ne Menge zum Aufbauen, weshalb ich das ganz gerne in einem Chip unterbringen würde.

    Mal gespannt auf eure Ideen und Anregungen.

    Gruß

    Sven

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    22.05.2005
    Ort
    12°29´ O, 48°38´ N
    Beiträge
    2.731
    Hallo,
    theoretisch reicht doch ein Timer, diesen z.B. alle 0,1ms takten (oder wie genau die Auflösung sein soll), und dann muss man nur pro SoftPWM mitzählen, wann man einen Ausgang auf high und low setzen muss.

    Was ist das Problem mit dem Prescaler, ich weiss zwar jetzt nichts von dem Bascom-Fehler, aber Du weisst, das es nur einen Prescaler für die Timer gibt, bzw. ein Prescaler ist für mehrere Timer ?!
    Timer0 und 1 verwenden den gleichen Prescaler, nur Timer2 hat einen eigenen Prescaler.

  3. #3
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    09.08.2004
    Ort
    Potsdam
    Beiträge
    190

    Re: Mehrere Software Pwm auf einem µC

    Zitat Zitat von ACsenf
    ...weil Bascom immernoch den bug hat, das ich (...) den Prescaler nicht verändern kann...also man kann schon wie es sich gehört, alles programmieren, aber der µC ändert später nichts. Das muss ich nochmals an Mark schreiben. Wenn das nicht bald behoben wird muss ich Bascom in Rente schicken...
    Dann solltest Du Schnarchnase mal nen Blick in die Bedienungsanleitungen der Controller werfen!
    Der Mega32 und Mega16 bieten bei Timer0 und Timer1 nur folgende Prescale-Möglichkeiten: 0,8,64,256 und 1024
    Die 16-Bit Timer hängen an diesem Prescaler mit dran wenn ich es richtig verstanden hab.
    Bascom hat in diesem Zusammenhang wohl doch keinen Bug.

    Ich würd an Deiner Stelle vier Slaves (Tiny 13 oder sowas in der Richtung) nehmen die durch den Master Synchronisiert werden. Mit einem Controller wird das, durch die fehlende Möglichkeit Variablen parallel zu bearbeiten, nicht sauber funktionieren.

  4. #4
    Benutzer Stammmitglied
    Registriert seit
    22.03.2005
    Beiträge
    91
    Hallo E-Nase

    Das mit dem Prescaler ist mir schon bekannt, ebenso die verfügbaren Auflösungen! Und wenn man mit dem 16 Bit kleinere, wie auch größere Frequenzen erzeugen möchte, muss ich eben diesen Prescaler in meiner Software in einer If Verzweigung von z.B. 8 auf 64 umschalten, was beim 8515 einwandfrei klappt, aber eben bei diesen beiden Megas tut der Compiler nicht das richtige! Dieser Bug wurde hier auch schonmal erwähnt! Probiere es mal aus und schreibe ein Proggi, das zwei Prescalerwerten umschalten muss und dann messe mal mit einem Oszi ob das was du vorausberechnet hast auch mit der Realität übereinstimmt.
    Bei klappt das jedenfalls nicht. Die idee mit den Slaves werde ich vermutlich auch umsetzen um in "Echtzeit" synchronisieren zu können.

    Ich krame mal meinen Code raus mit dem es nicht ging, geht.

    Gruß

    Sven

  5. #5
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    09.08.2004
    Ort
    Potsdam
    Beiträge
    190
    hmmm...
    Haste die Chose schon mal alleine im Controller ausgetestet? Also ohne dat andere Codegedöns und nur die Umschaltung der Prescalerwerte?

  6. #6
    Benutzer Stammmitglied
    Registriert seit
    22.03.2005
    Beiträge
    91
    So hier ist mein code mit den Timern, wo sich der Prescalerwert nicht ändert! Der Compiler setzt alles ohne zu murren um, aber ab 29Hz kommt nur noch Mist heraus.

    Code:
    '*******************************************************************************
    'Frequenzgenerator
    'Prozessor: Atmel Mega 32
    'Programm: Test_Prescaler verändern
    '*******************************************************************************
    '$sim
    $regfile = "M32DEF.DAT"
    $crystal = 16000000
    $baud = 9600
    
    '-----------------------------Variablendeklaration--------------------------------
    Dim Rel_flag As Bit
    Dim S As String * 10
    
    '------------------------Variablen zur Frequenzberechnung-------------------------
    Dim F As Single
    Dim Fein As Single
    Dim Fcalc As Single
    Dim Check As Single
    Dim Calc As Single
    Dim Pre As Integer                                          'Prescaler
    Dim Presc As Integer                                        'Prescaler Uebergabewert
    Dim Vorteiler As Long                                       'Prescaler berechnet
    Dim Reload1 As Word
    Dim Count0 As Byte
    Dim Count1 As Byte
    Const Fosc = 16000000                                       'Frequenz µC
    Const Aufl = 65536                                          'Timeraufloesung
    Dim T As Single                                             'Periode
    Declare Sub Aus
    Declare Sub Neue_frequenz
    Declare Sub Reloadsub
    
    '-----------------------------Portkonfiguration-----------------------------------
    
    'Der PortC wird als Ausgang programmiert
    Config Pinc.0 = Output
    Config Pinc.1 = Output
    Config Pinc.2 = Output
    Config Pinc.3 = Output
    Config Pinc.4 = Output
    Config Pinc.5 = Output
    Config Pinc.6 = Output
    Config Pinc.7 = Output
    Config Pina.7 = Output
    Config Pina.6 = Output
    Config Pina.5 = Output
    Config Pina.4 = Output
    
    'Der Port B und D wird als Eingang programmiert
    Config Pinb.0 = Input
    Config Pinb.1 = Input
    Config Pinb.2 = Input                                       ' Interrupt 2 für Zuendung Slave IN sync
    Config Pinb.3 = Input
    Config Pinb.4 = Input
    Config Pinb.5 = Input
    Config Pinb.6 = Input
    Config Pinb.7 = Input
    Config Pind.2 = Input                                       ' Interrupt 0 für ON/OFF
    Config Pind.3 = Input                                       'Interrupt 1 Sammelinterrupt Stoerung
    Config Pind.4 = Input
    Config Pind.5 = Input
    Config Pind.6 = Input
    Config Pind.7 = Input
    
    'Pullup einschalten nur bei PD3 noetig!
    Portd.3 = 1
    
    'Hier geben wir der Definition einen schoeneren Namen
    _out Alias Portc.0
    Sync Alias Portc.1
    _rdy Alias Portc.2
    Reserve_out Alias Portc.3
    Stoerung_out Alias Portc.4
    Outp Alias Portc.5
    Led1 Alias Portc.6
    Led2 Alias Portc.7
    Led3 Alias Porta.7
    Led4 Alias Porta.6
    Ok Alias Porta.5
    Relais Alias Porta.4
    
    '-----------------------------Timerkonfiguration----------------------------------
    'Hier wird der Timer und der Teiler festgelegt
    Config Timer0 = Timer , Prescale = 64
    Config Timer1 = Timer , Prescale = 8
    
    'Hier wird das Unterprogramm festgelegt, das
    'in dem eingestellten Intervall aufgerufen wird
    On Timer0 Timer0_irq                                        'Nosave
    On Timer1 Timer1_irq                                        'Nosave
    
    Const Reload0 = 6
    Reload1 = 30534
    
    'Hier werden die Timer aktiviert
    Enable Timer0
    Enable Timer1
    Enable Interrupts
    
    
    Call Aus
    Start Timer1
    
    Do
      If Ischarwaiting() <> 0 Then Call Neue_frequenz
       nop
    Loop
    
    Timer0_irq:                                                 '1 Pausenteil 1ms
      Timer0 = Reload0
        Outp = 0                                                'EIN
        Stop Timer0
        Waitus 500
        Outp = 1                                                'AUS
        Waitus 1000                                             '2.Pausenteil 1ms
        Led1 = 0
        Start Timer1
    
       Return
    
    
    Timer1_irq:                                                 'lange Zeit 17,5ms
        Timer1 = Reload1
        Led1 = 1
        Stop Timer1
        Start Timer0
       Return
    
    '----------------------------Funktion Ausschalten---------------------------------
    
    Sub Aus
    
    Portc = &HFF                                                ' alle LEDs aus
    Led1 = 1
    Led2 = 1
    Led3 = 1                                                    ' alle LEDs aus
    Led4 = 1                                                    ' alle LEDs aus
    Ok = 1
    Outp = 1                                                    ' alle LEDs aus
    Waitms 200
    
      If Rel_flag = 0 Then
          Relais = 1                                            ' alle LEDs aus
      End If
    
    End Sub
    
    '--------------------------Funktion Frequenzberechnung----------------------------
    Sub Neue_frequenz
     Stop Timer0
     Stop Timer1
     Waitms 200
    
     Call Aus
     S = Inkey()
     Print "Frequenz ohne dezimale eingeben, d.h 500 entspricht 50Hz"
     Eingabe:
     Input " neue Frequenz: " , Fein
    
     If Fein > 500 Then
       Print "Fequenz zu Gross!!!"
       Goto Eingabe
     End If
        F = Fein / 10
        Check = Frac(f)                                         'nur Nachkommastelle
     If Check = 0.5 Or Check = 0 Then
       Print " neue Frequenz: " ; F ; "Hz"
     Else
       Print "falsche Eingabe! Nur 0,5Hz Schritte moeglich!"
       Goto Eingabe
     End If
    
     T = 1 / F
     T = T - 0.0025
     Fcalc = 1 / T
     Vorteiler = T * Fosc
     Vorteiler = Vorteiler \ Aufl
    
     If Vorteiler <= 1 Then
         Pre = 1
         Presc = Pre
         Call Reloadsub
         Reload1 = Round(calc)
     End If
    
     If Vorteiler > 1 And Vorteiler <= 8 Then
         Pre = 8
         Presc = Pre
         Call Reloadsub
         Reload1 = Round(calc)
     End If
    
     If Vorteiler > 8 And Vorteiler <= 64 Then
         Pre = 64
         Presc = Pre                                            'Prescaler
         Call Reloadsub
         Reload1 = Round(calc)
     End If
    
     If Vorteiler > 64 And Vorteiler <= 256 Then
         Pre = 256
         Presc = Pre                                            'Prescaler
         Call Reloadsub
         Reload1 = Round(calc)
     End If
    
     If Vorteiler > 256 And Vorteiler <= 1024 Then
         Pre = 1024
         Presc = Pre                                            'Prescaler
         Call Reloadsub
         Reload1 = Round(calc)
     End If
    
    
     Start Timer1
    End Sub
    
    Sub Reloadsub
    'Berechnung von Reload1
     Calc = Fosc / Pre
     Calc = Calc / Fcalc
     Calc = Aufl - Calc
     Tccr1b = Tccr1b And &HF8
     Tccr1b = Tccr1b Or Presc
    
    End Sub

  7. #7
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    09.08.2004
    Ort
    Potsdam
    Beiträge
    190

    Wenn ich es richtig sehe müllst Du durch diese Art der Prescalerumstellung nur das Kontrollregister B des Timer1 zu und schreibst schon beim ersten Umstellem &hFF da rein (weil &h08 AND &hF8 = &hFF). Das kann nicht funktionieren weil Du damit den Timer1des ATmega32 auf externe Synchronisation umstellst.
    Anbei mal ein Screenshot der Registerbitbelegung von TCCR1B:
    Die Bits sollten daher anders manipuliert werden.
    Miniaturansichten angehängter Grafiken Miniaturansichten angehängter Grafiken tccr1b_bitbelegung.jpg  

  8. #8
    Benutzer Stammmitglied
    Registriert seit
    22.03.2005
    Beiträge
    91
    Ah gut zu wissen! Hm man sollte nicht alles glauben was man hier so geraten bekommt. Hatte diese Version halt versucht. Hatte vorher dem Prescaler eine Zahl zugewiesen, wie bei der ersten Initializiereung, das ging aber auch nicht.
    Nun die große Frage...wie geht dem???

    so habe es mal geändert:

    Code:
    '*******************************************************************************
    'Frequenzgenerator
    'Prozessor: Atmel Mega 32
    'Programm: Test_Prescaler verändern
    '*******************************************************************************
    '$sim
    $regfile = "M32DEF.DAT"
    $crystal = 16000000
    $baud = 9600
    
    '-----------------------------Variablendeklaration--------------------------------
    Dim Rel_flag As Bit
    Dim S As String * 10
    
    '------------------------Variablen zur Frequenzberechnung-------------------------
    Dim F As Single
    Dim Fein As Single
    Dim Fcalc As Single
    Dim Check As Single
    Dim Calc As Single
    Dim Pre As Integer                                          'Prescaler
    Dim Presc As Byte                                           'Prescaler Uebergabewert
    Dim Vorteiler As Long                                       'Prescaler berechnet
    Dim Reload1 As Word
    Dim Count0 As Byte
    Dim Count1 As Byte
    Const Fosc = 16000000                                       'Frequenz µC
    Const Aufl = 65536                                          'Timeraufloesung
    Dim T As Single                                             'Periode
    Declare Sub Aus
    Declare Sub Neue_frequenz
    Declare Sub Reloadsub
    
    '-----------------------------Portkonfiguration-----------------------------------
    
    'Der PortC wird als Ausgang programmiert
    Config Pinc.0 = Output
    Config Pinc.1 = Output
    Config Pinc.2 = Output
    Config Pinc.3 = Output
    Config Pinc.4 = Output
    Config Pinc.5 = Output
    Config Pinc.6 = Output
    Config Pinc.7 = Output
    Config Pina.7 = Output
    Config Pina.6 = Output
    Config Pina.5 = Output
    Config Pina.4 = Output
    
    'Der Port B und D wird als Eingang programmiert
    Config Pinb.0 = Input
    Config Pinb.1 = Input
    Config Pinb.2 = Input                                       ' Interrupt 2 für Zuendung Slave IN sync
    Config Pinb.3 = Input
    Config Pinb.4 = Input
    Config Pinb.5 = Input
    Config Pinb.6 = Input
    Config Pinb.7 = Input
    Config Pind.2 = Input                                       ' Interrupt 0 für ON/OFF
    Config Pind.3 = Input                                       'Interrupt 1 Sammelinterrupt Stoerung
    Config Pind.4 = Input
    Config Pind.5 = Input
    Config Pind.6 = Input
    Config Pind.7 = Input
    
    'Pullup einschalten nur bei PD3 noetig!
    Portd.3 = 1
    
    'Hier geben wir der Definition einen schoeneren Namen
    _out Alias Portc.0
    Sync Alias Portc.1
    _rdy Alias Portc.2
    Reserve_out Alias Portc.3
    Stoerung_out Alias Portc.4
    Outp Alias Portc.5
    Led1 Alias Portc.6
    Led2 Alias Portc.7
    Led3 Alias Porta.7
    Led4 Alias Porta.6
    Ok Alias Porta.5
    Relais Alias Porta.4
    
    '-----------------------------Timerkonfiguration----------------------------------
    'Hier wird der Timer und der Teiler festgelegt
    Config Timer0 = Timer , Prescale = 64
    Config Timer1 = Timer , Prescale = 8
    
    'Hier wird das Unterprogramm festgelegt, das
    'in dem eingestellten Intervall aufgerufen wird
    On Timer0 Timer0_irq                                        'Nosave
    On Timer1 Timer1_irq                                        'Nosave
    
    Const Reload0 = 6
    Reload1 = 30534
    
    'Hier werden die Timer aktiviert
    Enable Timer0
    Enable Timer1
    Enable Interrupts
    
    
    Call Aus
    Start Timer1
    
    Do
      If Ischarwaiting() <> 0 Then Call Neue_frequenz
       nop
    Loop
    
    Timer0_irq:                                                 '1 Pausenteil 1ms
      Timer0 = Reload0
        Outp = 0                                                'EIN
        Stop Timer0
        Waitus 500
        Outp = 1                                                'AUS
        Waitus 1000                                             '2.Pausenteil 1ms
        Led1 = 0
        Start Timer1
    
       Return
    
    
    Timer1_irq:                                                 'lange Zeit 17,5ms
        Timer1 = Reload1
        Led1 = 1
        Stop Timer1
        Start Timer0
       Return
    
    '----------------------------Funktion Ausschalten---------------------------------
    
    Sub Aus
    
    Portc = &HFF                                                ' alle LEDs aus
    Led1 = 1
    Led2 = 1
    Led3 = 1                                                    ' alle LEDs aus
    Led4 = 1                                                    ' alle LEDs aus
    Ok = 1
    Outp = 1                                                    ' alle LEDs aus
    Waitms 200
    
      If Rel_flag = 0 Then
          Relais = 1                                            ' alle LEDs aus
      End If
    
    End Sub
    
    '--------------------------Funktion Frequenzberechnung----------------------------
    Sub Neue_frequenz
     Stop Timer0
     Stop Timer1
     Waitms 200
    
     Call Aus
     S = Inkey()
     Print "Frequenz ohne dezimale eingeben, d.h 500 entspricht 50Hz"
     Eingabe:
     Input " neue Frequenz: " , Fein
    
     If Fein > 500 Then
       Print "Fequenz zu Gross!!!"
       Goto Eingabe
     End If
        F = Fein / 10
        Check = Frac(f)                                         'nur Nachkommastelle
     If Check = 0.5 Or Check = 0 Then
       Print " neue Frequenz: " ; F ; "Hz"
     Else
       Print "falsche Eingabe! Nur 0,5Hz Schritte moeglich!"
       Goto Eingabe
     End If
    
     T = 1 / F
     T = T - 0.0025
     Fcalc = 1 / T
     Vorteiler = T * Fosc
     Vorteiler = Vorteiler \ Aufl
    
     If Vorteiler <= 1 Then
         Pre = 1
         Presc = &B00000001
         Call Reloadsub
         Reload1 = Round(calc)
     End If
    
     If Vorteiler > 1 And Vorteiler <= 8 Then
         Pre = 8
         Presc = &B00000010
         Call Reloadsub
         Reload1 = Round(calc)
     End If
    
     If Vorteiler > 8 And Vorteiler <= 64 Then
         Pre = 64
         Presc = &B00000011                                     'Prescaler
         Call Reloadsub
         Reload1 = Round(calc)
     End If
    
     If Vorteiler > 64 And Vorteiler <= 256 Then
         Pre = 256
         Presc = &B00000100                                     'Prescaler
         Call Reloadsub
         Reload1 = Round(calc)
     End If
    
     If Vorteiler > 256 And Vorteiler <= 1024 Then
         Pre = 1024
         Presc = &B00000101                                     'Prescaler
         Call Reloadsub
         Reload1 = Round(calc)
     End If
    
    
     Start Timer1
    End Sub
    
    Sub Reloadsub
    'Berechnung von Reload1
     Calc = Fosc / Pre
     Calc = Calc / Fcalc
     Calc = Aufl - Calc
     'Tccr1b = Tccr1b And &HF8
     Tccr1b = Presc
    
    End Sub
    geht aber trotzdem nicht!

    Bleibe bei dem hier schonmal erwähnten...daß Bascom da einen Bug hat, lasse mich aber gerne eines Besseren belehren.

    Gruß

    Sven

  9. #9
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    22.12.2004
    Alter
    70
    Beiträge
    277
    Zitat Zitat von ACsenf
    Bleibe bei dem hier schonmal erwähnten...daß Bascom da einen Bug hat, lasse mich aber gerne eines Besseren belehren.
    Den Fehler der nichtangenommenen Veränderung des Prescalers gab es tatsächlich mal bei einer Version, ist aber schon länger behoben.

    Das dies stimmt, kann man leich anhand dieses völlig fehlerfrei funktionierenden Testprogrammes überprüfen (habe jetzt nicht forenfreundlich gekürzt):

    Code:
    'Frequenzgenerator Atmega 8/168 oder M32 mit Menue - HR -  2006
    '#######################################################
    
    '$regfile = "m8def.dat"
    '$regfile = "m168def.dat"
    $regfile = "m32def.dat"
    $crystal = 7372800
    '$crystal = 14745000
    '$crystal = 16000000
    
    $baud = 9600
    
    $hwstack = 64
    $swstack = 64
    $framesize = 64
    
    
    
    '$lib "i2c_twi.lbx"                           'Hardware I2C!
    
    'Config Lcdpin = Pin , Db4 = Pd.4 , Db5 = Pd.5 , Db6 = Pd.6 , Db7 = Pd.7 , _
    'E = Pd.3 , Rs = Pd.2
    '
    'Config Scl = Portc.5           'für Mega8 und 168
    'Config Sda = Portc.4
    
    'Config Scl = Portd.0           'für Mega16 und 32
    'Config Sda = Portd.1
    
    '-------------------------------------------------------------------------------
    $lib "Lcd_i2c.lib"                           'i2c Treiber für das LCD
    Dim _lcd_e As Byte                           'Nötig für die Enable Auswahl
    'Const Pcf8574_lcd = 112                      'Adresse des LCD-PCF
    'Const Pcf8574_lcd = 64
    Waitms 200
    _lcd_e = 128                                 'Für LCDs mit 1 Controller
    
    'Config Scl = Portc.5                         'für Mega8 und 168
    'Config Sda = Portc.4
    Config Scl = Portc.0                         'für Mega16 und 32
    Config Sda = Portc.1
    
    
    I2cinit                                      'I2C Initialisierung
    '-------------------------------------------------------------------------------
    Config Lcd = 16 * 2
    Config Adc = Single , Prescaler = Auto       'Für Analogtastatur
    
    
    'Config Portd.4 = Output                      'Test LED-Port
    
    'Config Pina.0 = Input                        'Für analog_key
    'Keyboard Alias Pina.0                        'Aliasname
    'Porta.0 = 1                                  'Pullup Widerstand ein
    
    '-------------------------------------------------------------------------------
    Const Pcf8591 = 144                          'DA-AD-Wandler auf Basis
    Const Eeprom2 = 166                          'Eeprom2 auf Basis
    Const Eeprom1 = 174                          'Eeprom1 oder Ram auf Basis
    Const Eeprom0 = 160                          'externes Chip Card Eeprom0
    Const Pcf8574_1 = 64                         'Portext. auf Basis
    Const Tda8444 = 78                           'DA-Wandler auf Extension-Platine
    Const Pcf8574_lcd = 112                      'Portextension für LCD
    Const Pcf8583_rtc = 162                      'RTC auf Extension-Platine
    
    Const Max520 = 94                            'für MAX520 (extern)
    Const Keyboard = 0                           'ADC-Nr.
    
    Config Timer1 = Timer , Prescale = 8
    Stop Timer1
    On Timer1 Timer_irq Nosave
    
    Enable Timer1
    Enable Interrupts                            'Interrupts erlauben
    
    
    
    Config Adc = Single , Prescaler = Auto
    Config Pinb.1 = Output
    
    
    
    Config Pinb.4 = Input                        'Für Frequenzzählung
    Portb.4 = 1                                  'Pullup Widerstand ein
    Flow_in Alias Pinb.4
    
    Config Pinc.2 = Output                       'Ausgang  für beeper
    Beep Alias Portc.2
    
    Config Pinb.0 = Output                       'Ausgang  für Frequenz
    
    Declare Sub Beep_alarm()
    Declare Sub Beep_confirm()
    Declare Sub Analog_key_wait()                'Resultat in Taste
    
    Declare Function Analog_key() As Byte
    Declare Function Adjust_value_
    (byval Up_down As Word , Byval Schritt As Byte)as Word
    
    Declare Function Timer_test() As Word
    
    Dim Timervorgabe As Word
    'Timervorgabe = 19456                         'für 20Hz bzw 10 Hz an PB0
    'Timervorgabe = 34816                         'für 30Hz bzw 15 Hz an PB0
    Timervorgabe = 56320                         'für 100Hz bzw 50 Hz an PB0
    
    Dim Value As Word At &H100
    Dim Value_low As Byte At &H100 Overlay
    Dim Value_high As Byte At &H101 Overlay
    Dim Address As Word At &H102
    Dim Address_low As Byte At &H102 Overlay
    Dim Address_high As Byte At &H103 Overlay
    
    
    Dim I As Integer
    Dim N As Integer
    Dim Hertz_word As Word
    Dim Count As Byte
    Dim Temp As Word
    Dim Schritt As Byte
    
    Dim Command As Byte
    Dim Taste As Byte
    Dim Counter_ds As Word
    
    
    Dim Menue_current As Byte
    Dim Wert As Byte
    
    '-------------------------------------------------------------------------------
    
    Call Beep_alarm()                            'Bin wach -)
    Cls
    Cursor Off
    Lcd "  FREQUENZGEN."
    'Locate 2 , 1
    'Lcd " MEGA8 - Control"
    Wait 3
    Start Timer1
    '------------------------------------------------------------------------------
    Beep_confirm
    Cls
    Menue:
    Menue_current = 1
    
    Menue_1:
    
    Taste = Analog_key()
    Waitms 100
    
    If Taste = 32 Then
    Menue_current = Menue_current + 1
    End If
    
    If Taste = 33 Then
    Menue_current = Menue_current - 1
    End If
    
    If Menue_current > 8 Then Menue_current = 1
    If Menue_current < 1 Then Menue_current = 8
    
    If Taste = 10 Then Goto Execute
    '-------------------------------------------------------------------------------
    Select Case Menue_current                    'aktuelle Auswahl anzeigen
    
       Case 1
        Locate 1 , 1
        Lcd " 10 Hz          "
       Case 2
        Locate 1 , 1
        Lcd " 50 Hz          "
       Case 3
        Locate 1 , 1
        Lcd " 100 Hz         "
       Case 4
        Locate 1 , 1
        Lcd " 1 kHz          "
       Case 5
        Locate 1 , 1
        Lcd " 10 kHz         "
       Case 6
        Locate 1 , 1
        Lcd " 20 kHz         "
       Case 7
        Locate 1 , 1
        Lcd " 50 kHz         "
       Case 8
        Locate 1 , 1
        Lcd " FREE           "
    
    
    
    End Select
        Taste = 255
    Goto Menue_1
    
    '-------------------------------------------------------------------------------
    Execute:                                     'aktuellen Menuepunkt ausführen
    Cls
    
    Select Case Menue_current
       Case 1
              Cls
              Disable Timer1
              Config Timer1 = Timer , Prescale = 8
              Timervorgabe = 19456               'für 20 bzw. 10 Hz
              Enable Timer1
    
       Case 2
              Cls
              Disable Timer1
              Config Timer1 = Timer , Prescale = 8
              Timervorgabe = 56320               'für 100 bzw. 50 Hz
              Enable Timer1
              Cls
       Case 3
              Cls
              Disable Timer1
              Config Timer1 = Timer , Prescale = 1
              Timervorgabe = 28672               'für 200 bzw. 100 Hz
              Enable Timer1
              Cls
       Case 4
              Cls
              Disable Timer1
              Config Timer1 = Timer , Prescale = 1
              Timervorgabe = 61850 + 32          'für 2000 bzw. 1000 Hz
              Enable Timer1
              Cls
       Case 5
              Cls
              Disable Timer1
              Config Timer1 = Timer , Prescale = 1
              Timervorgabe = 65167 + 32          'für 20000 bzw. 10000 Hz
              Enable Timer1
              Cls
       Case 6
              Cls
              Disable Timer1
              Config Timer1 = Timer , Prescale = 1
              Timervorgabe = 65352 + 32          'für 40000 bzw. 20000 Hz
              Enable Timer1
              Cls
       Case 7
              Cls
              Disable Timer1
              Config Timer1 = Timer , Prescale = 1
              Timervorgabe = 65462 + 32          'für 100kHz bzw. 50kHz  bei Toggle
              Enable Timer1
              Cls
      Case 8
              Cls                                'zur Ermittlung der maximal
              Locate 2 , 2                       'erziebaren Frequenz
              Lcd " free running"
              Disable Timer1
              Do
              Set Portb.0
              nop
              nop
              Reset Portb.0
              nop
              nop
              Loop
              Enable Timer1
    
    
    
    End Select
    
    Goto Menue_1
    '-------------------------------------------------------------------------------
    
    End                                          'Hauptprogramm Ende
    
    '-------------------------------------------------------------------------------
    
    
    '-------------------------------------------------------------------------------
    
    
    Sub Beep_alarm()
              Sound Beep , 200 , 450
              Sound Beep , 200 , 250
    End Sub
    '-------------------------------------------------------------------------------
    
    Sub Beep_confirm()
              Sound Beep , 200 , 450
    End Sub
    '-------------------------------------------------------------------------------
    
    Sub Analog_key_wait()
    Wait_ana_key:
    Taste = Analog_key()
    If Taste = 255 Then Goto Wait_ana_key
    End Sub
    
    '------------------------------------------------------------------------------
    'Diese Unterfunktion fragt die Tastatur am analogen Port ab
    Function Analog_key() As Byte
       Local Ws As Word
       Analog_key = 255
       Start Adc
       Ws = Getadc(keyboard)
       If Ws < 900 Then
          Select Case Ws
             Case 0 To 100
                Analog_key = 32
             Case 400 To 600
                Analog_key = 33
             Case 650 To 850
                Analog_key = 10
          End Select
          Call Beep_confirm()
       End If
    Waitms 100
    End Function
    '-------------------------------------------------------------------------------
    
    Function Adjust_value(byval Up_down As Word , Byval Schritt As Byte)
    
    Cls
    
    Adj1:
    Locate 2 , 1
    Lcd Up_down ; "  "
    Taste = Analog_key()
    If Taste = 32 Then Up_down = Up_down + Schritt
    If Taste = 33 Then Up_down = Up_down - Schritt
    If Taste = 10 Then
       Adjust_value = Up_down
       Exit Sub
    End If
    
    Goto Adj1
    
    End Function
    '-------------------------------------------------------------------------------
    Timer_irq:
    
    $asm
    push R24
    push R25
    push R26
    push R27
    push XH
    push XL
    in R24, SREG
    push R24
    $end Asm
    Timer1 = Timervorgabe
    Toggle Portb.0
    $asm
    pop R24
    Out Sreg , R24
    pop XL
    pop XH
    pop R27
    pop R26
    pop R25
    pop R24
    $end Asm
    
    
    Return
    '-------------------------------------------------------------------------------
    Das Beispiel ist mit Absicht "Klein Fritzchen mäßig" strukturiert.

    Grüße
    Henrik

  10. #10
    Benutzer Stammmitglied
    Registriert seit
    22.03.2005
    Beiträge
    91
    Hallo!

    Hier nochmal mein Code zu deinem Beispiel, so hatte ich es übrigens auch schonmal und funktioniert bei meinem 8515 wunderbar!
    Habe es eben extra nochmal durch den Simulator gejagt. Da kann man schön sehen, daß die Berechnungen richtig sind und sogar das Register korrekt gesetzt wird. Aber in Realität passiert eben genau das nicht!

    Anbei nochmal mein Code

    Code:
    '*******************************************************************************
    'Frequenzgenerator
    'Prozessor: Atmel Mega 32
    'Programm: Test_Prescaler verändern
    '*******************************************************************************
    '$sim
    $regfile = "M32DEF.DAT"
    $crystal = 16000000
    $baud = 9600
    
    '-----------------------------Variablendeklaration--------------------------------
    Dim Rel_flag As Bit
    Dim S As String * 10
    
    '------------------------Variablen zur Frequenzberechnung-------------------------
    Dim F As Single
    Dim Fein As Single
    Dim Fcalc As Single
    Dim Check As Single
    Dim Calc As Single
    Dim Pre As Integer                                          'Prescaler
    Dim Presc As Byte                                           'Prescaler Uebergabewert
    Dim Vorteiler As Long                                       'Prescaler berechnet
    Dim Reload1 As Word
    Dim Count0 As Byte
    Dim Count1 As Byte
    Const Fosc = 16000000                                       'Frequenz µC
    Const Aufl = 65536                                          'Timeraufloesung
    Dim T As Single                                             'Periode
    Declare Sub Aus
    Declare Sub Neue_frequenz
    Declare Sub Reloadsub
    
    '-----------------------------Portkonfiguration-----------------------------------
    
    'Der PortC wird als Ausgang programmiert
    Config Pinc.0 = Output
    Config Pinc.1 = Output
    Config Pinc.2 = Output
    Config Pinc.3 = Output
    Config Pinc.4 = Output
    Config Pinc.5 = Output
    Config Pinc.6 = Output
    Config Pinc.7 = Output
    Config Pina.7 = Output
    Config Pina.6 = Output
    Config Pina.5 = Output
    Config Pina.4 = Output
    
    'Der Port B und D wird als Eingang programmiert
    Config Pinb.0 = Input
    Config Pinb.1 = Input
    Config Pinb.2 = Input                                       ' Interrupt 2 für Zuendung Slave IN sync
    Config Pinb.3 = Input
    Config Pinb.4 = Input
    Config Pinb.5 = Input
    Config Pinb.6 = Input
    Config Pinb.7 = Input
    Config Pind.2 = Input                                       ' Interrupt 0 für ON/OFF
    Config Pind.3 = Input                                       'Interrupt 1 Sammelinterrupt Stoerung
    Config Pind.4 = Input
    Config Pind.5 = Input
    Config Pind.6 = Input
    Config Pind.7 = Input
    
    'Pullup einschalten nur bei PD3 noetig!
    Portd.3 = 1
    
    'Hier geben wir der Definition einen schoeneren Namen
    _out Alias Portc.0
    Sync Alias Portc.1
    _rdy Alias Portc.2
    Reserve_out Alias Portc.3
    Stoerung_out Alias Portc.4
    Outp Alias Portc.5
    Led1 Alias Portc.6
    Led2 Alias Portc.7
    Led3 Alias Porta.7
    Led4 Alias Porta.6
    Ok Alias Porta.5
    Relais Alias Porta.4
    
    '-----------------------------Timerkonfiguration----------------------------------
    'Hier wird der Timer und der Teiler festgelegt
    Config Timer0 = Timer , Prescale = 64
    Config Timer1 = Timer , Prescale = 8
    
    'Hier wird das Unterprogramm festgelegt, das
    'in dem eingestellten Intervall aufgerufen wird
    On Timer0 Timer0_irq                                        'Nosave
    On Timer1 Timer1_irq                                        'Nosave
    
    Const Reload0 = 6
    Reload1 = 30534
    
    'Hier werden die Timer aktiviert
    Enable Timer0
    Enable Timer1
    Enable Interrupts
    
    
    Call Aus
    Start Timer1
    
    Do
      If Ischarwaiting() <> 0 Then Call Neue_frequenz
       nop
    Loop
    
    Timer0_irq:                                                 '1 Pausenteil 1ms
      Timer0 = Reload0
        Outp = 0                                                'EIN
        Stop Timer0
        Waitus 500
        Outp = 1                                                'AUS
        Waitus 1000                                             '2.Pausenteil 1ms
        Led1 = 0
        Start Timer1
    
       Return
    
    
    Timer1_irq:                                                 'lange Zeit 17,5ms
        Timer1 = Reload1
        Led1 = 1
        Stop Timer1
        Start Timer0
       Return
    
    '----------------------------Funktion Ausschalten---------------------------------
    
    Sub Aus
    
    Portc = &HFF                                                ' alle LEDs aus
    Led1 = 1
    Led2 = 1
    Led3 = 1                                                    ' alle LEDs aus
    Led4 = 1                                                    ' alle LEDs aus
    Ok = 1
    Outp = 1                                                    ' alle LEDs aus
    Waitms 200
    
      If Rel_flag = 0 Then
          Relais = 1                                            ' alle LEDs aus
      End If
    
    End Sub
    
    '--------------------------Funktion Frequenzberechnung----------------------------
    Sub Neue_frequenz
     Stop Timer0
     Stop Timer1
     Waitms 200
    
     Call Aus
     S = Inkey()
     Print "Frequenz ohne dezimale eingeben, d.h 500 entspricht 50Hz"
     Eingabe:
     Input " neue Frequenz: " , Fein
    
     If Fein > 500 Then
       Print "Fequenz zu Gross!!!"
       Goto Eingabe
     End If
        F = Fein / 10
        Check = Frac(f)                                         'nur Nachkommastelle
     If Check = 0.5 Or Check = 0 Then
       Print " neue Frequenz: " ; F ; "Hz"
     Else
       Print "falsche Eingabe! Nur 0,5Hz Schritte moeglich!"
       Goto Eingabe
     End If
    
     T = 1 / F
     T = T - 0.0025
     Fcalc = 1 / T
     Vorteiler = T * Fosc
     Vorteiler = Vorteiler \ Aufl
    
     If Vorteiler <= 1 Then
         Pre = 1
         Call Reloadsub
         Disable Timer1
         Config Timer1 = Timer , Prescale = 1
         Reload1 = Round(calc)
         Enable Timer1
     End If
    
     If Vorteiler > 1 And Vorteiler <= 8 Then
         Pre = 8
         Call Reloadsub
         Disable Timer1
         Config Timer1 = Timer , Prescale = 8
         Reload1 = Round(calc)
         Enable Timer1
     End If
    
     If Vorteiler > 8 And Vorteiler <= 64 Then
         Pre = 64
         Call Reloadsub
         Disable Timer1
         Config Timer1 = Timer , Prescale = 64
         Reload1 = Round(calc)
         Enable Timer1
     End If
    
     If Vorteiler > 64 And Vorteiler <= 256 Then
         Pre = 256
         Call Reloadsub
         Disable Timer1
         Config Timer1 = Timer , Prescale = 256
         Reload1 = Round(calc)
         Enable Timer1
     End If
    
     If Vorteiler > 256 And Vorteiler <= 1024 Then
         Pre = 1024
         Call Reloadsub
         Disable Timer1
         Config Timer1 = Timer , Prescale = 1024
         Reload1 = Round(calc)
         Enable Timer1
     End If
    
    
     'Start Timer1
    End Sub
    
    Sub Reloadsub
    'Berechnung von Reload1
     Calc = Fosc / Pre
     Calc = Calc / Fcalc
     Calc = Aufl - Calc
    
    End Sub
    Mich würde es brennend interessieren, warum das nicht klappt??? Vielleicht packt mal jemand das programm auf seinen Chip.

    Gruß

    Sven

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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

LiFePO4 Speicher Test