4 Farben LED-Leiste: Software





Sourcecode ir8051.a51, rc_uni140.inc.txt
Hexfile ir8051.hex




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