目次

通過カウンタ

 8048で通過カウンタを実現します。

 タイマー割込みを利用し、ゲートの出力が
 変化したことをトリガーを捉えて、内部の
 カウンタをインクリメントします。

 タイマー割込みで、入力ピンの変化(L→H)を
 捉えます。

 8048では、10進補正を実行し、BCD(Binary Coded
  Decimal)により、外部のレジスタに数値を出力する
 と仕様を決めました。

 カウンタ値の出力回路は、以下。



 メモリ内にあるDIG0、DIG1、DIG2、DIG3に1桁ごとに
 4桁の数値が含まれているとして、サブルーチンを作成。

SND_CNT:
	; set pointer
	mov	r0,#DIG0
	; get lower
	mov	a,@r0
	; mask
	anl	a,#0fh
	; exchange nibble
	swap	a
	; update pointer (set DIG1 address)
	inc	r0
	; add
	add	a,@r0
	; exchange nibble
	swap	a
	; transfer
	mov	r6,a
	; update pointer (set DIG2 address)
	inc	r0
	; get lower
	mov	a,@r0
	; mask
	anl	a,#0fh
	; exchange nibble
	swap	a
	; update pointer (set DIG3 address)
	inc	r0
	; add
	add	a,@r0
	; exchange nibble
	swap	a
	; transfer
	mov	r7,a
	; upper counter
	mov	a,r7
	; impress
	outl	P1,a
	; send trigger
	in	a,P2
	anl	a,#0dfh
	outl	P2,a
	orl	a,#20h
	outl	P2,a
	anl	a,#0dfh
	outl	P2,a
	; lower counter
	mov	a,r6
	; impress
	outl	P1,a
	; send trigger
	in	a,P2
	anl	a,#0efh
	outl	P2,a
	orl	a,#10h
	outl	P2,a
	anl	a,#0efh
	outl	P2,a
	;
	ret

 レジスタr2で、タイマー割込みが発生するごとに
 シフトして、ゲートセンサーの論理値を入力。

 タイマー割込みが発生したときには、イベント通知
 のフラグだけを設定しておきます。

 割込みが発生したときには、極力処理をしないで
 おいた方がよいので、イベント通知フラグセット
 だけにしておきます。

TIM_HND:
	; set flag
	mov	@r0,#1
	; stop counter
	stop	tcnt
	; initialize
	mov	a,#TZERO
	mov	t,a
	; start timer
	strt	t
	;
	retr

 メインルーチンでイベント通知フラグを
 監視して、セットされたならばレジスタr2
 の値をシフトして、ゲートの状態により
 カウンタをインクリメントします。

MAIN:
	; get flag
	mov	a,@r0
	; judge
	anl	a,#1
	jz	MAINL
	; clear flag
	mov	@r0,#0
	; ?
	; ??
	; update counter
	call	SND_CNT
	;
MAINL:
	;
	jmp	MAIN

 レジスタr2の値が2進数で01であれば
 通過物体があるので、カウンタをインクリメント。
 これをサブルーチンとします。

GET_GATE:
	; get register value
	xch	a,r2
	; shift
	rl	a
	; mask
	anl	a,#03h
	; resume
	xch	a,r2
	; get gate state
	in	a,P2
	anl	a,#80h
	; judge
	jz	GET_GATE1
	; increment
	inc	r2
	;
GET_GATE1:
	xch	a,r2
	; judge
	anl	a,#01h
	jz	GET_GATE2
	; increment
	inc	@r1
GET_GATE2:
	;
	ret

 メモリに用意した4桁のカウンタDIG0からDIG3の値が
 10より大きくなっていれば、桁上げと該当桁にゼロを
 設定します。

 サブルーチンでは、以下のように処理。

ADJ_CNT:
	; set pointer
	mov	r1,#DIG0
	; judge = 10
	mov	a,#0f7h
	add	a,@r1
	jz	ADJ_CNT1
	jmp	ADJ_CNTE
	; DIG0 <- 0 , DIG1 <- DIG1 + 1
ADJ_CNT1:
	mov	@r1,#0
	; update pointer (#DIG1)
	inc	r1
	; judge = 10
	mov	a,#0f7h
	add	a,@r1
	jz	ADJ_CNT2
	jmp	ADJ_CNTE
	; DIG1 <- 0 , DIG2 <- DIG2 + 1
ADJ_CNT2:
	mov	@r1,#0
	; update pointer (#DIG2)
	inc	r1
	; judge = 10
	mov	a,#0f7h
	add	a,@r1
	jz	ADJ_CNT3
	jmp	ADJ_CNTE
	; DIG2 <- 0 , DIG3 <- DIG3 + 1
ADJ_CNT3:
	mov	@r1,#0
	; update pointer (#DIG3)
	inc	r1
	; judge = 10
	mov	a,#0f7h
	add	a,@r1
	jz	ADJ_CNT4
	jmp	ADJ_CNTE
	;
ADJ_CNT4:
	mov	@r1,#0
	;
ADJ_CNTE
	;

 下の桁から順次、インクリメントするので
 10になっているか否かで、判定と設定にして
 あります。

 カウンタの補正ができれば、MAINは単純な
 サブルーチン呼び出しをすれば、よいだけ。

MAIN:
	; get flag
	mov	a,@r0
	; judge
	anl	a,#1
	jz	MAINL
	; clear flag
	mov	@r0,#0
	; judge 
	call	GET_GATE
	; adjust
	call	ADJ_CNT
	; update counter
	call	SND_CNT
	;
MAINL:
	;
	jmp	MAIN

 部品が揃ったので合体。

;
;	TEST program for 8048 ( PROASM-II )
;	Copyright (C) 2018 Kensuke Ooyu
;
	INCLUDE 8048.LIB

;*******************
; value and address 
;*******************
TZERO	equ	6
DIG0	equ	18h
DIG1	equ	19h
DIG2	equ	1Ah
DIG3	equ	1Bh
TFLAG	equ	1Ch

;****************
; define symbols
;****************
ENTRY	equ	0h
E_INT	equ	3h
E_TIM	equ	7h

;*******************
; interrupt vectors
;*******************
	org	ENTRY
	jmp	START

	; external interrupt
	org	E_INT
	retr

	; timer interrupt
	org	E_TIM
	jmp	TIM_HND

	org	10h
;**************
; sub routines
;**************
INIT:
	; disable external interrupt
	dis	i

	; disable timer interrupt
	dis	tcnti

	; initialize I/O
	clr	a
	outl	P1,a
	outl	P2,a

	; set pointer
	mov	r0,#TFLAG
	mov	r1,#DIG0
	; clear flag
	mov	@r0,#0

	; clear resigters
	clr	a
	mov	r2,a
	mov	r3,a
	mov	r4,a
	mov	r5,a
	mov	r6,a
	mov	r7,a

	ret

INIT_TIM:
	; stop counter
	stop	tcnt
	; initialize
	mov	a,#TZERO
	mov	t,a
	; start timer
	strt	t
	;
	ret

TIM_HND:
	; set flag
	mov	@r0,#1
	; stop counter
	stop	tcnt
	; initialize
	mov	a,#TZERO
	mov	t,a
	; start timer
	strt	t
	;
	retr

CLR_DIG:
	; set pointer
	mov	r0,#DIG0
	; set zero
	clr	a
	; set counter
	mov	r2,#4
	; copy
CLR_DIGL:
	mov	@r0,a
	inc	r0
	djnz	r2,CLR_DIGL
	;
	ret

SND_CNT:
	; set pointer
	mov	r0,#DIG0
	; get lower
	mov	a,@r0
	; mask
	anl	a,#0fh
	; exchange nibble
	swap	a
	; update pointer (set DIG1 address)
	inc	r0
	; add
	add	a,@r0
	; exchange nibble
	swap	a
	; transfer
	mov	r6,a
	; update pointer (set DIG2 address)
	inc	r0
	; get lower
	mov	a,@r0
	; mask
	anl	a,#0fh
	; exchange nibble
	swap	a
	; update pointer (set DIG3 address)
	inc	r0
	; add
	add	a,@r0
	; exchange nibble
	swap	a
	; transfer
	mov	r7,a
	; upper counter
	mov	a,r7
	; impress
	outl	P1,a
	; send trigger
	in	a,P2
	anl	a,#0dfh
	outl	P2,a
	orl	a,#20h
	outl	P2,a
	anl	a,#0dfh
	outl	P2,a
	; lower counter
	mov	a,r6
	; impress
	outl	P1,a
	; send trigger
	in	a,P2
	anl	a,#0efh
	outl	P2,a
	orl	a,#10h
	outl	P2,a
	anl	a,#0efh
	outl	P2,a
	;
	ret

GET_GATE:
	; get register value
	xch	a,r2
	; shift
	rl	a
	; mask
	anl	a,#03h
	; resume
	xch	a,r2
	; get gate state
	in	a,P2
	anl	a,#80h
	; judge
	jz	GET_GATE1
	; increment
	inc	r2
	;
GET_GATE1:
	xch	a,r2
	; judge
	anl	a,#01h
	jz	GET_GATE2
	; increment
	inc	@r1
GET_GATE2:
	;
	ret

ADJ_CNT:
	; set pointer
	mov	r1,#DIG0
	; judge = 10
	mov	a,#0f7h
	add	a,@r1
	jz	ADJ_CNT1
	jmp	ADJ_CNTE
	; DIG0 <- 0 , DIG1 <- DIG1 + 1
ADJ_CNT1:
	mov	@r1,#0
	; update pointer (#DIG1)
	inc	r1
	; judge = 10
	mov	a,#0f7h
	add	a,@r1
	jz	ADJ_CNT2
	jmp	ADJ_CNTE
	; DIG1 <- 0 , DIG2 <- DIG2 + 1
ADJ_CNT2:
	mov	@r1,#0
	; update pointer (#DIG2)
	inc	r1
	; judge = 10
	mov	a,#0f7h
	add	a,@r1
	jz	ADJ_CNT3
	jmp	ADJ_CNTE
	; DIG2 <- 0 , DIG3 <- DIG3 + 1
ADJ_CNT3:
	mov	@r1,#0
	; update pointer (#DIG3)
	inc	r1
	; judge = 10
	mov	a,#0f7h
	add	a,@r1
	jz	ADJ_CNT4
	jmp	ADJ_CNTE
	;
ADJ_CNT4:
	mov	@r1,#0
	;
ADJ_CNTE
	;
	ret

;**************
; main routine
;**************
	org	100h
START:
	call	INIT
	call	CLR_DIG
	call	INIT_TIM
	; clear counter
	call	SND_CNT
	; enable
	en	TCNTI
MAIN:
	; get flag
	mov	a,@r0
	; judge
	anl	a,#1
	jz	MAINL
	; clear flag
	mov	@r0,#0
	; judge 
	call	GET_GATE
	; adjust
	call	ADJ_CNT
	; update counter
	call	SND_CNT
	;
MAINL:
	;
	jmp	MAIN

	end

 アセンブリリストは、以下。

0000          	;
0000          	;	TEST program for 8048 ( PROASM-II )
0000          	;	Copyright (C) 2018 Kensuke Ooyu
0000          	;
0000          		INCLUDE 8048.LIB
0000          		list
0000          	
0000          	;*******************
0000          	; value and address 
0000          	;*******************
0006          	TZERO	equ	6
0018          	DIG0	equ	18h
0019          	DIG1	equ	19h
001A          	DIG2	equ	1Ah
001B          	DIG3	equ	1Bh
001C          	TFLAG	equ	1Ch
0000          	
0000          	;****************
0000          	; define symbols
0000          	;****************
0000          	ENTRY	equ	0h
0003          	E_INT	equ	3h
0007          	E_TIM	equ	7h
0000          	
0000          	;*******************
0000          	; interrupt vectors
0000          	;*******************
0000          		org	ENTRY
0000 2400    +		jmp	START
0002
0002          		; external interrupt
0002          		org	E_INT
0003 93      +		retr
0004
0004          		; timer interrupt
0004          		org	E_TIM
0007 0429    +		jmp	TIM_HND
0009
0009          		org	10h
0010          	;**************
0010          	; sub routines
0010          	;**************
0010          	INIT:
0010          		; disable external interrupt
0010 15      +		dis	i
0011
0011          		; disable timer interrupt
0011 35      +		dis	tcnti
0012
0012          		; initialize I/O
0012 27      +		clr	a
0013 39      +		outl	P1,a
0014 3A      +		outl	P2,a
0015
0015          		; set pointer
0015 B81C    +		mov	r0,#TFLAG
0017 B918    +		mov	r1,#DIG0
0019          		; clear flag
0019 B000    +		mov	@r0,#0
001B
001B          		; clear resigters
001B 27      +		clr	a
001C AA      +		mov	r2,a
001D AB      +		mov	r3,a
001E AC      +		mov	r4,a
001F AD      +		mov	r5,a
0020 AE      +		mov	r6,a
0021 AF      +		mov	r7,a
0022
0022 83      +		ret
0023
0023          	INIT_TIM:
0023          		; stop counter
0023 65      +		stop	tcnt
0024          		; initialize
0024 2306    +		mov	a,#TZERO
0026 62      +		mov	t,a
0027          		; start timer
0027 55      +		strt	t
0028          		;
0028 83      +		ret
0029
0029          	TIM_HND:
0029          		; set flag
0029 B001    +		mov	@r0,#1
002B          		; stop counter
002B 65      +		stop	tcnt
002C          		; initialize
002C 2306    +		mov	a,#TZERO
002E 62      +		mov	t,a
002F          		; start timer
002F 55      +		strt	t
0030          		;
0030 93      +		retr
0031
0031          	CLR_DIG:
0031          		; set pointer
0031 B818    +		mov	r0,#DIG0
0033          		; set zero
0033 27      +		clr	a
0034          		; set counter
0034 BA04    +		mov	r2,#4
0036          		; copy
0036          	CLR_DIGL:
0036 A0      +		mov	@r0,a
0037 18      +		inc	r0
0038 EA36    +		djnz	r2,CLR_DIGL
003A          		;
003A 83      +		ret
003B
003B          	SND_CNT:
003B          		; set pointer
003B B818    +		mov	r0,#DIG0
003D          		; get lower
003D F0      +		mov	a,@r0
003E          		; mask
003E 530F    +		anl	a,#0fh
0040          		; exchange nibble
0040 47      +		swap	a
0041          		; update pointer (set DIG1 address)
0041 18      +		inc	r0
0042          		; add
0042 60      +		add	a,@r0
0043          		; exchange nibble
0043 47      +		swap	a
0044          		; transfer
0044 AE      +		mov	r6,a
0045          		; update pointer (set DIG2 address)
0045 18      +		inc	r0
0046          		; get lower
0046 F0      +		mov	a,@r0
0047          		; mask
0047 530F    +		anl	a,#0fh
0049          		; exchange nibble
0049 47      +		swap	a
004A          		; update pointer (set DIG3 address)
004A 18      +		inc	r0
004B          		; add
004B 60      +		add	a,@r0
004C          		; exchange nibble
004C 47      +		swap	a
004D          		; transfer
004D AF      +		mov	r7,a
004E          		; upper counter
004E FF      +		mov	a,r7
004F          		; impress
004F 39      +		outl	P1,a
0050          		; send trigger
0050 0A      +		in	a,P2
0051 53DF    +		anl	a,#0dfh
0053 3A      +		outl	P2,a
0054 4320    +		orl	a,#20h
0056 3A      +		outl	P2,a
0057 53DF    +		anl	a,#0dfh
0059 3A      +		outl	P2,a
005A          		; lower counter
005A FE      +		mov	a,r6
005B          		; impress
005B 39      +		outl	P1,a
005C          		; send trigger
005C 0A      +		in	a,P2
005D 53EF    +		anl	a,#0efh
005F 3A      +		outl	P2,a
0060 4310    +		orl	a,#10h
0062 3A      +		outl	P2,a
0063 53EF    +		anl	a,#0efh
0065 3A      +		outl	P2,a
0066          		;
0066 83      +		ret
0067
0067          	GET_GATE:
0067          		; get register value
0067 2A      +		xch	a,r2
0068          		; shift
0068 E7      +		rl	a
0069          		; mask
0069 5303    +		anl	a,#03h
006B          		; resume
006B 2A      +		xch	a,r2
006C          		; get gate state
006C 0A      +		in	a,P2
006D 5380    +		anl	a,#80h
006F          		; judge
006F C672    +		jz	GET_GATE1
0071          		; increment
0071 1A      +		inc	r2
0072          		;
0072          	GET_GATE1:
0072 2A      +		xch	a,r2
0073          		; judge
0073 5301    +		anl	a,#01h
0075 C678    +		jz	GET_GATE2
0077          		; increment
0077 11      +		inc	@r1
0078          	GET_GATE2:
0078          		;
0078 83      +		ret
0079
0079          	ADJ_CNT:
0079          		; set pointer
0079 B918    +		mov	r1,#DIG0
007B          		; judge = 10
007B 23F7    +		mov	a,#0f7h
007D 61      +		add	a,@r1
007E C682    +		jz	ADJ_CNT1
0080 04A2    +		jmp	ADJ_CNTE
0082          		; DIG0 <- 0 , DIG1 <- DIG1 + 1
0082          	ADJ_CNT1:
0082 B100    +		mov	@r1,#0
0084          		; update pointer (#DIG1)
0084 19      +		inc	r1
0085          		; judge = 10
0085 23F7    +		mov	a,#0f7h
0087 61      +		add	a,@r1
0088 C68C    +		jz	ADJ_CNT2
008A 04A2    +		jmp	ADJ_CNTE
008C          		; DIG1 <- 0 , DIG2 <- DIG2 + 1
008C          	ADJ_CNT2:
008C B100    +		mov	@r1,#0
008E          		; update pointer (#DIG2)
008E 19      +		inc	r1
008F          		; judge = 10
008F 23F7    +		mov	a,#0f7h
0091 61      +		add	a,@r1
0092 C696    +		jz	ADJ_CNT3
0094 04A2    +		jmp	ADJ_CNTE
0096          		; DIG2 <- 0 , DIG3 <- DIG3 + 1
0096          	ADJ_CNT3:
0096 B100    +		mov	@r1,#0
0098          		; update pointer (#DIG3)
0098 19      +		inc	r1
0099          		; judge = 10
0099 23F7    +		mov	a,#0f7h
009B 61      +		add	a,@r1
009C C6A0    +		jz	ADJ_CNT4
009E 04A2    +		jmp	ADJ_CNTE
00A0          		;
00A0          	ADJ_CNT4:
00A0 B100    +		mov	@r1,#0
00A2          		;
00A2          	ADJ_CNTE
00A2          		;
00A2 83      +		ret
00A3
00A3          	;**************
00A3          	; main routine
00A3          	;**************
00A3          		org	100h
0100          	START:
0100 1410    +		call	INIT
0102 1431    +		call	CLR_DIG
0104 1423    +		call	INIT_TIM
0106          		; clear counter
0106 143B    +		call	SND_CNT
0108          		; enable
0108 25      +		en	TCNTI
0109          	MAIN:
0109          		; get flag
0109 F0      +		mov	a,@r0
010A          		; judge
010A 5301    +		anl	a,#1
010C C616    +		jz	MAINL
010E          		; clear flag
010E B000    +		mov	@r0,#0
0110          		; judge 
0110 1467    +		call	GET_GATE
0112          		; adjust
0112 1479    +		call	ADJ_CNT
0114          		; update counter
0114 143B    +		call	SND_CNT
0116          		;
0116          	MAINL:
0116          		;
0116 2409    +		jmp	MAIN
0118
0118          		end

 HEXファイルは、次のようになります。

:020000002400DA
:010003009369
:020007000429CA
:10001000153527393AB81CB918B00027AAABACADD2
:10002000AEAF83652306625583B001652306625532
:1000300093B81827BA04A018EA3683B818F0530FFB
:1000400047186047AE18F0530F47186047AFFF39A5
:100050000A53DF3A43203A53DF3AFE390A53EF3A64
:1000600043103A53EF3A832AE753032A0A5380C6D0
:10007000721A2A5301C6781183B91823F761C68210
:1000800004A2B1001923F761C68C04A2B1001923A0
:10009000F761C69604A2B1001923F761C6A004A2B5
:0300A000B1008329
:10010000141014311423143B25F05301C616B0000B
:0801100014671479143B240963
:00000001FF


目次

inserted by FC2 system