-         

Ergebnis 1 bis 6 von 6

Thema: LED per PWM einschalten und dimmen PROBLEM

  1. #1
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    25.03.2006
    Ort
    Hinsdorf
    Alter
    43
    Beiträge
    379

    LED per PWM einschalten und dimmen PROBLEM

    Anzeige

    Guten Morgen liebe Gemeinde,

    ich hänge schon eine geraume Zeit an meiner PWM-Dimmung eines LED-Strip.
    Ich möchte diesen Strip einmal per PWM dimmen und ihn ein/ausschalten können.
    Das Einschalten funktioniert: Start Timer1
    Pwm_byte = 255 (Pwm1a = Pwm_byte in der Main-Do/Loop)
    und dimmen auch: Pwm_byte = Pwm_byte - 10

    Nur das Auschalten des PWM funktioniert nur sporadisch. Verkleinere ich den Wert für Pwm1a dann kann ich über: Pwm_byte = 0 und Stop Timer1 die LEDs ausschalten.
    Steht aber eine 255 im Pwm1a drinnen, lassen sich die LEDs nicht ausschalten, warum???

    Könnte mir bitte jemand einen Tipp geben, wie man den PWM so ansteuert, dass somit gedimmt und ausgeschalten werden kann???

    Klar.... ich habe die Hilfe gelesen und gegoogelt aber keine Lösung gefunden.
    Die LEDs hängen am OC1A.
    Hier mein kleines Programmchen:

    Code:
    $regfile = "m88def.dat"                                                                             ' specify the used micro                                                                             ' used crystal frequency
    $crystal = 14745600
    $baud = 57600                                                                                       ' use baud rate
    $hwstack = 70                                                                                       ' default use 32 for the hardware stack
    $swstack = 70                                                                                       ' default use 10 for the SW stack
    $framesize = 60                                                                                     ' default use 40 for the frame space
    Const Release = "2014.02.13 RGB-On V1.00"
    '------------------------------------------------------------------------------- Testvariablen
    
    Dim Tempo As Byte                                                                                   '=> für Print
    '------------------------------------------------------------------------------- RS232
    Dim Rx_data As Byte , Uart_rxd As Bit
    On Urxc Rxd_isr                                                                                     'Interrupt Empfange String von RXD
    Enable Urxc
    '------------------------------------------------------------------------------- allg. Variablen
    'Ddrc = &B01001111                                                                                   ' PortC (LED + Relaisausgänge + FSK) auf Ausgang setzen
    'Portc = &B10110000                                                                                  ' PortC  pull up Widerstand (Taster) einschalten
    Config Pinb.0 = Input : Taster Alias Pinb.0 : Portb.0 = 1                                           ' Schalter von der Dunstabzugshaube
    Config Portb.1 = Output : Led_pwm Alias Portb.1                                                     ' hinterer LED-Strip dieser kann gedimmt werden
    Config Portc.1 = Output : Led_vorn Alias Portc.1                                                    ' vorderer LED-String nur für Beleuchtung
    Dim Pwm_byte As Byte                                                                                ' Konstante für hinterer Strip = 100%
    Config Timer1 = Pwm , Pwm = 8 , Compare_a_pwm = Clear Up , Prescale = 1
    'Dim Rgb_vorn_flag As Bit , Rgb_hinen_flag As Bit
    
    '-------------------------------------------------------------------------------  Variablen
    
    '------------------------------------------------------------------------------- RFM12 Variablen & Hardwaresetup = Anschluss
    Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Clockrate = 4 , Noss = 0 , Spiin = &HB0
    Spiinit
    Config Int0 = Rising                                                                                'Rising
    On Int0 Ffit_isr
    Enable Int0
    Spi_sdo Alias Pinb.4
    Spi_cs Alias Portb.2 : Ddrb.2 = 1
    Set Spi_cs
    Config Portc.3 = Input
    Nirq Alias Pinc.3
    Config Portc.2 = Input
    Ffit Alias Pinc.2
    '-------------------------------------------------------
    Declare Sub Rf12_init()
    Declare Sub Rf12_txdata(byval Txlen As Byte)
    Declare Sub Rf12_ready
    Declare Sub Rf_cmd(byval Wert As Word)
    Dim Cmd(2) As Byte , Lv As Byte
    Declare Sub Sdi_send(byval Sdi_byte As Byte)
    Dim Sdi(2) As Byte , Fifo(2) As Byte
    Sdi(1) = &HB8
    
    Const Myadress = 40                                                                                 'Nodeadresse vom Teilnehmer
    Const Snap_sync = &H54                                                                              'Synczeichen SNAP-Protokoll
    Const Hdb2_ = &H50
    Const Recive_buffer_size = 15
    Dim Slaveadress As Byte
    Dim Mem_dummy As Byte , Dummy As Byte                                                               ' Variablen für Lösche des Empfangsarray
    Dim Rf12_timeout As Word , Rf12_err As Byte , Byteanzahl As Byte
    Dim Framelength As Byte , Crc As Byte , Crc_rx As Byte , Rf_sync As Bit , Rf_rxd As Bit , Crclength As Byte
    Dim Rf12_data(20) As Byte                                                                           ' , Rf12_s(12) As Byte At Rf12_data + 4   '  Rx_data(40) As Byte
    Dim Temp As Byte , Temp_rfm As Word
    Sync Alias Rf12_data(1)
    Hdb2 Alias Rf12_data(2)
    Hdb1 Alias Rf12_data(3)
    Dab1 Alias Rf12_data(4)
    Sab1 Alias Rf12_data(5)
    
    
    '-------------------------------------------------------------------------------
    '****************************  Programmstart   *********************************
    Enable Interrupts
    Call Rf12_init()
    Print Release
    Stop Timer1                                                                                         ' PWM-Erzeugung gestoppt, wird über RFM12 zugeschalten
    
    '#####################################################################################################
    '#############################################            MAIN DO          ###########################
    '#####################################################################################################
    Do
    Pwm1a = Pwm_byte                                                                                    ' Timervorgaben für Timer => Steuerung Helligkeit
    '******************************************************************************* UART-Auswertung
    If Uart_rxd = 1 Then
        Select Case Rx_data
                   Case 123 : Goto $c00                                                                 'vom MCS-Programmer geschickte "123" empfangen?
                   Case "1" : Pwm_byte = Pwm_byte - 10
                                    Print " pwm_byte " ; Pwm_byte
                   Case "2" : Start Timer1
                                     Pwm_byte = 100
                   Case "3" : Pwm_byte = 0
                                     Stop Timer1
                                     Reset Led_pwm
    
       End Select
      Print Pwm_byte
       Uart_rxd = 0
    End If
    
    '******************************************************************************
    Debounce Taster , 0 , Led_an , Sub                                                                  ' Lichtschalter an Haube
    
    '******************************************************************************* RFM12 abfragen & Empfangsbereit schalten
    If Rf_rxd = 1 Then
       Rf_rxd = 0
       'Gosub Framehandler
       'Gosub Rf12_rxd_on
    End If                                                                                              '
    
    Loop
    End
    
    '+++++++++++++++++++++++++++++++++++++++++++++++Subroutinen+++++++++++++++++++++
    '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    '(********* ISR Timer 1 ***************************************************
     25ms_irq:                                                  ' 25ms Interrupt für die Tastenentprellung und Zeitzählung Rolladen Hoch/Runter
    
     Timer1 = Timer1vorgabe
     Incr Timecount
    Return                                                      'and exit isr with RETI
    ')
    '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Tasterdebounce
    Led_an:
    Toggle Led_vorn
    Select Case Led_vorn
                 Case 0 : If Rf12_data(6) = 1 Then
                                   Pwm_byte = 155
                                   Start Timer1
                                Else
                                    Stop Timer1
                                    Pwm_byte = 0
                                    Reset Led_pwm
                                End If
                 Case 1 : Start Timer1
                               Pwm_byte = 255
    End Select
    Return
    
    '++++++++++++++++++++++++++++++ Auswertung des RFM12 Frames auf Pausablität & Sende-Empfangsroutinen +++++++++++++++++++++++++++++++++++++++++++
      '++++++++++++++++++++++++++++ Einstellen des RFM 12 für 868,35MHz
    'Einstellen des RFM 12
    Sub Rf12_init()
      Waitms 150
                Call Rf_cmd(&H0000)                                                                     'Read Status
                Call Rf_cmd(&Hc0e0)                                                                     'low battery, clock 10 MHz
                Call Rf_cmd(&H80e7)                                                                     'Configuration: 868MHzband, 12pf, enable FIFO
                Call Rf_cmd(&H82d8)                                                                     'power management: enable receiver, enable clock output
                Call Rf_cmd(&Hc2ac)                                                                     'data filter command
                Call Rf_cmd(&Ha686)                                                                     'Frequency: 868,35MHz
                'Call Rf_cmd(&Ha74e)                                                                                                                       'Frequency: 869,35MHz
                Call Rf_cmd(&Hc611)                                                                     'Datarate: 19,2 kbit
                Call Rf_cmd(&H94a1)                                                                     'receiver setting: 134kHz, -97dbm
                Call Rf_cmd(&Hc2ac)                                                                     'data filter:
                Call Rf_cmd(&Hc483)                                                                     'AFC:
                Call Rf_cmd(&H9850)                                                                     'TX control
                Call Rf_cmd(&He000)                                                                     'wake-up
                Call Rf_cmd(&Hc800)                                                                     'low duty-cycle
                Call Rf_cmd(&Hca81)                                                                     'Reset FIFO
                Call Rf_cmd(&Hca83)                                                                     'enable FIFO
                Call Rf_cmd(&H0000)                                                                     'read Status
    End Sub
    '++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Sende Daten
    Sub Rf12_txdata(byval Txlen As Byte)
    '
      Print "Rf12_txdata(framelength) " ; Framelength
       For Tempo = 1 To Framelength
                Print "send-data " ; Rf12_data(tempo) ; "  " ; Tempo
       Next
       Print "txdata-end "
       Print
    
      Call Rf_cmd(&H8220) : Rf12_ready                                                                  ' Sender aktivieren
      Call Sdi_send(&Haa) : Rf12_ready                                                                  'Preamble
      Call Sdi_send(&Haa) : Rf12_ready                                                                  'Preamble
      Call Sdi_send(&H2d) : Rf12_ready                                                                  'Startzeichen: 2D für den Empfänger                                                                                                                    'Preamble
      Call Sdi_send(&Hd4) : Rf12_ready                                                                  'Startzeichen: D4 für den Empfänger
      For Lv = 1 To Txlen
          Rf12_ready
          Call Sdi_send(rf12_data(lv))
      Next Lv
      Call Sdi_send(&Haa) : Rf12_ready                                                                  'Dummybyte nachschieben
      Call Sdi_send(&Haa) : Rf12_ready
    
    End Sub
    '++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Befehl zum RFM senden z.bsp. Initialisierungen
    '
    Sub Rf_cmd(byval Wert As Word)
       Cmd(2) = Wert And 255
       Shift Wert , Right , 8
       Cmd(1) = Wert
       Spiout Cmd(1) , 2
    End Sub
    
    '++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Daten zum RFM12 senden
    Sub Sdi_send(byval Sdi_byte As Byte)                                                                'wait for TX FIFO IRQ
       Bitwait Nirq , Reset
       Sdi(2) = Sdi_byte
       Spiout Sdi(1) , 2
    End Sub
    
    '++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Busy check
    ' nach jeder SPI-Übertragung wird geprüft, ob Übertragung erfolgreich und neue Daten gesendet werden können
    Sub Rf12_ready
      Rf12_timeout = 60000                                                                              'Timeout Zeit (orig. 50000)
      Reset Spi_cs                                                                                      'SS-Pin--> select RF12
      While Spi_sdo = 0                                                                                 'MISO muss von RF12 auf high gehen  'In der Sim. auf 1 stellen
         If Rf12_timeout > 0 Then                                                                       'Timeout Loop
            Decr Rf12_timeout
            Else
            Rf12_err = 1                                                                                'Flag setzen
            Exit While                                                                                  'Timeout --> Abbruch kein ready vom RF12
            End If
         Waitus 20
      Wend                                                                                              'Warten bis senden bzw. empfangen fertig
    End Sub
    '++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ RFM12 - Empfänger einschalten
    Rf12_rxd_on:
    Print "rxd on"
    'Dummy = Memcopy(mem_dummy , Rf12_data(1) , Framelength , 2)
       Lv = 1                                                                                           ' Empfangsbytezähler zurück setzen
       Rf_sync = 0                                                                                      'Sync-Erkennung zurücksetzen                                                                                                                                        'sync-Flag
       Rf_rxd = 0                                                                                       ' Empfangserkennung zurücksetzen
       Call Rf_cmd(&H0000)                                                                              'Status lesen
       Call Rf_cmd(&H82d8)                                                                              ' Empfänger einschalten
       Call Rf_cmd(&Hca81)                                                                              'FIFO&Reset CMD: sensitiver Reset aus (Brownout)
       Call Rf_cmd(&Hca83)                                                                              'FIFO&Reset CMD: Synchroner Zeichenemfang (warte auf Startzeichen: 2DD4)
       Enable Int1
       Enable Interrupts
    Return
    '++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ INT1 ISR(Daten vom RFM12)
    'Interrupt Routine zum empfangen der bytes aus dem RFM 12
     Ffit_isr:
          Spiin Fifo(1) , 2                                                                             '1 Byte lesen
         Temp = Fifo(2)
         If Temp = Snap_sync And Rf_sync = 0 Then
            Rf_sync = 1
            Lv = 1
            Framelength = 4
          End If
        Rf12_data(lv) = Temp
         If Lv = 3 Then Framelength = Temp
          If Framelength >= Recive_buffer_size Then
             Dummy = Memcopy(mem_dummy , Rf12_data(1) , Framelength , 2)
              Framelength = Recive_buffer_size
              Call Rf_cmd(&H8208)
              Disable Int1
              Gosub Rf12_rxd_on
            End If
         If Lv = Framelength And Rf_sync = 1 Then                                                       'alles eingetroffen
                Rf_rxd = 1                                                                              'Flag setzen und Empfänger zurück setzen
                Rf_sync = 0
          Call Rf_cmd(&H8208)
          Disable Int1
        End If
     Incr Lv
    Return
    
    '++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Send Frame over RF12
    Sendsnapframe:
    ' Zusammenstellung des Sendepaketes mit SNAP-Protokoll
    'Header aufbereiten (SNAP) => 5 Byte-Header
       Select Case Byteanzahl                                                                           '6Byte<=sync+HDB2+HDB1+DAB+SAB+letztes Byte = CRC
               'Case 0 To 8 : Framelength = 6                                                                                                              '6-14 (0--8 Datebyte)
               Case 5 : Byteanzahl = 11
               Case 9 : Byteanzahl = 16                                                                 '22   (16 Datenbyte)
               Case 10 : Byteanzahl = 4
               Case 15 : Byteanzahl = 15                                                                '38   (32 Datenbyte)
               End Select
      Rf12_data(1) = Snap_sync
      Rf12_data(3) = Byteanzahl                                                                         'HDB1  0..32DatenByteInfo
      Rf12_data(4) = Slaveadress                                                                        'Zieladresse
      Rf12_data(5) = Myadress                                                                           'Senderadresse
      'ab 6.Stelle <--0...40 Datenbyte rein
      Framelength = Byteanzahl
      Crclength = Byteanzahl - 1
      Rf12_data(framelength) = Crc8(rf12_data(1) , Crclength)                                           'CRC an letzter Stelle anhängen und raus senden
      Call Rf12_txdata(framelength)                                                                     ' Datenpaket senden
    Return
    
    '++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Auswertung empfangener Frams
     Framehandler:
     If Sync = Snap_sync Then                                                                           'Check auf richtiger SNAP-Knoten Syncbyte richtig?                                                                                                                                ' Adressraum = 1 Byte?
        If Dab1 = Myadress Then                                                                         ' Stimmt die Adressierung?
             Crc = Framelength - 1                                                                      ' CRC-Länge bestimmen
             Crc_rx = Crc8(rf12_data(1) , Crc)                                                          ' CRC berechnen
             Print "CRC " ; Crc ; "  " ; Rf12_data(framelength)
             If Crc_rx = Rf12_data(framelength) Then                                                    ' in letzter Stelle steht der berechnete Sende-CRC => überprüfen
             Print "CRC OK! => " ; Crc_rx
                Select Case Hdb2
                          ' Case 1 weiter ohne ACK
                          Case 1 : Print "ohne ACK "
                                         Gosub Rf12_rxd_on
                                         Gosub Funkdaten_handler
                                         'Dummy = Memcopy(mem_dummy , Rf12_data(1) , Framelength , 2)
                          ' Case 2 als Master => Slave hat mit ACK geantwortet
                         Case 2 : Print "CRC good => "
                                        Hdb2 = &H0
                                        'Dummy = Memcopy(mem_dummy , Rf12_data(1) , Framelength , 2)
                         ' Case 3 als Slave => sende Master ein ACK
                         Case 3 : Print "Master fordert ACK "
                                        Gosub Rf12_rxd_on
                                        Swap Dab1 , Sab1
                                        Hdb2 = &H2
                                        Rf12_data(framelength) = Crc8(rf12_data(1) , Crc)
                                        Call Rf12_txdata(framelength)
                                        Gosub Funkdaten_handler                                         ' => Hier Dann Aktionen Ausführen
                                        'Dummy = Memcopy(mem_dummy , Rf12_data(1) , Framelength , 2)
                         End Select
                    Else
                          Print "Framehandler-CRC-Bad" ; Crc_rx
                         'Dummy = Memcopy(mem_dummy , Rf12_data(1) , Framelength , 2)
               End If
           Else
             Print "das war nicht für mich  " ; Dab1
          End If
    
     End If
    Return
    '++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    Funkdaten_handler:                                                                                  'Auswertung der Nutzdaten.... nur als Denkhilfe :)
    
    Select Case Rf12_data(6)
           Case 0 : Reset Led_vorn
                          Stop Timer1
                          Pwm_byte = 0
                          Reset Led_pwm
    
           Case 1 : Reset Led_vorn                                                                      'Led_vorn = 0
                          Start Timer1
                          Pwm_byte = 155
    
    
           End Select
    Return
    '++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ UART ISR
    Rxd_isr:                                                                                            '
    Rx_data = Udr                                                                                       'Zeichen aus UART holen
    Uart_rxd = 1
    Return
    Vielen Dank für Eure Hilfe!!!
    MAT

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    16.02.2006
    Beiträge
    1.112
    Setze die TCCR1A.COM1Ax bits auf disconnect, bevor du Reset LED_pwm machst.
    Beim Starten musst du dann vor dem PWM_Byte=xxx die bits wieder auf Clear setzen.

  3. #3
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    25.03.2006
    Ort
    Hinsdorf
    Alter
    43
    Beiträge
    379
    Hallo for_ro,

    gut, jetzt weiss ich, wie ich den Ausgang OC1A auch als Portpin nutzen kann. Habe ich es richtig verstanden, dass wenn ich TCCR1A.COM1A0/TCCR1A.COM1A1 auf Null setze ich den Portpin als Normalen Input/Outputpin nutzen kann?
    Ich wollte nicht umbedingt über diesen Weg gehen. Ursprünglich möchte ich den PWM/OC1a nur ein/ausschalten (LED an/aus) und ich habe gelesen, dass die über Start und Stop Timer1 gehen soll. Nur leider funktioniert dies nicht immer richtig, auch wenn ich den PWM-Wert auf null setze nicht....
    Irgend eine Idee du haben

  4. #4
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    15.01.2007
    Ort
    Göttingen
    Beiträge
    705
    Ich sehe das Problem eigentlich hier: Wenn Du den Timer einfach so anhältst weißt Du ja nie, ob er gerade über oder unter der Wert von PWM1A ist. Folglich ist es auch nicht beeinflussbar, ob der OC-Pin gerade auf 1 oder auf 0 steht, wenn der Timer stoppt.

    Ich konfiguriere meine PWM-Anwendungen immer direkt über die Register, aber "Clear Up" verstehe ich so, dass der Ausgang auf 0 gesetzt wird, wenn der Timer den Wert von PWM1A beim hochzählen überschreitet (korrigiert mich, wenn das nicht stimmt!). Wenn aber 255 in diesem Register steht, tritt dieser Fall aber niemals ein, d.h. der Ausgang bleibt dauerhaft auf 1. Dementsprechend wird der Ausgang immer auf 0 bleiben, wenn 0 im PWM1A-Register steht.

    Für alle anderen PWM1A-Werte dürfte der Ausgang beim Stoppen vom Timer 1 "zufällig" 1 oder 0 führen, je nachdem an welcher Stelle der Timer angehalten wurde.

    Ich denke, dass das "Abhängen" des OC1A-Pins die beste Lösung ist (wie ja schon von for_ro beschrieben).

  5. #5
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    25.03.2006
    Ort
    Hinsdorf
    Alter
    43
    Beiträge
    379
    @Sauerbruch,

    Genau so ist es wie Du es beschreibt. das ausschalten der LEDs ist nur spontan möglich. Und Dein erklärtes bestätigt mir meine Vermutung. Dann werde ich per Hand den OC1a direkt ausschalten.
    Danke an alle

  6. #6
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    25.03.2006
    Ort
    Hinsdorf
    Alter
    43
    Beiträge
    379
    Soooo und gleich mal ausprobiert

    Code:
    'zum Ausschalten mega88 OC1A
    Tccr1a.7 = 0
    Tccr1a.6 = 0
    "Clear OC1A on Compare Match (Set output to
    low level)"
    
    'zum Wiedereinschalten
    Tccr1a.7 = 1
    Tccr1a.6 = 0
    Start Timer1 ' PWM aktivieren
    Ocr1a = 100 ' PWM Wert bei dem begonnen werden soll
    Also das Heißt, dass durch diese Zuweisung mein OC1A-Pin auf 0 geschalten wird.
    Noch eine Frage: wie könnte ich die Schreibweise vereinfachen, also ala Tccr1a = &H..... Was ich mich schon immer gefragt habe ist, wie kann ich einzellne Bits im Byte so verändern, dass nur diese geändert werden (siehe obriges Beispiel).

    Vielen Dank an alle!
    Geändert von mat-sche (15.02.2014 um 17:15 Uhr) Grund: ''war noch ein kleiner Denkfehler dabei :)

Ähnliche Themen

  1. LED dimmen ohne PWM
    Von migTec im Forum Elektronik
    Antworten: 8
    Letzter Beitrag: 13.02.2009, 17:37
  2. Led dimmen mit PWM
    Von H3llGhost im Forum C - Programmierung (GCC u.a.)
    Antworten: 7
    Letzter Beitrag: 25.08.2008, 08:39
  3. LED dimmen
    Von any_key im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 6
    Letzter Beitrag: 08.07.2008, 09:51
  4. LED Dimmen per Software | Problem
    Von xeno im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 3
    Letzter Beitrag: 02.04.2008, 00:02
  5. LED Dimmen
    Von darkkiller im Forum Assembler-Programmierung
    Antworten: 2
    Letzter Beitrag: 04.04.2007, 21:01

Berechtigungen

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