4 Farben LED-Leiste: Software
Quelltext ir8051.a51:
; 12.11.2005 15:56:50
#cpu = 80C31 ; @15.600 MHz
ajmp Initialisierung
EXTI0: ; externer Interrupt 0
ajmp Externer Interrupt 0
;definitionen für die fernbedienung einbinden
#include 'rc_uni140.inc'
#const start_addr=30h, end_addr=68h, max_nochange=17
#const ch_0_max=255, ch_1_max=255, ch_2_max=255, ch_3_max=255
#const ch_step=fh
#exclude Byte 30h-68h
#byte rc_ptr
#byte rc_cnt, nochange_cnt, last_code, comp_val
#byte tp1, tp2
#byte ch_0=71h, ch_1=72h, ch_2=73h, ch_3=74h, active_ch, max_active_ch
#bit last_bit, have_code, match_end, led_toggle, rc_led=p3.3
#bit dir_0, dir_1, dir_2, dir_3
#byte prog_running, prog_state
#byte ch_data_port=p1
#bit ch0_le=p3.4, ch1_le=p3.5, ch2_le=p3.6, ch3_le=p3.7
Initialisierung:
; Serieller Port
mov SCON, # 40h ; Modus 1, asynchron, 8 Bit, Baudrate Timer 1 Überlauf
mov TMOD, # 20h ; Timer 1 Autoreloadmodus
mov TH1, # fch ; Reloadwert für Baudrate 158691,4
setb TR1 ; Timer 1 Start
orl TMOD, # 01h ; Timer 0 als 16-Bit Timer.
; Die Überlauffrequenz des Timer 0 beträgt 19836,43 Hz, die Periodendauer 5,041231E-02 ms.
mov TL0, # FFh
mov TH0, # 3Fh
; Interrupts
clr IT0
setb EA ; globale Interruptfreigabe
mov last_code, #ffh
setb rc_led
mov prog_running, #0h
setb p3.3
mov ch_0, #00h
mov ch_1, #00h
mov ch_2, #00h
mov ch_3, #00h
mov active_ch, #0h
mov max_active_ch, #ch_0_max
setb ch0_le
setb ch1_le
setb ch2_le
setb ch3_le
acall write_ch
init_vars:
clr have_code
acall t0_go_long
acall wait_for_t0
;acall t0_go_long
;acall wait_for_t0
setb ex0
main:
if bit have_code
jmp eval
end if
mov a, prog_running
if a=#1h
acall prog1
elseif a=#2
acall prog2
end if
jmp main
eval:
;auf repeat code checken
mov a, rc_cnt
clr cy
subb a, #rc_repeat_len
;code zu kurz
if bit cy
jmp init_vars
end if
;vergleich mit repeat code tabelle
mov dptr, #rc_repeat_tab
mov r0, #start_addr
mov r7, #rc_repeat_len
inc r7
for r7
mov a, #0
movc a, @a+dptr
mov comp_val, @r0
if a=comp_val
inc r0
inc dptr
else
jmp check_rc_id
end if
next
;schleife ist durchgelaufen, also repeat code empfangen
mov a, last_code
if a=#ffh
jmp init_vars
else
mov r7, last_code
jmp code_found
end if
check_rc_id:
;auf fernbedienungs id checken
mov a, rc_cnt
clr cy
subb a, #rc_id_len
;code zu kurz
if bit cy
jmp init_vars
end if
;mit id tabelle vergleichen
mov dptr, #rc_id_tab
mov r0, #start_addr
mov r7, #rc_id_len
inc r7
for r7
mov a, #0
movc a, @a+dptr
mov comp_val, @r0
if a=comp_val
inc r0
inc dptr
else
jmp init_vars
end if
next
;schleife ist durchgelaufen, d.h. id ist gültig
;code ermitteln, dazu codetabelle durchgehen
mov dptr, #code_tab
mov r7, #known_codes
for r7
clr match_end
mov a, #start_addr
add a, #code_pos
mov r0, a
for r6=#code_len
mov a, #0
movc a, @a+dptr
mov comp_val, @r0
if a=comp_val
else
setb match_end
end if
inc r0
inc dptr
next
;es gab keinen fehler beim aktuellen code
if not bit match_end
jmp code_found
end if
next
;schleife ist durchgelaufen, dh kein code passte
jmp init_vars
code_found:
;codeauswertung
mov last_code, r7
mov a, #known_codes
clr cy
subb a, r7
;aktionen für den jeweiligen tastencode
if a=#0
mov active_ch, #3h
mov max_active_ch, #ch_3_max
elseif a=#1
mov active_ch, #1h
mov max_active_ch, #ch_1_max
elseif a=#2
mov active_ch, #2h
mov max_active_ch, #ch_2_max
elseif a=#3
mov active_ch, #0h
mov max_active_ch, #ch_0_max
elseif a=#4
acall on_off
elseif a=#5
acall dec_ch
elseif a=#6
acall inc_ch
elseif a=#7
acall dec_ch_step
elseif a=#8
acall inc_ch_step
elseif a=#9
mov a, prog_running
if a=#1h
mov prog_running, #0
else
mov prog_running, #1
end if
elseif a=#10
mov a, prog_running
if a=#2h
mov prog_running, #0
else
mov prog_running, #2
acall prog2_init
end if
end if
acall write_ch
acall write_stats
;zurück auf anfang
jmp init_vars
Externer Interrupt 0:
clr ex0
; timer start
acall t0_go
; receive buffer auf 0
mov r0, #start_addr
mov rc_cnt, #0h
mov nochange_cnt, #0h
next_byte:
; rc led toggeln
if bit led_toggle
setb rc_led
clr led_toggle
else
clr rc_led
setb led_toggle
end if
;schleife zum empfang eines bytes
for r7=#8
mov a, @r0
clr cy
rlc a
clr p3.3
if not bit p3.2 then
setb acc.0
end if
mov @r0, a
;anzahl der hintereinander gleichen pegel zählen
if bit acc.0
if bit last_bit
inc nochange_cnt
else
mov nochange_cnt, #0h
setb last_bit
end if
else
if not bit last_bit
inc nochange_cnt
else
mov nochange_cnt, #0h
clr last_bit
end if
end if
;überschreitet die anzahl der hintereinander empfangen gleichen pegel
;eine grenze wird der signalempfang abgebrochen
mov a, nochange_cnt
if a=#max_nochange then
jmp abort_rc
end if
setb p3.3
;warten bis der timerabgelaufen ist
acall wait_for_t0
;timer neu starten
acall t0_go
next
;ein byte wurde komplett gesampelt
inc rc_cnt
inc r0
mov a, r0
;überlauf des speichers verhindern
if a=#end_addr
jmp abort_rc
end if
;nächstes byte sampeln
jmp next_byte
abort_rc:
;code empfange und zur kontrolle auf die ser. schnittstelle geben
;mov r0, #start_addr
;inc rc_cnt
;for r7=rc_cnt
; mov a, @r0
; acall send_a
; inc r0
;next
;dec rc_cnt
setb rc_led
setb have_code
reti
on_off:
mov a, prog_running
if a=#0h
acall get_active_ch
if a=#0h
mov a, #ffh
else
mov a, #0h
end if
mov @r0, a
else
mov prog_running, #0h
end if
ret
inc_ch:
acall get_active_ch
if a=max_active_ch
else
inc a
end if
mov @r0, a
ret
dec_ch:
acall get_active_ch
if a=#0h
else
dec a
end if
mov @r0, a
ret
inc_ch_step:
acall get_active_ch
clr cy
subb a, max_active_ch
dec a
clr cy
add a, #ch_step
if bit cy
mov a, max_active_ch
end if
mov @r0, a
ret
dec_ch_step:
acall get_active_ch
clr cy
subb a, #ch_step
if bit cy
mov a, #0h
end if
mov @r0, a
ret
;holt den wert des aktiven kanals nach a und dessen adresse nach r0
get_active_ch:
mov a, #ch_0
add a, active_ch
mov r0, a
mov a, @r0
ret
;schreibt die kanalwerte zu den cplds
write_ch:
mov ch_data_port, ch_0
clr ch0_le
setb ch0_le
mov ch_data_port, ch_1
clr ch1_le
setb ch1_le
mov ch_data_port, ch_2
clr ch2_le
setb ch2_le
mov ch_data_port, ch_3
clr ch3_le
setb ch3_le
ret
;sendet ein byte in a an die serielle schnittstelle
send_a:
clr ti
mov sbuf, a
loop while not bit ti
end loop
ret
;startet timer0 mit der sampleperiode für die aktuelle fernbedienung
t0_go:
mov TL0, #sample_time_lo
mov TH0, #sample_time_hi
clr tf0
setb tr0
ret
;startet timer0 mit maximaler periodendauer
t0_go_long:
mov TL0, #0h
mov TH0, #0h
clr tf0
setb tr0
ret
;wartet auf einen overflow von timer0
wait_for_t0:
loop while not bit tf0
end loop
ret
write_stats:
mov a, r7
send_a
mov a, ch_0
send_a
mov a, ch_1
send_a
mov a, ch_2
send_a
mov a, ch_3
send_a
ret
prog1:
mov a, #0
dec tp1
if a=tp1
mov tp1, #1h
dec tp2
if a=tp2
mov tp2, #ffh
acall prog1_action
end if
end if
acall write_ch
ret
prog1_action:
if bit dir_0
inc ch_0
mov a, #ffh
if a=ch_0
cpl dir_0
jmp a1
else
ret
end if
else
dec ch_0
mov a, #1h
if a=ch_0
cpl dir_0
jmp a1
else
ret
end if
end if
a1:
if bit dir_1
inc ch_1
mov a, #ffh
if a=ch_1
cpl dir_1
jmp a2
else
ret
end if
else
dec ch_1
mov a, #1h
if a=ch_1
cpl dir_1
jmp a2
else
ret
end if
end if
a2:
if bit dir_2
inc ch_2
mov a, #ffh
if a=ch_2
cpl dir_2
jmp a3
else
ret
end if
else
dec ch_2
mov a, #1h
if a=ch_2
cpl dir_2
jmp a3
else
ret
end if
end if
a3:
if bit dir_3
inc ch_3
mov a, #ffh
if a=ch_3
cpl dir_3
jmp a4
else
ret
end if
else
dec ch_3
mov a, #1h
if a=ch_3
cpl dir_3
jmp a4
else
ret
end if
end if
a4:
ret
prog2_init:
mov ch_0 ,#1
mov ch_1, #feh
mov ch_2, #feh
mov ch_3, #feh
mov prog_state, #0
ret
prog2:
mov a, #0
dec tp1
if a=tp1
mov tp1, #1h
dec tp2
if a=tp2
mov tp2, #ffh
acall prog2_action
end if
end if
acall write_ch
ret
prog2_action:
mov a, prog_state
if a=#0
inc ch_0
dec ch_1
mov a, ch_1
if a=#1
mov prog_state, #1
end if
elseif a=#1
inc ch_1
dec ch_2
mov a, ch_2
if a=#1
mov prog_state, #2
end if
elseif a=#2
inc ch_2
dec ch_3
mov a, ch_3
if a=#1
mov prog_state, #3
end if
elseif a=#3
inc ch_3
dec ch_0
mov a, ch_0
if a=#1
mov prog_state, #0
end if
end if
ret
Quelltext rc_uni140.a51:
; Definitionen für die Fernbedienung Medion Universal Code 140
; Controller bei 15,36 MHz
#const sample_time_hi=fdh ;16bit Timerwert für das Sampleintervall
#const sample_time_lo=3ch ;38 -> 40 -> 48
#const rc_id_len=8 ;Länge der Fernbedienungskennung (-1)
#const rc_repeat_len=2 ;Länge der Repeatkennung (-1)
#const known_codes=19 ;Anzahl der Tastencodes (s.u.)
#const code_pos=9 ;Position des Tastencodes in den empfangenen Daten
#const code_len=5 ;Länge eines Tastencodes
;Kennung der Fernbedienung
rc_id_tab:
db FFh, FFh, 80h, 55h, 45h, 14h, 44h, 45h, 14h
rc_repeat_tab:
db FFh, FFh, 84h
; Tastencodes
code_tab:
db 45h, 45h, 55h, 11h, 44h ;rot
db 44h, 45h, 55h, 54h, 44h ;gruen
db 45h, 15h, 45h, 45h, 11h ;gelb
db 45h, 51h, 55h, 11h, 14h ;blau
db 44h, 45h, 15h, 55h, 14h ;power
db 51h, 51h, 54h, 51h, 14h ;vol+
db 45h, 14h, 55h, 45h, 14h ;vol-
db 45h, 44h, 55h, 44h, 54h ;ch+
db 55h, 11h, 54h, 44h, 54h ;ch-
db 45h, 11h, 55h, 45h, 44h ;1
db 51h, 11h, 55h, 15h, 44h ;2
db 44h, 44h, 55h, 55h, 44h ;3
db 54h, 44h, 55h, 11h, 54h ;4
db 45h, 11h, 15h, 51h, 54h ;5
db 51h, 11h, 15h, 45h, 54h ;6
db 44h, 44h, 45h, 55h, 54h ;7
db 54h, 55h, 51h, 14h, 44h ;8
db 45h, 15h, 55h, 14h, 44h ;9
db 54h, 45h, 54h, 45h, 44h ;0
4 Farben LED-Leiste Index