PIC-Lernbeispiel: IR-Fernbedienung

für Philips-TV-Geräte

zurück zu Lernbeispiele , PIC-Prozessoren , Elektronik , Homepage


wenn ein Gerät über einen langen Zeitraum von einer Batterie versorgt werden muss, dann ist Stromsparen angesagt.
Die Grundlagen der Infrarot-Fernbedienungen sind an anderer Stelle erörtert worden. In diesem Beispiel wird mit einem 16F628 eine IR-Fernbedienung aufgebaut, mit der man Audio/Video-Geräte von Philips (und Marantz) steuern kann.
Die Grundvariante kann die Kanalwahl und die Lautstärke eines TV steuern.

Schaltung
Stromlaufplan der IR-Fernbedienung Die Schaltung besteht aus einem PIC16F628, vier Tasten, einem Schalter (optional) und der IR-LED mit Treiber.
Die Tasten sind an den Port B angeschlossen, und die LED an den Port A.
Die nicht eingezeichneten Pins RA0, RA2..RA5 sollten im Interesse eines minimalen Stromverbrauchs mit Vss verbunden werden.

Zur Stromversorgung kann man z.B. 3 in Reihe geschaltete AAA-Zellen benutzen.

Falls die Reichweite der Fernbedienung nicht ausreichend sein sollte, kann R2 weiter verringert werden. Aufgrund des gepulsten Betriebs sind Werte bis hinab zu 10 Ohm unkritisch. In mit AAA-Zellen gespeisten Fernbedienungen wird oft gar kein Vorwiderstand benutzt, da der Kurzschlussstrom der AAA-Zellen kleiner ist als der Peak-Strom der LED. Die Verwendung eines Widerstandes empfehle ich aber dringend, da schon die im Elko gespeicherte Energie die LED zerstören könnte.

Der Schalter am Pin 6 dient der Umschaltung zwischen zwei Anwendungsfällen. Ist der Schalter offen (oder schlichtweg nicht vorhanden), dann werden die wichtigsten vier Codes für ein Phillips-TV-Gerät erzeugt. Ist der Schalter aber geschlossen, dann werden anstelle der Lautstärkenkommandos die Codes für die Programmtasten "0" und "9" gesendet. Damit eignet sich die Fernbedienung ideal als Sender für diesen RC5-Empfänger.

Zum Aufbau eignet sich z.B. die 16F84-Testplatine. oder die 16F84-Minitestplatine.

Bitte darauf achten, das beim Brennen LV-Programming-Enable nicht aktiv ist.



Strom sparen

PICs sind zwar keine Stromfresser, aber auch eine Dauerstromaufnahme von wenigen Milliampere leert jede Batterie in wenigen Tagen.
Zur Senkung der Stromaufnahme gibt es prinzipiell drei Möglichkeiten:

Senkung des PIC-Taktes
Ein PIC16F628 benötigt bei 20 MHz (HS-Mode) ca 5 mA, bei 4 MHz (XT-Mode oder INTRC-Mode) noch etwa 1 mA und bei 32 kHz (LP-Mode) nur noch Mikroampere. Der Sprung vom XT zum HS-Mode verfünffacht also die Stromaufnahme. Es bietet sich deshalb an, den XT-Mode mit den maximal erlaubten 4 MHz oder den internen 4-MHz-Oszillator zu benutzen, wenn man einen schnellen aber stromsparenden PIC haben möchte.
Wer mit einem langsamen PIC auskommt, kann den LP-Mode benutzen, dessen Funktion ist aber nur für die PIC16LF62x-Typen garantiert.

Nutzung des Sleep-Mode
In einer Fernbedienung hat ein PIC die meiste Zeit gar nichts zu tun, das Gerät wird ja nicht pausenlos benutzt. Da kann man den PIC in der arbeitsfreien Zeit schlafen legen. Dazu gibt es einen 'power-down-mode', in dem der PIC die Arbeit einstellt, und dann weniger als 10 µA verbraucht.
Beim Druck auf eine Fernbedienungstaste muss der PIC natürlich wieder aufwachen.
Ein PIC kann auf drei verschiedenen Weisen geweckt werden:

Wird ein zu diesen Interruptquellen gehörendes Interrupt-Flag gesetzt und wurde vorher das zugehörige Interrupt-Enable-Flag gesetzt, dann läuft ein schlafender PIC wieder los, unabhängig davon, ob Interrupts durch das GIE-Flag überhaupt erlaubt sind.
Ich wecke in diesem Beispiel den PIC durch einen 'Interrupt durch Pegelwechsel an RB4..RB7', den die gedrückte Taste auslöst. Dazu verbindet die Taste eines der Pins RB4..RB7 mit Masse (Vss). Die Pins RB0..RB3 führen während des Schlafs Low-Pegel, während die Pins RB4..RB7 mit internen pull-up-Widerständen auf high-Pegel gehalten werden. Beim Tastendruck ändert sich der Pegel an einem der Pins RB4..RB7 von high auf low, woraufhin das Interrupt-Flag gesetzt wird.

Man könnte auch 16 Taster als Matrix zwischen die Pins RB0..3 und RB4..7 anordnen. Dann verbindet die gedrückte Taste eines der Pins RB0..RB3 mit einem der Pins RB4..RB7. Da RB0..3 in diesem Beispiel Low-Pegel ausgeben, wird der PIC aus dem Schlaf geweckt. Nun kann der PIC analysieren, welche der 16 Tasten gedrückt wurde, und einen von 16 möglichen IR-Befehlen aussenden. Die weiter unten vorgestellt Software unterstützt zunächst aber nur 4 Tasten.

freie Pins
Freie Input-Pins können zu einem erhöhten Stromverbrauch führen, da sie unkontrolliert zwischen high und low schwingen können. Um den Stromverbrauch im Sleep-Mode zu minimieren sollte man freie Input-Pins also mit Vdd und Vss verbinden, oder zu offenen Output-Pins machen. Die freien Pins des PortB liegen durch interne Pull-up-Widerstände fest auf High-Pegel. Wer diese Schaltung wirklich dauerhaft verwenden will, sollte aber die freine Pins des PortA (RA0, RA2..RA5) z..B. mit Vss verbinden.



Programmablauf Der PIC verbringt also die meiste Zeit im Schlaf.


Programmlisting

        list p=16f628
;**************************************************************
;*
;*      ---------------------------------- 
;*      PORTA:  0 -
;*              1 RC-5 Output
;*              2 - 
;*              3 -
;*              4 -
;*
;*      PORTB:  0 < 0: 0/9  1: leise/laut
;*              1 > 
;*              2 > 
;*              3 > 
;*              4 < Taste 4
;*              5 < Taste 5
;*              6 < Taste 6
;*              7 < Taste 7
;*
;**************************************************************
;
; Senden von RC-5-codes an philips/marantz geräte
;
; An RB4..7 liegen 4 Tasten nach Masse
; beim Drücken einer Taste wird ein der Taste
; fest zugeordneter RC-5-code gesendet
;
; output: RA1
;
; Takt 4 MHz
;
;
; RC5-code hatt 5 Adressenbits (A0-A4) und 7 Commandobits (C0-C6)
; und ist wie folgt als 14-bit code aufgebaut:
;  1. startbit=1
;  2. invertiertes C6
;  3. Toggelbit: wechselt seinen wert von code zu code
;  4. A4
;  5. A3
;  6. A2
;  7. A1
;  8. A0
;  9. C5
; 10. C4
; 11. C3
; 12. C2
; 13. C1
; 14. C0
;
;
;
;****************************************************************************

        #include <P16f628.INC>

        ERRORLEVEL      -302            ;SUPPRESS BANK SELECTION MESSAGES

; Configuration festlegen:
; Power on Timer, kein Watchdog, interner 4MHz-Oscillator, kein Brown out, kein LV-programming
    __CONFIG    _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _BODEN_OFF & _LVP_OFF
 

toggel  Equ     0x20            ; zählt ir-Sendungen, bit 0 ist toggelbit
gr      Equ     0x21            ; Gruppencode 5 bit rechtsbündig
co      Equ     0x22            ; Commandocode 6 bit rechtsbündig
cycl_1  Equ     0x23            ; zähler 
cycl_2  Equ     0x24            ; zähler

#define IrOut      PORTA, 1
#define Auswahl    PORTB, 0

;****************************************************************************
        org     0

Init
; ports einstellen
        bsf     STATUS, RP0     ; Bank 1
        movlw   B'00111101'     ; RA1 output 
        movwf   TRISA           ; 
        movlw   B'11110000'     ; PortB7..4 input, 3..0 output
        movwf   TRISB
        bcf     STATUS, RP0     ; Bank 0
        clrf    PORTA           ; 
        clrf    PORTB           ;

; 16F628 alle Comparatoreingänge auf Digital umschalten
        BSF     CMCON, CM0
        BSF     CMCON, CM1
        BSF     CMCON, CM2

; interrupt on change an PortB RB4..7
        bsf     STATUS, RP0     ; Bank 1
        bcf     OPTION_REG, 7   ; pull up an
        bcf     STATUS, RP0     ; Bank 0
        clrf    INTCON          ; GIE aus
        bsf     INTCON, RBIE    ; RBIF kann wecken

; pull-up ein
        bcf     INTCON, RBIF

Main
        sleep
        ; wecken durch Tastendruck an PortB
        btfss   INTCON, RBIF
        goto    Main            ; stör mich nicht!
        movfw   PORTB
        bcf     INTCON, RBIF

        btfss   PORTB,4
        call    Taste4
        btfss   PORTB,5
        call    Taste5
        btfss   PORTB,6
        call    Taste6
        btfss   PORTB,7
        call    Taste7
        goto    Main

;****************************************************************************
Taste4
        movlw   D'0'            ; TV
        movwf   gr
        movlw   D'32'           ; Kanal +
        movwf   co
        call    Tx
        return
Taste5
        movlw   D'0'            ; TV
        movwf   gr
        movlw   D'33'           ; Kanal -
        movwf   co
        call    Tx
        return
Taste6
        movlw   D'0'            ; TV
        movwf   gr
        movlw   D'16'           ; lauter
        btfss   Auswahl
        movlw   D'9'            ; 9
        movwf   co

        call    Tx
        return
Taste7
        movlw   D'0'            ; TV
        movwf   gr
        movlw   D'17'           ; leiser
        btfss   Auswahl
        movlw   0               ; 0

        movwf   co
        call    Tx
        return
 

;****************************************************************************
; Senden eines kompletten IR-Befehls mit Gruppencode in gr und Kommando in co
; die Routine ist etwas primitiv aufgebaut, dafür aber übersichtlich
Tx
        incf    toggel, f

        ;Startbit
        call    TxEins

        ;invertiertes C6
        btfss   co,6            ;1T
        call    TxEins          ;2T+
        btfsc   co,6            ;2T
        call    TxNull          ;0T

        ;Toggelbit
        btfsc   toggel,0
        call    TxEins
        btfss   toggel,0
        call    TxNull

        ;A4,3,2,1,0
        btfsc   gr,4
        call    TxEins
        btfss   gr,4
        call    TxNull

        btfsc   gr,3
        call    TxEins
        btfss   gr,3
        call    TxNull

        btfsc   gr,2
        call    TxEins
        btfss   gr,2
        call    TxNull

        btfsc   gr,1
        call    TxEins
        btfss   gr,1
        call    TxNull

        btfsc   gr,0
        call    TxEins
        btfss   gr,0
        call    TxNull

        ;C5,4,3,2,1,0

        btfsc   co,5
        call    TxEins
        btfss   co,5
        call    TxNull

        btfsc   co,4
        call    TxEins
        btfss   co,4
        call    TxNull

        btfsc   co,3
        call    TxEins
        btfss   co,3
        call    TxNull

        btfsc   co,2
        call    TxEins
        btfss   co,2
        call    TxNull

        btfsc   co,1
        call    TxEins
        btfss   co,1
        call    TxNull

        btfsc   co,0
        call    TxEins
        btfss   co,0
        call    TxNull

        return

;****************************************************************************
; Senden einer 0 (on-off)
TxNull
        call    LichtAn         ;2T
        call    LichtAus        ;2T
        return                  ;2T

;****************************************************************************
; Senden einer 1 (off-on) 
TxEins
        call    LichtAus
        call    LichtAn
        return

;****************************************************************************
; Licht aus  (889 us)
; ca. 13 Takte werden für den Aufruf benötigt
;  889 us -13 us =876 us = 175 Takte x 5
LichtAus

        movlw   D'175'
        movwf   cycl_2
LichtAus2
        nop                     ;1T
        nop                     ;1T
        decfsz  cycl_2,f        ;1T
        goto    LichtAus2       ;2T
        return                  ;2T

;****************************************************************************
; Licht pulsen (889 us)
; ideal: 32 IR Pulse von je 6,944 us mit Pausen von 20,8332 us
; real:  32 Pulse a 7 us mit je 21 us Pause, letzte Pause entfällt (32x7+31*21=875 us)
LichtAn
        ; 1. Puls
        bsf     IrOut
        movlw   D'31'           ; 31 weitere Zyklen
        movwf   cycl_1
        nop
        nop
        nop
        nop
        bcf     IrOut

        ;31 Zyklen aus Pause und Puls
LichtAn1
        ;Pause
        movlw   D'5'            ;1T
        movwf   cycl_2          ;1T
        nop                     ;1T
        nop                     ;1T
LichtAn2                        ; 4x3T + 1x2T =14T
        decfsz  cycl_2,f        ;1T
        goto    LichtAn2        ;2T
        ;Puls                   ;7T
        bsf     IrOut
        nop
        nop
        nop
        nop
        nop
        nop
        bcf     IrOut
        decfsz  cycl_1,f        ;1T
        goto    LichtAn1        ;2T

        return

        end



Andere Variante

In diesem Programm werden alle Pulse des RC-5-Protokolls durch Warteschleifen erzeugt. Man kann dafür aber auch das PWM-Modul benutzen. Wie das geht, wird hier erläutert.


zurück zu Lernbeispiele , PIC-Prozessoren , Elektronik , Homepage
Autor: sprut
erstellt : 20.02.2003
letzte Änderung: 13.11.2012