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

Thema: Bascom getrc5 und SPI Problem

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    11.01.2004
    Beiträge
    44

    Bascom getrc5 und SPI Problem

    Anzeige

    Praxistest und DIY Projekte
    hi,

    ich versuche gerade ne Schaltung mit nem Mega8 zu basteln, mit der ich per Infrarot Fernbedienung eine 7-Segment Anzeige verstellen kann. Die Segmentanzeige wird mit einem max7221 betrieben. Nun zum Problem. Seperat läuft der Empfang des Infrarot Signals (TSOP1736) und die Ansteuerung des MAx7221 per SPI. wenn ich aber nun z.b. die Emfangsroutine getrc5 zusammen mit dem SPI verwenden will geht gar nichts. Ich habe auch schonmal den Software SPI benutzt funzt auch nicht.
    Was mache ich falsch? Irgenwie müssen die beiden Sachen doch zusammen laufen oder?

  2. #2
    1hdsquad
    Gast
    Ich würde sagen, dass die beiden Protokolle kollidieren. Soviel ich weiß, nutzt der RC5 Interrupts? Sie scheinen den Rest zu stören, mit Software SPI geht das noch schlechter...

  3. #3
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    16.02.2006
    Beiträge
    1.113
    Hallo,
    ich meine, ich hätte anfangs GetRC5() und Soft-SPI zusammen benutzt. Bei mir kamen die Probleme bei der Kombination GetRC5 und Clock=Soft.
    GetRC5 kannst du übrigens auch über den Timer2 laufen lassen.
    Da mir das ganze zu unsicher und der Befehl sowieso viel zu langsam war, habe ich mir eine kleine Routine geschrieben, die das RC5-Signal über einen externen Interrupt Eingang abgreift. Das funzt jetzt viel besser und wesentlich schneller.

    Gruß Rolf

  4. #4
    Benutzer Stammmitglied
    Registriert seit
    11.01.2004
    Beiträge
    44
    Danke für die Antworten. Also ich habe jetzt das Spi komplett rausgeschmissen, und mein eigenes eingesetzt. Die Anzeigen leuchten,aber der RC5 funktioniert erst wenn ich die Segmente ausschalte. Das verstehe ich nu nicht, die getrc5-funktion müßte eigentlich gehen da meine Routine keine IRQ etc belegt (sie sendet nur). ich weiß momentan nicht weiter?

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    12.09.2007
    Beiträge
    19
    Zitat Zitat von for_ro
    Hallo,
    ich meine, ich hätte anfangs GetRC5() und Soft-SPI zusammen benutzt. Bei mir kamen die Probleme bei der Kombination GetRC5 und Clock=Soft.
    GetRC5 kannst du übrigens auch über den Timer2 laufen lassen.
    Da mir das ganze zu unsicher und der Befehl sowieso viel zu langsam war, habe ich mir eine kleine Routine geschrieben, die das RC5-Signal über einen externen Interrupt Eingang abgreift. Das funzt jetzt viel besser und wesentlich schneller.

    Gruß Rolf
    Hallo Rolf,

    bin durch Zufall auf Deinen Beitrag zu GetRC5 gestoßen. Habe ein ganz ähnliches Problem wie Du (RC5 dauert zu lange) aber nicht so viel Ahnung diesen selbst zu programmieren. Daher würde ich mich brennend für Deine funzende Alternative interessieren. Danke Jeronnimo

  6. #6
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    16.02.2006
    Beiträge
    1.113
    Hallo Jeronnimo,
    für meine Routine brauchst du einen freien, externen Interrupt Eingang.
    Wenn du den hast, dann gib mir mal den Portx.y, deinen µC und Frequenz, mit der er läuft.
    Ich passe dir dann die Config an und stelle den Code ein.
    Außerdem benutze ich einen durchlaufenden Allzweck-Timer, der mit 8KHz überläuft.

    Gruß

    Rolf

  7. #7
    Neuer Benutzer Öfters hier
    Registriert seit
    12.09.2007
    Beiträge
    19
    Hallo Rolf,

    super, danke Dir.

    Ich benutze ATMEGA8, An PortD.2 soll der Infrarotempfänger (TSOP1736), als Quarz benutze ich einen mit 6,144MHz. Du kannst es auch direkt an jeronnimo39@hotmail.de senden.

    Gruß Jeronnimo

  8. #8
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    16.02.2006
    Beiträge
    1.113
    Hallo

    Code:
    'Hier mal eine Routine für die Eigenverarbeitung von RC5 Signalen.
    'Ich hatte immer wieder Probleme mit der langen Wartezeit von dem Standard Getrc5 gehabt.
    'Daher habe ich mir eine Routine geschrieben, die keine Wartezeiten und auch kein Polling macht,
    'sondern einen externen Interrupt benutzt
    '
    'Der Timer wird nicht ausschliesslich für den RC5 benutzt, läuft also immer mit 8kHz durch.
    'Es wird in Impuls_laenge nur die Anzahl der overflows festgehalten.
    'Außerdem kann man festlegen, ob mehrfach Empfang ohne loslassen erlaubt ist (wiederholen_erlaubt=1)
    'oder nicht (wiederholen_erlaubt=0).
    'Eingehende Impulse werden nach Länge überprüft und dann in die Variable Temp_daten geschoben,
    'also 14-bit bei einem korrekten Befehl.
    'Wenn man sich die möglichen Zeiten zwischen zwei steigenden Flanken ansieht,
    'stellt man fest, dass es drei verschiedenen geben kann:
    'kurze Impulselänge (1,778ms ~ 14 Überläufe) ->
    '          gleicher Wert empfangen wie beim letzten Impuls, also vorher 0 jetzt 0 oder vorher 1 und jetzt 1
    'lange Impulselänge (2,677ms ~ 21 Überläufe) ->
    '          vorher war es eine 0, jetzt kommt eine 1 und eine 0 (also 2 bit zusammen)
    'mittl Impulselänge (3,556ms ~ 28 Überläufe) ->
    '          entweder war es vorher eine 0, dann jetzt eine 1 oder vorher eine 1 dann jetzt eine 1 und eine 0
    'Wenn dann 14 bit zusammen sind, extrahiere ich daraus die Adresse und den Befehl und überprüfe, ob die Sinn machen.
    'Dann wird der Befehl ausgegeben, falls er ungleich dem letzten Befehl ist bzw. wiederholen erlaubt ist.
    
    $crystal = 16000000
    $regfile = "m128def.dat"
    
    Dim Impuls_laenge As Word , Bit_nummer As Byte , Temp_daten As Word
    Dim Befehl As Byte , Adresse As Byte , Empfangs_fehler As Byte , Wiederholen_erlaubt As Byte
    Dim Letzte_adresse As Byte , Letzter_befehl As Byte , Startwert As Byte
    Dim Interrupt_vektor As Byte
    
    Config Timer0 = Timer , Prescale = 8
    On Ovf0 Tim0_isr
    Enable Timer0
    Startwert = 160                                             '6144000/8/(256-160)=8000 Überläufe pro Sekunde,
    Timer0 = Startwert                                          'also alle 0,125ms, Impulslänge bei RC5 1,778ms, also ca. 14
    
    
    Config Int0 = Rising                                        'externer interrupt, dauernd high, falls Signal dann low
                                                                 'falls dauernd low, dann auf falling ändern und PORTD.2=0 setzen
    On Int0 Get_rc5_isr
    Enable Int0
    
    Ddrd.2 = 0                                                  'ausgang des RC5-empfängers
    Portd.2 = 1                                                 'Pullup ein, auf Pulldown ändern, wenn dauernd low kommt
    
    Wiederholen_erlaubt = 0                                     'auf 1 setzen, wenn wiederholen erlaubt sein soll, sonst 0
    
    $baud1 = 115200
    Open "COM2:" For Binary As #1
    
    Enable Interrupts
    
    Do
       If Interrupt_vektor.7 = 1 Then
          'Print #1 , Impuls_laenge                              'Vorsicht, wenn das Print aktiv ist, können sich bei geringer
                                                                 'Übertragungsrate die Zeiten verändern
          Select Case Impuls_laenge
             Case Is > 1500:                                    '-> startimpuls, nach empgfangsfehler muss immer erst ein solcher kommen.
                Bit_nummer = 1
                Temp_daten = 1
                Empfangs_fehler = 0
             Case 26 To 29:                                     '-> große Länge: vorher 0, jetzt 1 + 0
                If Empfangs_fehler = 0 Then
                   Shift Temp_daten , Left                      'hinzufügen einer 0
                   Incr Temp_daten                              'umwandeln in 1
                   Shift Temp_daten , Left                      'hinzufügen einer 0
                   Incr Bit_nummer                              'bei Kombination '10' fehlt ein Impuls
                End If
             Case 19 To 22:                                     '-> mittlere Länge: vorher 1, jetzt 1 + 0 oder vorher 0 jetzt 1
                If Empfangs_fehler = 0 Then
                   Shift Temp_daten , Left                      'hinzufügen einer 0
                   Incr Temp_daten                              'umwandeln in 1
                   If Temp_daten.1 = 1 Then                     'vorher gab es eine 1
                      Shift Temp_daten , Left                   'hinzufügen einer 0
                      Incr Bit_nummer                           'bei Kombination '10' fehlt ein Impuls
                   End If
                End If
             Case 12 To 15:                                     '-> kleine Länge     --> gleicher Wert wie vorher
                If Empfangs_fehler = 0 Then
                   Shift Temp_daten , Left                      'hinzufügen einer 0
                   If Temp_daten.1 = 1 Then                     'vorher gab es eine 1
                      Incr Temp_daten                           'umwandeln in 1
                   End If
                End If
             Case Is > 400:                                     'aber kleiner 1500, dann war's eine Pause zwischen Befehlen beim Dauerdrücken
                If Empfangs_fehler = 1 Or Wiederholen_erlaubt = 1 Then
                   Bit_nummer = 1
                   Temp_daten = 1
                   Empfangs_fehler = 0
                End If
             Case Else
                Empfangs_fehler = 1
          End Select
          If Bit_nummer = 14 Then
             Befehl = Temp_daten And &B00111111
             Shift Temp_daten , Right , 6
             Adresse = Temp_daten
             If Befehl < 64 And Adresse > 191 Then              '-C6 wird nicht benutzt, also immer 1
                If Wiederholen_erlaubt = 1 Or Befehl <> Letzter_befehl Or Adresse <> Letzte_adresse Then
                   Letzter_befehl = Befehl
                   Letzte_adresse = Adresse
                   Print #1 , "Befehl=" ; Befehl
                End If
             End If
          End If
          Impuls_laenge = 0
          Interrupt_vektor.7 = 0
       End If
    Loop
    
    End
    
    Tim0_isr:
       Timer0 = Startwert
       Incr Impuls_laenge
       If Impuls_laenge > 65000 Then                            'Überlauf von Impuls_laenge verhindern (nach 65535 kommt 0),
                                                                 'damit Start (Impuls_laenge > 500) sicher erkannt wird
          Impuls_laenge = 1501
       End If
    Return
    
    Get_rc5_isr:                                                'RC5 Impuls erkannt
       'Print #1 , "Received Get_rc5 Interrupt"                  'wenn gar nichts geht, dies mal aktivieren
       Incr Bit_nummer
       Interrupt_vektor.7 = 1
    Return
    Schau mal, ob du damit zurecht kommst.

    Gruß Rolf

  9. #9
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    16.02.2006
    Beiträge
    1.113
    Bei dir muss das natürlich so heißen:

    $crystal = 6144000
    $regfile = "m8def.dat"

  10. #10
    Neuer Benutzer Öfters hier
    Registriert seit
    12.09.2007
    Beiträge
    19
    Das wird eine kurze Nacht glaub ich, danke Dir

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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

MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad