; 23.12.2002 19:59:29

#cpu = 89S53	; @3,6 MHz

#Const byte_per_pattern=04h

#Bit Empfang, Sendebusy
#Bit timer_ret
#Byte chan_1, chan_2, chan_3, chan_4
#Byte next_out, next_port_out
 
;Registervereinbahrungen:
;r7 ... chan_1 counter
;r6 ... r5 .... r4 counter für 2, 3, 4
;r0 als bit counter


ajmp Initialisierung

Timer 0:	; Timer 0 Interrupt
	ajmp Timer 0 Interrupt

SINT:	; serieller Interrupt
	ajmp Serieller Interrupt

Initialisierung:

; Serieller Port
mov SCON, # D0h	; Modus 3, asynchron, 11 Bit, Baudrate Timer 1/2 Überlauf, Datenempfang freigeben
mov TMOD, # 20h	; Timer 1 Autoreloadmodus
mov TH1, # FCh	; Reloadwert für Baudrate 20833,33
setb TR1	; Timer 1 Start
orl TMOD, # 02h	; Timer 0 im 8-Bit Autoreload-Modus.
; Die Überlauffrequenz des Timer 0 beträgt 2000000 Hz, die Periodendauer 0,0005 ms.
mov TH0, #c0h	; Reloadwert

; Interrupts
setb ET0	; Timer 0 Interrupt freigeben
;setb PT0	; Priorität für Timer 0 Interrupt
setb ES	; seriellen Interrupt freigeben
setb EA	; globale Interruptfreigabe

;mögliche Channelwerte: 01h-21h (00h nicht erlaubt!! (bzw immer an))

mov chan_1, #21h
mov chan_2, #18h
mov chan_3, #10h
mov chan_4, #05h

mov r7, chan_1
mov r6, chan_2
mov r5, chan_3
mov r4, chan_4

mov r0, #20h

setb timer_ret
clr Empfang

mov dptr, #copyr
mov r0, #copyend-copyr
for r0
	clr a	
	movc a, @a+dptr
	inc dptr
	acall Sende
next

setb TR0	; Timer 0 läuft.

main:
	if bit Empfang then
		clr Empfang
		acall Serielle Daten auswerten
		mov r2,a
		anl a, #1fh
		mov r3, a
		mov a, r2		
		anl a, #c0h
		rl a
		rl a
		if a=#00h
			mov chan_1,r3
		elseif a=#01h
			mov chan_2, r3
		elseif a=#10h
			mov chan_3,r3
		elseif a=#11h
			mov chan_4,r3
		end if
		mov a, #61h
		call Sende
		mov a, #6bh
		call Sende	
	end if
	jb timer_ret, calc_pattern	
jmp main


calc_pattern:
	;Channel 1
	dec r7
	if r7=#0h
		inc r7
		mov next_out, #00h
	else
		mov next_out, #80h
	end if
	;Channel 2
	dec r6
	if r6=#0h
		inc r6
	else

		mov a, #40h
		orl a, next_out
		mov next_out, a
	end if
	;Channel 3
	dec r5
	if r5=#0h
		inc r5
	else
		mov a, #20h
		orl a, next_out
		mov next_out, a
	end if
	;Channel 4
	dec r4
	if r4=#0h
		inc r4
		mov a, next_out	
	else
		mov a, #10h
		orl a, next_out
	end if
	mov next_port_out, a
	clr timer_ret
jmp main

Serielle Daten auswerten:
	mov a, SBUF
	; weitere Befehle
ret

Sende:	; Sendewert in a
	jb Sendebusy, hier	; auf Sendefreigabe warten
	mov SBUF, a
	setb Sendebusy
ret

Timer 0 Interrupt:
	mov r1, a
	mov a, next_port_out
	mov p1, a
	dec r0
	if r0=#0h
		mov r7, chan_1
		mov r6, chan_2
		mov r5, chan_3
		mov r4, chan_4
		mov r0, #20h
	end if
	setb timer_ret
	mov a, r1
reti

Serieller Interrupt:
	; Herkunft ermitteln
	if bit TI then	; Senden
		clr TI
		clr Sendebusy
	else	; Empfangen
		clr RI
		setb Empfang
	end if
reti


copyr:
DB '************************************************'
DB '8051 PWM Lüftersteuerung (c) 2003'
DB ' Hardware by Runni, Software by elHakim'
DB '************************************************'
copyend: