PIC16F877マイコンでマルチタスクプログラミング

http://www.youtube.com/watch?v=YoJia_a6zJw


PICマイコンマルチタスクプログラミングができるというのWEBサイトを見つけて、やってみることにしました。
http://www.mars.dti.ne.jp/~m7030/pic_room/hinagata.html
http://www.mars.dti.ne.jp/~m7030/pic_room/kantan.html




PIC アセンブラ test2.asm

	list	p=16f877a
	include	<p16f877a.inc>
	__CONFIG	_CP_OFF & _WDT_ON & _BODEN_ON & _PWRTE_ON & _XT_OSC & _WRT_OFF & _LVP_OFF & _CPD_OFF

	radix	dec
	errorlevel	-302

	extern	Func1, Func2
	extern	gTimer1, gTimer2

SHARE	UDATA_SHR
w_temp		res	1

BANK0	UDATA
status_temp	res	1
pclath_temp	res	1

timer		res	1

context1		res	2
context2		res	2

#define	kWinkTime	122
#define	kLedPort		PORTB,0

STARTUP	CODE
	nop
	goto	Main

	nop
	nop
	movwf	w_temp
	movf	STATUS,W
	banksel	status_temp
	movwf	status_temp

	bcf	INTCON,T0IF

	movf	timer,F
	btfss	STATUS,Z
	decf	timer,F

	movf	gTimer1,F
	btfss	STATUS,Z
	decf	gTimer1,F

	movf	gTimer2,F
	btfss	STATUS,Z
	decf	gTimer2,F

	movf    status_temp,W
	movwf	STATUS
	swapf   w_temp,F
	swapf   w_temp,W
	retfie

PROG1	CODE

CallTask macro
	pagesel	ContextSw1
	call	ContextSw1
	movwf	context1+1
	movf	PCLATH,W
	movwf	context1
	pagesel	ContextSw2
	call	ContextSw2
	movwf	context2+1
	movf	PCLATH,W
	movwf	context2
	pagesel	$
	endm

ContextSw1:
	movf	context1,W
	movwf	PCLATH
	movf	context1+1,W
	movwf	PCL

ContextSw2:
	movf	context2,W
	movwf	PCLATH
	movf	context2+1,W
	movwf	PCL

ContextInit:
	movlw	high(Func1)
	movwf	context1
	movlw	low(Func1)
	movwf	context1+1

	movlw	high(Func2)
	movwf	context2
	movlw	low(Func2)
	movwf	context2+1
	return

Main:
	clrwdt
	pagesel	Init
	call	Init
	pagesel	ContextInit
	call	ContextInit
MainLoop:
	movlw	kWinkTime
	movwf	timer

	pagesel	MainLoop

	movlw	kWinkTime
	movwf	timer
WaitOn:
	clrwdt
	CallTask
	bsf	kLedPort
	movf	timer,F
	bnz	WaitOn

	movlw	kWinkTime
	movwf	timer
WaitOff:
	clrwdt
	CallTask
	bcf	kLedPort
	movf	timer,F
	bnz	WaitOff

	goto	MainLoop

PROG2	CODE
Init:
	banksel	OPTION_REG
	movlw	0x83
	movwf	OPTION_REG

	banksel	INTCON
	movlw	0x20
	movwf	INTCON
#ifdef ADCON1
	banksel	ADCON1
	movlw	0x06
	movwf	ADCON1
#endif
	banksel	TRISB
	bcf	TRISB,0
	bcf	TRISB,1
	bcf	TRISB,2
	banksel	INTCON
	bsf	INTCON,GIE
	return

	end




PIC アセンブラ task.asm

	list	p=16f877a
	include	<p16f877a.inc>

	radix	dec
	errorlevel	-302

	global	Func1, Func2
	global	gTimer1, gTimer2


BANK0	UDATA
gTimer1		res	1
gTimer2		res	1

#define	kTime1	81	;4.096(mS)x81=約333(mS)
#define	kTime2	61	;4.096(mS)x61=約250(mS)
#define	kOutPort1 PORTB,1
#define	kOutPort2 PORTB,2

SwTask	macro
	LOCAL	Next
	movlw	high(Next)
	movwf	PCLATH
	retlw	low(Next)
Next:
	endm

PROG2	CODE
Func1:
	movlw	kTime1
	movwf	gTimer1
WaitOn1:
	SwTask
	bsf	kOutPort1
	movf	gTimer1,F
	bnz	WaitOn1

	movlw	kTime1
	movwf	gTimer1
WaitOff1:
	SwTask
	bcf	kOutPort1
	movf	gTimer1,F
	bnz	WaitOff1

	goto	Func1

Func2:
	movlw	kTime2
	movwf	gTimer2
WaitOn2:
	SwTask
	bsf	kOutPort2
	movf	gTimer2,F
	bnz	WaitOn2

	movlw	kTime2
	movwf	gTimer2
WaitOff2:
	SwTask
	bcf	kOutPort2
	movf	gTimer2,F
	bnz	WaitOff2

	goto	Func2


	end




PIC アセンブラ task.lkr

CODEPAGE	NAME=startup	START=0x0000	END=0x00ff
CODEPAGE	NAME=page0	START=0x0100	END=0x07ff
CODEPAGE	NAME=page1	START=0x0800	END=0x0fff

CODEPAGE	NAME=.config	START=0x2007	END=0x2007

SHAREBANK NAME=share	START=0x20	END=0x20
SHAREBANK NAME=share	START=0xa0	END=0xa0
SHAREBANK NAME=share	START=0x120	END=0x120
SHAREBANK NAME=share	START=0x1a0	END=0x1a0

DATABANK	NAME=gpr0	START=0x21	END=0x6f

SECTION	NAME=STARTUP	ROM=startup
SECTION	NAME=PROG1	ROM=page0
SECTION	NAME=PROG2	ROM=page1

SECTION	NAME=SHARE	RAM=share
SECTION	NAME=BANK0	RAM=gpr0