目次

PIC10活用

 8ピンの手軽なマイコンとして使ってきたPIC12F1501の
 値段が、半導体不足で一気に値上がりしました。



 はじめてPIC12F1501を入手した頃は、¥70だったのが
 2023年2月現在では、¥140と2倍の金額に。

 ハードウエアの置き換えに、金額がかかり過ぎるのは問題。
 8ピンで安価なPICマイコンがないのかを探そう。

 こう考えて秋月電子のサイトを見ると、PIC10F322が出て
 きました。



 仕様を見てみます。



 プログラムメモリは、512ワード(256バイト)で
 RAMが64バイトというので、ハードウエアを置換え
 する用途では、充分と判断。

 利用できるGPIOが4ピンなので、2入力1出力という
 条件を入れて使えば、問題はない。

 こう判断して回路で使うために、ピン配置を確認。



 6ピンと8ピンのデバイスがって、8ピンだと
 リセットピンが8番ピンに割当て。

 8ピンのICソケットを使って、基板に実装すれば
 リセット回路だけに注意して半田付けするとよい
 と判断。

 GPIOで使いたい機能をリストして、利用するか否か
 の判断をしてみます。

 備えていればよい機能は、以下。

 データシートで、これらの機能を具備しているか確認。



 内蔵レジスタの表から、プルアップ抵抗、外部割込み
 タイマー割込みができると理解しました。

 内蔵クロックの周波数を、ブロック図から確認。



 ハードウエアを置換えるとして、1MHz以上の
 クロックで動作するとすれば、充分だと認識して
 いるので、問題はないでしょう。

 次の回路を、PIC10F322で置換えて、プログラム
 サイズがどのくらいになるか、試してみます。



 スイッチの接続は、以下。



 動作は、次のタイミングチャートを実現すると仮定。



 GreateCowBasicを利用して、プログラムを作成してみます。



 クロックを4MHzとして、内蔵にします。
 また、リセットピンを活用に指定。

#chip 10F322,4
#config MCLRE = On , OSC = Int

 4MHzを分周して、タイマー0に与えて1kHzを生成。



 このカラクリは、以下。

 システムクロックの1/4である1MHzを
 プリスケーラで1/4として250kHzを
 生成。
 250kHzを250分周して、1kHzの
 生成とする。

 これをBasicのコードで指定。

InitTimer0 Osc,PS0_4
On Interrupt Timer0Overflow Call t0EXEC

 1kHzでタイマー割込みを発生させて
 変数millisのインクリメントを実現。

Sub t0EXEC
  ' initialize
  TMR0 = 6
  ' increment
  millis = millis + 1
End Sub

 カウンタTMR0に6を設定しているのは
 255から0に変化するときに割込み
 を発生させるので、256-6=250として
 250分周に持ち込むため。

 変数millisの値を参照して、インターバルを
 求めれられれば、いろいろな応用ができると
 考えて、タイマー割込みでインクリメントと
 します。

 変数millisをシステムタイマーのカウント値に
 していると、シフトレジスタを使い、スイッチ
 のチャタリングを除去できます。

 2個のスイッチのチャタリング除去は、次のように
 まとめて処理できます。

Sub getSW
  ' time interval
  tflag = 0
  gcur = millis
  tmpx = gcur - gpre
  If tmpx >= GINTERVAL Then
    gpre = gcur
    tflag = 1
  End If
  IF tflag = 0 Then
    return
  End If
    ' shift
  xpsw_sft = xpsw_sft * 2
  xwsw_sft = xwsw_sft * 2
  ' mask
  xpsw_sft = xpsw_sft and 0b00001111
  xwsw_sft = xwsw_sft and 0b00001111
  ' update LSB
  ptmp = PORTA
  If (ptmp and 2) = 0 Then
    xpsw_sft = xpsw_sft + 1
  End If
  If (ptmp and 4) = 0 Then
    xwsw_sft = xwsw_sft + 1
  End If
  ' judge
  eflag = 0
  If xpsw_sft = 7 Then
    eflag = 1
  End if
  If xwsw_sft = 7 Then
    eflag = 1
  End if
End Sub

 指定時間を経過するたびに、スイッチの状態を入力して
 レジスタ値を更新していきます。
 レジスタ値が規定値になったら、フラグで出力論理レベル
 を扱うブロックに通知。

 出力論理レベルを扱うブロックは、ステートマシンを
 使って、規定時間だけ'H'を出力させます。

 ステートマシンは、次の状態遷移図で表現。



 プログラムでは、次のようにまとめられます。

Sub do_perform
  Select Case state
    ' wait trigger
    Case 0
      state = 0
      If eflag = 1 Then
        eflag = 0
        state = state + 1
      End If
    ' set counter and send 'H'
    Case 1
      state = state + 1
      xcur = millis + XINTERVAL
      LATA = 1
    ' Wait
    Case 2
      state = 2
      If xcur <= millis Then
        state = state + 1
      End If
    ' reset and first state
    Case 3
      state = 0
      LATA = 0
    ' others
    Case Else
      state = 0
  End Select
End Sub

 GPIOの初期化、変数の初期値設定等を
 ひとつにまとめます。

Sub InitPort
  ' initial value
  LATA = 0
  ' direction
  TRISA = 0xFE
  ' pull up
  WPUA = 0x06
  ' others
  TMR0 = 6
  state = 0
  xpsw_sft = 0
  xwsw_sft = 0
  eflag = 0
  tflag = 0
  gpre = millis
  gcur = gpre
  millis = 0
End Sub

 スイッチの状態を判断し、出力に論理値の'H'か'L'を
 出力するのは、ループで実現。

Do
  ' get switch state
  getSW
  ' perform
  do_perform
  '
LOOP

 GreateCowBasicの全体コードは、以下。

' PIC10F322 test code

#chip 10F322,4
#config MCLRE = On , OSC = Int

#define GINTERVAL 10
#define XINTERVAL 1000

Dim millis As Long

Dim xpsw_sft As Byte
Dim xwsw_sft As Byte

Dim eflag As Bit
Dim tflag As Bit

Dim tmpx As Byte
Dim ptmp As Byte

Dim xcur As Long
Dim gcur As Long
Dim gpre As Long

Dim state As Byte

InitTimer0 Osc,PS0_4
On Interrupt Timer0Overflow Call t0EXEC

' initialize port direction
InitPort

' enable timer 0
StartTimer 0
' endless loop
Do
  ' get switch state
  getSW
  ' perform
  do_perform
  '
LOOP

' subroutine initialize
Sub InitPort
  ' initial value
  LATA = 0
  ' direction
  TRISA = 0xFE
  ' pull up
  WPUA = 0x06
  ' others
  TMR0 = 6
  state = 0
  xpsw_sft = 0
  xwsw_sft = 0
  eflag = 0
  tflag = 0
  gpre = millis
  gcur = gpre
  millis = 0
End Sub

Sub t0EXEC
  ' initialize
  TMR0 = 6
  ' increment
  millis = millis + 1
End Sub

Sub getSW
  ' time interval
  tflag = 0
  gcur = millis
  tmpx = gcur - gpre
  If tmpx >= GINTERVAL Then
    gpre = gcur
    tflag = 1
  End If
  IF tflag = 0 Then
    return
  End If
    ' shift
  xpsw_sft = xpsw_sft * 2
  xwsw_sft = xwsw_sft * 2
  ' mask
  xpsw_sft = xpsw_sft and 0b00001111
  xwsw_sft = xwsw_sft and 0b00001111
  ' update LSB
  ptmp = PORTA
  If (ptmp and 2) = 0 Then
    xpsw_sft = xpsw_sft + 1
  End If
  If (ptmp and 4) = 0 Then
    xwsw_sft = xwsw_sft + 1
  End If
  ' judge
  eflag = 0
  If xpsw_sft = 7 Then
    eflag = 1
  End if
  If xwsw_sft = 7 Then
    eflag = 1
  End if
End Sub

Sub do_perform
  Select Case state
    ' wait trigger
    Case 0
      state = 0
      If eflag = 1 Then
        eflag = 0
        state = state + 1
      End If
    ' set counter and send 'H'
    Case 1
      state = state + 1
      xcur = millis + XINTERVAL
      LATA = 1
    ' Wait
    Case 2
      state = 2
      If xcur <= millis Then
        state = state + 1
      End If
    ' reset and first state
    Case 3
      state = 0
      LATA = 0
    ' others
    Case Else
      state = 0
  End Select
End Sub

 コンパイル、リンクして、どのくらいの
 プログラムサイズになるのかを見ると
 次のようになりました。



 プログラムメモリ容量の半分くらいとなったので
 ハードウエアの置換えには使えると、判断してます。

 どんなアセンブリ言語に変換されているのかを、見ると
 以下のようになっています。

;********************************************************************************

;Set up the assembler options (Chip type, clock source, other bits and pieces)
 LIST p=10F322, r=DEC
#include <P10F322.inc>
 __CONFIG _LVP_OFF & _MCLRE_ON & _WDTE_OFF & _FOSC_INTOSC

;********************************************************************************

;Set aside memory locations for variables
GCUR		EQU	64
GCUR_E		EQU	67
GCUR_H		EQU	65
GCUR_U		EQU	66
GPRE		EQU	68
GPRE_E		EQU	71
GPRE_H		EQU	69
GPRE_U		EQU	70
MILLIS		EQU	72
MILLIS_E	EQU	75
MILLIS_H	EQU	73
MILLIS_U	EQU	74
PTMP		EQU	76
SAVEPCLATH	EQU	77
STATE		EQU	78
SYSBITVAR0	EQU	79
SYSBYTETEMPA	EQU	117
SYSBYTETEMPB	EQU	121
SYSBYTETEMPX	EQU	112
SYSLONGTEMPA	EQU	117
SYSLONGTEMPA_E	EQU	120
SYSLONGTEMPA_H	EQU	118
SYSLONGTEMPA_U	EQU	119
SYSLONGTEMPB	EQU	121
SYSLONGTEMPB_E	EQU	124
SYSLONGTEMPB_H	EQU	122
SYSLONGTEMPB_U	EQU	123
SYSSTATUS	EQU	127
SYSTEMP1	EQU	80
SYSTEMP2	EQU	81
SYSW		EQU	126
TMPX		EQU	82
TMRNUMBER	EQU	83
TMRPRES		EQU	84
TMRSOURCE	EQU	85
XCUR		EQU	86
XCUR_E		EQU	89
XCUR_H		EQU	87
XCUR_U		EQU	88
XPSW_SFT	EQU	90
XWSW_SFT	EQU	91

;********************************************************************************

;Vectors
	ORG	0
	pagesel	BASPROGRAMSTART
	goto	BASPROGRAMSTART
	ORG	4
Interrupt

;********************************************************************************

;Save Context
	movwf	SysW
	swapf	STATUS,W
	movwf	SysSTATUS
	banksel	STATUS
;Store system variables
	movf	PCLATH,W
	movwf	SavePCLATH
	clrf	PCLATH
;On Interrupt handlers
	btfss	INTCON,TMR0IE
	goto	NotTMR0IF
	btfss	INTCON,TMR0IF
	goto	NotTMR0IF
	call	T0EXEC
	bcf	INTCON,TMR0IF
	goto	INTERRUPTDONE
NotTMR0IF
;User Interrupt routine
INTERRUPTDONE
;Restore Context
;Restore system variables
	movf	SavePCLATH,W
	movwf	PCLATH
	swapf	SysSTATUS,W
	movwf	STATUS
	swapf	SysW,F
	swapf	SysW,W
	retfie

;********************************************************************************

;Start of program memory page 0
	ORG	27
BASPROGRAMSTART
;Call initialisation routines
	call	INITSYS
;Enable interrupts
	bsf	INTCON,GIE
	bsf	INTCON,PEIE

;Start of the main program
;PIC10F322 test code
;
;#define GINTERVAL 10
;#define XINTERVAL 1000
;Dim millis As Long
;Dim xpsw_sft As Byte
;Dim xwsw_sft As Byte
;Dim eflag As Bit
;Dim tflag As Bit
;Dim tmpx As Byte
;Dim ptmp As Byte
;Dim xcur As Long
;Dim gcur As Long
;Dim gpre As Long
;Dim state As Byte
;InitTimer0 Osc,PS0_4
	movlw	1
	movwf	TMRSOURCE
	movlw	1
	movwf	TMRPRES
	call	INITTIMER0156
;On Interrupt Timer0Overflow Call t0EXEC
	bsf	INTCON,TMR0IE
;initialize port direction
;InitPort
	call	INITPORT
;enable timer 0
;StartTimer 0
	clrf	TMRNUMBER
	call	STARTTIMER
;endless loop
;Do
SysDoLoop_S1
;get switch state
;getSW
	call	GETSW
;perform
;do_perform
	call	DO_PERFORM
;
;LOOP
	goto	SysDoLoop_S1
SysDoLoop_E1
;subroutine initialize
BASPROGRAMEND
	sleep
	goto	BASPROGRAMEND

;********************************************************************************

DO_PERFORM
;Select Case state
;wait trigger
;Case 0
SysSelect1Case1
	movf	STATE,F
	btfss	STATUS, Z
	goto	SysSelect1Case2
;state = 0
	clrf	STATE
;If eflag = 1 Then
	btfss	SYSBITVAR0,0
	goto	ENDIF7
;eflag = 0
	bcf	SYSBITVAR0,0
;state = state + 1
	incf	STATE,F
;End If
ENDIF7
;set counter and send 'H'
;Case 1
	goto	SysSelectEnd1
SysSelect1Case2
	decf	STATE,W
	btfss	STATUS, Z
	goto	SysSelect1Case3
;state = state + 1
	incf	STATE,F
;xcur = millis + XINTERVAL
	movlw	232
	addwf	MILLIS,W
	movwf	XCUR
	movlw	3
	btfsc	STATUS,C
	movlw	3 + 1
	addwf	MILLIS_H,W
	movwf	XCUR_H
	movlw	0
	btfsc	STATUS,C
	movlw	0 + 1
	addwf	MILLIS_U,W
	movwf	XCUR_U
	movlw	0
	btfsc	STATUS,C
	movlw	0 + 1
	addwf	MILLIS_E,W
	movwf	XCUR_E
;LATA = 1
	movlw	1
	movwf	LATA
;Wait
;Case 2
	goto	SysSelectEnd1
SysSelect1Case3
	movlw	2
	subwf	STATE,W
	btfss	STATUS, Z
	goto	SysSelect1Case4
;state = 2
	movlw	2
	movwf	STATE
;If xcur <= millis Then
	movf	XCUR,W
	movwf	SysLONGTempB
	movf	XCUR_H,W
	movwf	SysLONGTempB_H
	movf	XCUR_U,W
	movwf	SysLONGTempB_U
	movf	XCUR_E,W
	movwf	SysLONGTempB_E
	movf	MILLIS,W
	movwf	SysLONGTempA
	movf	MILLIS_H,W
	movwf	SysLONGTempA_H
	movf	MILLIS_U,W
	movwf	SysLONGTempA_U
	movf	MILLIS_E,W
	movwf	SysLONGTempA_E
	call	SysCompLessThan32
	comf	SysByteTempX,F
	btfsc	SysByteTempX,0
;state = state + 1
	incf	STATE,F
;End If
ENDIF8
;reset and first state
;Case 3
	goto	SysSelectEnd1
SysSelect1Case4
	movlw	3
	subwf	STATE,W
	btfss	STATUS, Z
	goto	SysSelect1Case5
;state = 0
	clrf	STATE
;LATA = 0
	clrf	LATA
;others
;Case Else
	goto	SysSelectEnd1
SysSelect1Case5
;state = 0
	clrf	STATE
;End Select
SysSelectEnd1
	return

;********************************************************************************

GETSW
;time interval
;tflag = 0
	bcf	SYSBITVAR0,1
;gcur = millis
	movf	MILLIS,W
	movwf	GCUR
	movf	MILLIS_H,W
	movwf	GCUR_H
	movf	MILLIS_U,W
	movwf	GCUR_U
	movf	MILLIS_E,W
	movwf	GCUR_E
;tmpx = gcur - gpre
	movf	GPRE,W
	subwf	GCUR,W
	movwf	TMPX
;If tmpx >= GINTERVAL Then
	movlw	10
	subwf	TMPX,W
	btfss	STATUS, C
	goto	ENDIF1
;gpre = gcur
	movf	GCUR,W
	movwf	GPRE
	movf	GCUR_H,W
	movwf	GPRE_H
	movf	GCUR_U,W
	movwf	GPRE_U
	movf	GCUR_E,W
	movwf	GPRE_E
;tflag = 1
	bsf	SYSBITVAR0,1
;End If
ENDIF1
;IF tflag = 0 Then
	btfss	SYSBITVAR0,1
;return
	return
;End If
ENDIF2
;shift
;xpsw_sft = xpsw_sft * 2
	bcf	STATUS,C
	rlf	XPSW_SFT,F
;xwsw_sft = xwsw_sft * 2
	bcf	STATUS,C
	rlf	XWSW_SFT,F
;mask
;xpsw_sft = xpsw_sft and 0b00001111
	movlw	15
	andwf	XPSW_SFT,F
;xwsw_sft = xwsw_sft and 0b00001111
	movlw	15
	andwf	XWSW_SFT,F
;update LSB
;ptmp = PORTA
	movf	PORTA,W
	movwf	PTMP
;If (ptmp and 2) = 0 Then
	movlw	2
	andwf	PTMP,W
	movwf	SysTemp1
	movwf	SysBYTETempA
	clrf	SysBYTETempB
	call	SysCompEqual
	btfsc	SysByteTempX,0
;xpsw_sft = xpsw_sft + 1
	incf	XPSW_SFT,F
;End If
ENDIF3
;If (ptmp and 4) = 0 Then
	movlw	4
	andwf	PTMP,W
	movwf	SysTemp1
	movwf	SysBYTETempA
	clrf	SysBYTETempB
	call	SysCompEqual
	btfsc	SysByteTempX,0
;xwsw_sft = xwsw_sft + 1
	incf	XWSW_SFT,F
;End If
ENDIF4
;judge
;eflag = 0
	bcf	SYSBITVAR0,0
;If xpsw_sft = 7 Then
	movlw	7
	subwf	XPSW_SFT,W
	btfsc	STATUS, Z
;eflag = 1
	bsf	SYSBITVAR0,0
;End if
ENDIF5
;If xwsw_sft = 7 Then
	movlw	7
	subwf	XWSW_SFT,W
	btfsc	STATUS, Z
;eflag = 1
	bsf	SYSBITVAR0,0
;End if
ENDIF6
	return

;********************************************************************************

INITPORT
;initial value
;LATA = 0
	clrf	LATA
;direction
;TRISA = 0xFE
	movlw	254
	movwf	TRISA
;pull up
;WPUA = 0x06
	movlw	6
	movwf	WPUA
;others
;TMR0 = 6
	movlw	6
	movwf	TMR0
;state = 0
	clrf	STATE
;xpsw_sft = 0
	clrf	XPSW_SFT
;xwsw_sft = 0
	clrf	XWSW_SFT
;eflag = 0
	bcf	SYSBITVAR0,0
;tflag = 0
	bcf	SYSBITVAR0,1
;gpre = millis
	movf	MILLIS,W
	movwf	GPRE
	movf	MILLIS_H,W
	movwf	GPRE_H
	movf	MILLIS_U,W
	movwf	GPRE_U
	movf	MILLIS_E,W
	movwf	GPRE_E
;gcur = gpre
	movf	GPRE,W
	movwf	GCUR
	movf	GPRE_H,W
	movwf	GCUR_H
	movf	GPRE_U,W
	movwf	GCUR_U
	movf	GPRE_E,W
	movwf	GCUR_E
;millis = 0
	clrf	MILLIS
	clrf	MILLIS_H
	clrf	MILLIS_U
	clrf	MILLIS_E
	return

;********************************************************************************

INITSYS
;asm ShowDebug ChipIntOSCCONFormat is ChipIntOSCCONFormat
;1 is 1
;The section now handles two true table for frequency
;Supports 18f2425 (type1 max frq of 8mhz) classes and 18f26k22 (type2 max frq of 16mhz) classes
;Assumes that testing the ChipMaxMHz >= 48 is a valid test for type2 microcontrollers
;Supports IntOsc MaxMhz of 64 and not 64 ... there may be others true tables that GCB needs to support
;asm showdebug OSCCON type is 104' NoBit(SPLLEN) And NoBit(IRCF3) Or Bit(INTSRC)) and ifdef Bit(HFIOFS)
;osccon type is 104
;OSCCON = OSCCON AND b'10001111'
	movlw	143
	andwf	OSCCON,F
;Address the two true tables for IRCF
;[canskip] IRCF2, IRCF1, IRCF0 = b'101'    ;101 = 4 MHz
	bsf	OSCCON,IRCF2
	bcf	OSCCON,IRCF1
	bsf	OSCCON,IRCF0
;Ensure all ports are set for digital I/O and, turn off A/D
;Switch off A/D with NoVar(ADCON0)
;Set ADCON.ADON Off
	bcf	ADCON,ADON
;Commence clearing any ANSEL variants in the part
;ANSELA = 0
	clrf	ANSELA
;End clearing any ANSEL variants in the part
;Turn off all ports
;GPIO = 0
	clrf	PORTA
;PORTA = 0
	clrf	PORTA
	return

;********************************************************************************

;Overloaded signature: BYTE:BYTE:
INITTIMER0156
;Some PICS (18F+) Use T0CON for timer0 Control
;ALL OTHER PICS USE OPTION_REG for timer0 control
;Sub modified to set all TMR Control bits at once
;* TMRPres, TMRSource & TMRPost now shared *
;if TMRPRes > 7 then TMRPRes = 0 'failsafe
	movf	TMRPRES,W
	sublw	7
	btfss	STATUS, C
	clrf	TMRPRES
ENDIF10
;If Timer0 is 16-bit capable
;Re-Use TMRPres as T0CON Temp_register
;Keep T0CON 7:6 and write bits 2:0 from TMRPres
;Bits 5,4 & 3 will be cleared!
;TMRPres = (OPTION_REG AND 192) OR TMRPres
	movlw	192
	andwf	OPTION_REG,W
	movwf	SysTemp1
	iorwf	TMRPRES,F
;IF TMRSource = EXT then
	movlw	2
	subwf	TMRSOURCE,W
	btfss	STATUS, Z
	goto	ELSE11_1
;Set TMRPres.5 ON   'EXT
	bsf	TMRPRES,5
;ELSE
	goto	ENDIF11
ELSE11_1
;Set TMRPres.5 OFF  'OSC
	bcf	TMRPRES,5
;END IF
ENDIF11
;Now Write the OPTION_REG
;OPTION_REG = TMRPres
	movf	TMRPRES,W
	movwf	OPTION_REG
;Added For baseline Chips with write only option_reg
;If Timer0 is 16-bit capable
	return

;********************************************************************************

STARTTIMER
;IF TMRNumber = 2 then Set TMR2ON on
	movlw	2
	subwf	TMRNUMBER,W
	btfsc	STATUS, Z
	bsf	T2CON,TMR2ON
ENDIF9
	return

;********************************************************************************

SYSCOMPEQUAL
;Dim SysByteTempA, SysByteTempB, SysByteTempX as byte
;clrf SysByteTempX
	clrf	SYSBYTETEMPX
;movf SysByteTempA, W
	movf	SYSBYTETEMPA, W
;subwf SysByteTempB, W
	subwf	SYSBYTETEMPB, W
;btfsc STATUS, Z
	btfsc	STATUS, Z
;comf SysByteTempX,F
	comf	SYSBYTETEMPX,F
	return

;********************************************************************************

SYSCOMPLESSTHAN32
;dim SysLongTempA as long
;dim SysLongTempB as long
;dim SysByteTempX as byte
;clrf SysByteTempX
	clrf	SYSBYTETEMPX
;Test Exp, exit if more
;movf SysLongTempA_E,W
	movf	SYSLONGTEMPA_E,W
;subwf SysLongTempB_E,W
	subwf	SYSLONGTEMPB_E,W
;btfss STATUS,C
	btfss	STATUS,C
;return
	return
;If not more and not zero, is less
;btfss STATUS,Z
	btfss	STATUS,Z
;goto SCLT32True
	goto	SCLT32TRUE
;Test Upper, exit if more
;movf SysLongTempA_U,W
	movf	SYSLONGTEMPA_U,W
;subwf SysLongTempB_U,W
	subwf	SYSLONGTEMPB_U,W
;btfss STATUS,C
	btfss	STATUS,C
;return
	return
;If not more and not zero, is less
;btfss STATUS,Z
	btfss	STATUS,Z
;goto SCLT32True
	goto	SCLT32TRUE
;Test High, exit if more
;movf SysLongTempA_H,W
	movf	SYSLONGTEMPA_H,W
;subwf SysLongTempB_H,W
	subwf	SYSLONGTEMPB_H,W
;btfss STATUS,C
	btfss	STATUS,C
;return
	return
;If not more and not zero, is less
;btfss STATUS,Z
	btfss	STATUS,Z
;goto SCLT32True
	goto	SCLT32TRUE
;Test Low, exit if more or equal
;movf SysLongTempB,W
	movf	SYSLONGTEMPB,W
;subwf SysLongTempA,W
	subwf	SYSLONGTEMPA,W
;btfsc STATUS,C
	btfsc	STATUS,C
;return
	return
SCLT32TRUE
;comf SysByteTempX,F
	comf	SYSBYTETEMPX,F
	return

;********************************************************************************

T0EXEC
;initialize
;TMR0 = 6
	movlw	6
	movwf	TMR0
;increment
;millis = millis + 1
	incf	MILLIS,F
	btfsc	STATUS,Z
	incf	MILLIS_H,F
	btfsc	STATUS,Z
	incf	MILLIS_U,F
	btfsc	STATUS,Z
	incf	MILLIS_E,F
	return

;********************************************************************************
 END

 アセンブリ言語で見ると、IF文の条件判断で冗長な処理を
 していると、わかったので、次のように記述を変更して
 プログラム容量が減るかを試してみます。

  ' update LSB
  ptmp = PORTA
  ptmpa = ptmp and 2
  ptmpb = ptmp and 4
  If ptmpa = 0 Then
    xpsw_sft = xpsw_sft + 1
  End If
  If ptmpb = 0 Then
    xwsw_sft = xwsw_sft + 1
  End If

 コンパイル、リンクの結果は、次のようになりプログラム容量が
 減ったことがわかります。



 50%以上から50%未満になりました。

 GCBasicのプログラムは、判定処理を高速にするには
 メモリ(レジスタ)の値だけに注目する方がよいと
 ノウハウを得たと言ってよいでしょう。


目次

inserted by FC2 system