Hallo,
diesmal habe ich mit einer IR-Fernbedienung gespielt. Einen TSOP an PB4 und das GETRC5 Kommando ausprobiert. Weil das so einfach lief habe ich dann noch den Power-down des µC und Watchdogfunktion hinzugefügt. Das war dann schon etwas verzwickter um eine annehmbare Funktion hinzubekommen.
Code:
'###############################################################################
'File: RC5.bas
'4 x 7 Segment zeigt via Infrarotfernbedienung empfangene RC5 Nachricht in hex
'IDE: BASCOM-AVR Demoversion 1.11.9.8
'HW circuit: ATtiny45_4_X_7_Segment_SPI (TSOP nicht eingezeichnet)
'Anzeigemultiplexing via Timer1
'TSOP an PB4. Bascom Kommando Getrc5 nutzt Timer0 !!!
'
'Grober Ablauf:
'Nach Einschalten oder Watchdogablauf initialisieren und dann in "Power-down"
'Bei IR Empfang wird µC per Pin Change Interrupt aufgeweckt
'Mit Watchdog wird auf gültige RC5 Nachricht überwacht
'Ungültige Nachricht und Ausschalten wird 4s lang mit liegenden Strichen angekündigt
'Gültige Nachricht bleibt solange stehen bis sie durch neue gültige Nachricht ersetzt wird
'Ausschalten in den "Power-down" mit Standby Taste oder Watchdogablauf wg. ungültiger Nachricht
'###############################################################################
$regfile = "attiny45.dat"
$eepleave
$framesize = 32 'default?
$swstack = 32 'default?
$hwstack = 48 'hwstack reichlich wg Interruptroutine
$crystal = 8000000
$lib "mcsbyte.lbx" 'only byte operations
Dim Displaydigitaddress(4) As Byte 'pointer to segmentpattern
Dim Address As Byte , Command As Byte 'variables for getrc5
Dim Digitposition As Byte 'actual digit position, left to right = 1..4
Dim Helperbyte As Byte 'multipurpose
'Nutzung von Software SPI - nur Output
Config Spi = Soft , Dout = Portb.0 , Ss = Portb.1 , Clock = Portb.2
Spiinit
'mit Senden von acht high bits sicherstellen, daß über Q7 des Schieberegisters
'der HEF4017 erste Ziffer der 4 X 7 Segmentanzeige adressiert -> reset des 4017
Helperbyte = &B11111111
Spiout Helperbyte , 1
Config Timer1 = Timer , Prescale = 128 'Anzeigetimer ~60Hz pro Ziffer (RCO=8MHz)
On Ovf1 Isr_display_digit
Config Watchdog = 4096 '4096 ms timeout
Config Rc5 = Pinb.4 'TSOP at PB4
Set Pcmsk.pcint4 'enable Pin Change Interrupt on TSOP activity
On Pcint0 Show_dashes 'if PCINT then display dashes
Enable Interrupts
Enable Pcint0 'enable wake up on Pin Change Interrupt
Power Powerdown 'switch µC down, wait for PCINT (IR signal)
Disable Pcint0 'in power up avoid further PCINTs
Enable Ovf1 'enable display interrupt
Start Watchdog 'supervise for valid RC5 message
Do
Getrc5(address , Command) 'function returns FF FF if no RC5 message
If Address <> &HFF Then 'RC5 message received then...
Command = Command And &B01111111 'set toggle bit to zero
Stop Watchdog 'stop watchdog due to accepted RC5 message
If Command = &H0C Then 'if "Standby" command received then...
Gosub Show_dashes 'announce Power-down
Waitms 4000 'show dashes for 4 seconds
Gosub Display_dark 'switch all segments off
Enable Pcint0 'enable wake up on new TSOP (IR) signal
Power Powerdown 'switch µC down, wait for PCINT (IR signal)
Disable Pcint0 'in power up avoid further PCINTs
Start Watchdog 'supervise for valid RC5 message
Else
Gosub Message_to_display 'display all RC5 messages except "Standby"
End If
End If
Loop
Display_dark: 'all segments off
Displaydigitaddress(1) = 16
Displaydigitaddress(2) = 16
Displaydigitaddress(3) = 16
Displaydigitaddress(4) = 16
Waitms 100 'give time to multiplex
Return
Show_dashes: 'dashes to display
Displaydigitaddress(1) = 17
Displaydigitaddress(2) = 17
Displaydigitaddress(3) = 17
Displaydigitaddress(4) = 17
Return
Message_to_display: 'RC5 address and command to display
Displaydigitaddress(1) = Address
Shift Displaydigitaddress(1) , Right , 4
Displaydigitaddress(2) = Address
Displaydigitaddress(2) = Displaydigitaddress(2) And &H0F
Displaydigitaddress(3) = Command
Shift Displaydigitaddress(3) , Right , 4
Displaydigitaddress(4) = Command
Displaydigitaddress(4) = Displaydigitaddress(4) And &H0F
Return
Isr_display_digit: 'on each interrupt OVF1 send one digit
Digitposition = Digitposition And &B00000011 'if Digitposition = 4 -> 0
Incr Digitposition 'set digit position
Helperbyte = Lookup(displaydigitaddress(digitposition) , Segmentpattern)
Spiout Helperbyte , 1 'send digit to display
Return
Segmentpattern: 'darzustellende Zeichen (hex 0..F...)
'0gfedcba (segmente, msb immer 0)
Data &B01000000 'Ziffer "0", 0 = segment ein, 1 = aus
Data &B01111001 'Ziffer "1"
Data &B00100100 'Ziffer "2"
Data &B00110000
Data &B00011001
Data &B00010010
Data &B00000010
Data &B01111000
Data &B00000000
Data &B00010000
Data &B00001000
Data &B00000011
Data &B01000110
Data &B00100001
Data &B00000110 'Ziffer "E"
Data &B00001110 'Ziffer "F"
Data &B01111111 'dunkel
Data &B00111111 'nur Segment g eingeschaltet=Strich
Kritik, Fragen etc. willkommen.
Gruß
Searcher
Lesezeichen