MC9RS08KA2マイコンを使って、ルーレットゲームを作ります。 目標は、できるだけ半田付け箇所を減らすことです。
以下にこのアプリケーションの回路図を示します。 押しボタンの操作で8個のLEDと1個の圧電スピーカを駆動します。
R2(470Ω)は、 FLASH ROMのプログラム用12V電源がつながっている時に押しボタンを押しても、 悲惨な事故が起こらないように入れてあります。
| 品名 | 規格 | メーカ | 個数 | 調達先 |
|---|---|---|---|---|
| マイコン | MC9RS08KA2CPC | Freescale | 1 | Freescale |
| カーボン抵抗 | 470Ω 1/6W | - | 1 | 秋月電子 |
| カーボン抵抗 | 1kΩ 1/6W | - | 1 | 秋月電子 |
| 電解コンデンサ | 47µF 16V | SANYO | 1 | 手持在庫 |
| 積層セラミック・コンデンサ | 0.1µF 50V | - | 2 | 秋月電子 |
| 赤色発光ダイオード | OSDR5113A | OptoSupply | 1 | 秋月電子 |
| 黄色発光ダイオード | OSNG5113A | OptoSupply | 3 | 秋月電子 |
| 緑色発光ダイオード | OSYL5113A | OptoSupply | 4 | 秋月電子 |
| タクト・スイッチ | - | - | 1 | 梅澤無線 |
| ICソケット | 8P DIP | - | 1 | 秋月電子 |
| ボタン電池ホルダ | CH25-2032 | SHOGYO | 1 | 秋月電子 |
| ボタン電池 | CR2032 | 東芝 | 1 | 千石電商 |
| 圧電スピーカ | - | - | 1 | 梅澤無線 |
| ピンヘッダ | 2×3 | - | 1 | 秋月電子 |
| 片面ユニバーサル基板 | 95mm×72mm | - | 1 | 秋月電子 |
| 丸ビス | 2mm×10mm | - | 2 | 手持在庫 |
| 6角ナット | 2mm | - | 2 | 手持在庫 |
| スペーサ | 3mm×20mm | マック8 | 4 | 手持在庫 |
| 6角ナット | 3mm | - | 4 | 手持在庫 |
LEDには、電流制限抵抗を入れていません。 これは、MC9RS08KA2の出力電流が多くないという事実を利用しています。 下のグラフは、流れる電流に対する"H"出力ポートと"L"出力ポートの 電位差(VOH-VOL)とLEDの順方向電圧(VF)をモデル化したものです。 これら二つのグラフの交点でLEDが点灯します。
設計では、電源電圧3Vのときに、 "H"出力ポートと"L"出力ポートで0.5Vづつ電圧降下が起き、 それによって出力電流は約5mAに制限されます。 これは、3V電源の時に限る計算です。 したがって、この回路に5V電源を与えると マイコンとLEDに大電流が流れて破壊する可能性がありますのでご注意ください。
DEMO9RS08KA2評価ボードを開発ツールとして使用するためには、 BDMピンヘッダをつけます。
これで、ソフトウェア開発の準備は完了です。
ここでは、ソフトウェアの概要を説明します。
このプログラムは、 押しボタンスイッチを押すとLEDの光が走り出し、 押しボタンスイッチを放すとLEDの速度が徐々に遅くなり、 最後には停止します。 停止した位置によって、「あたり」と「はずれ」の音を出します。
このプログラムでは、押しボタンスイッチを押さずに 一定期間放置すると、LEDを消灯し、低消費電力モードに入ります。 低消費電力状態からは、押しボタンスイッチを押すと復帰します。
このプログラムは、状態遷移によって動作しています。
電源ONによるリセット直後、MC9RS08KA2は PROLOGUEという状態に入ります。 PROLOGUEでは、 押しボタンスイッチが押されていない状態であることを確認します。 つまり、押しボタンスイッチを押したまま電源を投入しても ルーレットは走り出しません。
押しボタンスイッチが押されていないことを確認したら、 MC9RS08KA2は、WAITという状態に入ります。 この状態では、キーボード割り込みを待ち、 押しボタンが押されたらRUNという状態に遷移します。 同時に、押しボタンが押されなかった時間を計測しており、 約5分間、押しボタンが押されない場合には、STOPという 状態に遷移します。
STOP状態では、 STOP命令により低消費電力モードに入ります。 この状態では、押しボタンスイッチが押されるのを待ちます。 押しボタンが押されたら、再び、PROLOGUE状態に 遷移します。
一方、RUN状態では、 徐々に移動速度を落としながら、LEDを移動させます。 移動速度が、ある決められた移動速度にまで低下したら、 EPILOGUE状態に遷移します。
EPILOGUE状態では、停止したLEDの位置によって、 「あたり」と「はずれ」の効果音を圧電スピーカから出します。 効果音を出し終わったら、PROLOGUE状態に遷移します。
MC9RS08KA2には、Cなどの高級言語が準備されていません。 このため、このアプリケーションの開発も アセンブラで行いました。 アセンブラには、アブソリュート・アセンブラを使い、 一つのファイルにすべての記述を行っています。
このプログラムの全ソースコードは、以下のようになっています。
;*******************************************************************
;*
;* RouletteKA2.asm :
;*
;* Copyright 2006 (C) noritan.org
;*
;*******************************************************************
; Include derivative-specific definitions
include 'derivative.inc'
;
; export symbols
;
xdef _Startup
absentry _Startup
;**************************************************************
;* Debug and Release Configurations.
;**************************************************************
IFNE MODE
;==============================================================
;= Release Configuration.
;==============================================================
;==============================================================
;= Initialization value for SPMSC1 register.
;=
;= In RELEASE case, LVD cause RESET in RUN and STOP.
;==============================================================
SPMSC1_init equ %01010000
; |||||||+-- BGBE=0 (no bandgap)
; ||||||+--- Reserved
; |||||+---- LVDE=0 (LVD enabled)
; ||||+----- LVDSE=0 (LVD enable in STOP)
; |||+------ LVDRE=1 (Reset by LVD enabled)
; ||+------- LVDIE=0 (INT by LVD disabled)
; |+-------- LVDACK=1 (Clear LVDF)
; +--------- LVDF=0 (N/A)
;==============================================================
;= Initialization value for SOPT register.
;=
;= In RELEASE case, STOP instruction is enabled.
;==============================================================
SOPT_init equ %00100000
; |||||||+-- RSTPE=0 (no RESET*)
; ||||||+--- BKGDPE=0 (no BKGD)
; |||+++---- Reserved
; ||+------- STOPE=1 (STOP available)
; |+-------- COPT=0 (COP rate)
; +--------- COPE=0 (no COP)
stop_nop: macro
stop
endm
wait_nop: macro
wait
endm
ELSE
;==============================================================
;= Debug Configuration.
;==============================================================
;==============================================================
;= Initialization value for SPMSC1 register.
;=
;= In DEBUG case, LVD cause RESET in RUN and STOP.
;==============================================================
SPMSC1_init equ %01011100
; |||||||+-- BGBE=0 (no bandgap)
; ||||||+--- Reserved
; |||||+---- LVDE=1 (LVD enabled)
; ||||+----- LVDSE=1 (LVD enable in STOP)
; |||+------ LVDRE=1 (Reset by LVD enabled)
; ||+------- LVDIE=0 (INT by LVD disabled)
; |+-------- LVDACK=1 (Clear LVDF)
; +--------- LVDF=0 (N/A)
;==============================================================
; Initialization value for SOPT register.
;
; In DEBUG case, STOP instruction and BKGD pin are enabled.
;==============================================================
SOPT_init equ %00100010
; |||||||+-- RSTPE=0 (no RESET*)
; ||||||+--- BKGDPE=1 (no BKGD)
; |||+++---- Reserved
; ||+------- STOPE=1 (STOP available)
; |+-------- COPT=0 (COP rate)
; +--------- COPE=0 (no COP)
stop_nop: macro
nop
endm
wait_nop: macro
nop
endm
ENDIF
;==============================================================
; Port Declaration
;==============================================================
BEEP: equ PTAD_PTAD3 ; Beeper is assigned to PTA5.
START: equ PTAD_PTAD2 ; Start is assigned to PTA2.
mBEEP: equ (1<<BEEP) ; Beeper MASK.
;==============================================================
; Flag Declaration
;==============================================================
PRESSED: equ 0 ; PRESSED flag position.
;==============================================================
; RTI initialization.
; RTI period: 8msec
;
SRTISC_init: equ %01000001
; |||||+++-- RTIS=001 (8msec period)
; ||||+----- Reserved
; |||+------ RTIE=0 (no interrupt)
; ||+------- RTICLKS=0 (internal 1kHz)
; |+-------- RTIACK=1 (clear RTIF)
; +--------- RTIF=0 (no effect)
;
;==============================================================
;==============================================================
; MTIM initialization
;
MTIMCLK_init: equ %00000101
; ||||++++-- PS=0101 (x32 prescale)
; ||++------ CLKS=00 (BUSCLK)
; ++-------- Reserved
;
; MTIM clock: Freq=250kHz, Period=4usec
;
; MTIMMOD in play: 334usec (1 / 2 * 1.497kHz)
MTIMMOD_1500: equ 42-1 ; 1488Hz*2=2976Hz
; MTIMMOD in epilogue: based on 250kHz
MTIMMOD_do3: equ 239-1 ; 523Hz*2=1046Hz
MTIMMOD_so3: equ 159-1 ; 786Hz*2=1572Hz
MTIMMOD_ra3: equ 142-1 ; 880Hz*2=1761Hz
MTIMMOD_si3: equ 127-1 ; 984Hz*2=1969Hz
MTIMMOD_do4: equ 119-1 ; 1050Hz*2=2101Hz
;
;==============================================================
;==============================================================
; Constant parameters
;==============================================================
ACCEL_PERIOD: equ 20 ; Period of accel events.
DEBOUNCE_PERIOD:equ 80 ; Period of debounce.
BEEP_PERIOD: equ 20 ; Period of beep.
MOVE_PERIOD: equ 40 ; Period for max speed.
WAIT_PERIOD: equ 146 ; Period of max waiting.
RELEASE_PERIOD: equ 6 ; Period of button release.
MAX_SPEED: equ 255 ; Maximum speed of LED.
MIN_SPEED: equ 13 ; Minimum speed of LED.
LED_AMOUNT: equ 8 ; Number of LEDs.
;**************************************************************
;
; variable/data section
;
;**************************************************************
org TINY_RAMStart ; TINY RAM is mainly used.
speed: rmb 1 ; speed of LED.
speedf: rmb 1 ; fractional part of speed.
position: rmb 1 ; position between LEDs.
positionf: rmb 1 ; fractional part of position.
led_index: rmb 1 ; index for LED.
accel_count: rmb 1 ; periodic timer for accel.
beep_count: rmb 1 ; periodic timer for beep.
debounce_count: rmb 1 ; periodic timer for debounce.
flag: rmb 1 ; user defined flag.
rti_count_h: equ speed ; RTI event counter H.
rti_count_l: equ speedf ; RTI event counter L.
sound_page: rmb 1 ; Page for sounder.
;**************************************************************
; Constant table section
;**************************************************************
org ROMStart
;==============================================================
; fanfare
;==============================================================
align 64
FANFARE:
fcb MTIMMOD_so3,60
fcb MTIMMOD_so3,30
fcb MTIMMOD_so3,30
fcb MTIMMOD_ra3,30
fcb MTIMMOD_si3,30
fcb MTIMMOD_do4,240
fcb 0
;==============================================================
; missed
;==============================================================
align 64
MISSED:
fcb MTIMMOD_so3,30
fcb MTIMMOD_so3,30
fcb MTIMMOD_do3,60
fcb 0
;==============================================================
; PORTA drive pattern.
; Tables must be in a same page.
;==============================================================
align 64
PTAD_PATTERN: ; PTAD PTADD
fcb %00100000,%00100001 ; 0 5-0
fcb %00000010,%00000011 ; 1 1-0
fcb %00000001,%00000011 ; 2 0-1
fcb %00010000,%00010010 ; 3 4-1
fcb %00000010,%00010010 ; 4 1-4
fcb %00100000,%00110000 ; 5 5-4
fcb %00010000,%00110000 ; 6 4-5
fcb %00000001,%00100001 ; 7 0-5
;**************************************************************
;* Macro code definition.
;**************************************************************
;==============================================================
;= enable_rti :
;= Enable the RTI interrupt.
;= SRTISC is initialized to start RTI counter.
;=
;= accept_rti :
;= Accept an RTI event.
;= RTIACK is set to clear the RTIF
;=
;= disable_rti
;= Disable the RTI interrupt.
;= Counter is stopped to reduce power.
;=
;==============================================================
enable_rti: macro
mov #HIGH_6_13(SRTISC),PAGESEL
mov #SRTISC_init,MAP_ADDR_6(SRTISC)
bset SRTISC_RTIE,MAP_ADDR_6(SRTISC)
endm
accept_rti: macro
mov #HIGH_6_13(SRTISC),PAGESEL
bset SRTISC_RTIACK,MAP_ADDR_6(SRTISC)
endm
disable_rti: macro
mov #HIGH_6_13(SRTISC),PAGESEL
bclr SRTISC_RTIE,MAP_ADDR_6(SRTISC)
endm
;==============================================================
;= enable_kbi :
;= Enable the KBI interrupt.
;= KBACK is set to clear the KBF
;=
;= accept_kbi :
;= Accept an KBI event.
;= KBACK is set to clear the KBF
;=
;= disable_kbi
;= Disable the KBI interrupt.
;=
;==============================================================
enable_kbi: macro
bset KBISC_KBACK,KBISC
bset KBISC_KBIE,KBISC
endm
accept_kbi: macro
bset KBISC_KBACK,KBISC
endm
disable_kbi: macro
bclr KBISC_KBIE,KBISC
endm
;==============================================================
;= enable_mtim :
;= Enable the TOF interrupt.
;= TRST is set to clear the TOF and MTIMCNT.
;= TSTP is controlled for safety enabling.
;=
;= accept_mtim :
;= Accept an TOF event.
;= TOF is reset to clear the TOF.
;=
;= disable_mtim
;= Disable the TOF interrupt.
;= TRST is set to reset the timer counter.
;= TSTP is set to stop the timer counter.
;=
;==============================================================
enable_mtim: macro
mov #mMTIMSC_TOIE+mMTIMSC_TRST+mMTIMSC_TSTP,MTIMSC
bclr MTIMSC_TSTP,MTIMSC
endm
accept_mtim: macro
bclr MTIMSC_TOF,MTIMSC
endm
disable_mtim: macro
mov #mMTIMSC_TRST+mMTIMSC_TSTP,MTIMSC
endm
;**************************************************************
; code section
;**************************************************************
;==============================================================
;= Genral initialization.
;=
;= Modules KBI, RTI and MTIM are initialized and ready to be
;= used.
;=
;= led_index = 0;
;= PTAPE2 = 1;
;= KBIPE2 = 1;
;= MTIMCLK = MTIMCLK_init;
;==============================================================
_Startup:
mov #HIGH_6_13(SOPT),PAGESEL
mov #SOPT_init,MAP_ADDR_6(SOPT)
mov #SPMSC1_init,MAP_ADDR_6(SPMSC1)
clr led_index
bset KBIPE_KBIPE2,KBIPE
mov #HIGH_6_13(PTAPE),PAGESEL
bset PTAPE_PTAPE2,MAP_ADDR_6(PTAPE)
bset KBISC_KBIMOD,KBISC
mov #MTIMCLK_init,MTIMCLK
;==============================================================
;= Initialization for PROLOGUE state
;= KBI -- disabled not to capture KBI.
;= RTI -- enabled to wait TIMEOUT event.
;= MTIM -- disabled to reduce power.
;=
;= put_led();
;= disable_kbi();
;= enable_rti();
;= disable_mtim();
;= rti_count = 0;
;==============================================================
prologue_init:
jsr put_led
disable_kbi
enable_rti
disable_mtim
clr rti_count_h
clr rti_count_l
;==============================================================
; PROLOGUE state
; Confirm START button released and go to WAIT state.
;
; for (;;) {
; $WAIT;
; if (RTI) {
; if (!PTAD[START]) {
; rtc_count = 0;
; } else {
; if (++rti_count >= RELEASE_PERIOD) goto wait_init;
; }
; }
; }
;==============================================================
prologue_loop:
mov #HIGH_6_13(SIP1),PAGESEL
wait_nop
brclr SIP1_RTI,MAP_ADDR_6(SIP1),prologue_loop
accept_rti
brset START,PTAD,prologue_release
clr rti_count_l
prologue_release:
inc rti_count_l
lda rti_count_l
cmp #RELEASE_PERIOD
bcs prologue_loop
;==============================================================
;= Initialization for WAIT state
;= KBI -- enabled to wait START button.
;= RTI -- enabled to wait TIMEOUT event.
;= MTIM -- disabled to reduce power.
;=
;= put_led();
;= enable_kbi();
;= enable_rti();
;= disable_mtim();
;= rti_count = 0;
;==============================================================
wait_init:
jsr put_led
enable_kbi
enable_rti
disable_mtim
clr rti_count_h
clr rti_count_l
;==============================================================
; WAIT state
; Wait for a START trigger and go to RUN state.
;
; for (;;) {
; $WAIT;
; if (KBI) goto run_init;
; if (RTI) goto wait_rti;
; }
;==============================================================
wait_loop:
mov #HIGH_6_13(SIP1),PAGESEL
wait_nop
brset SIP1_KBI,MAP_ADDR_6(SIP1),run_init
brclr SIP1_RTI,MAP_ADDR_6(SIP1),wait_loop
;==============================================================
;= Software count for RTI evnets.
;=
;= accept_rti();
;= if (++rti_count >= WAIT_PERIOD) goto stop_init;
;= else goto wait_loop;
;==============================================================
accept_rti
inc rti_count_l
bne wait_loop
inc rti_count_h
lda rti_count_h
cmp #WAIT_PERIOD
bcs wait_loop
;==============================================================
;= Initialization for STOP state
;= KBI -- enabled to wait START button.
;= RTI -- disabled to reduce power.
;= MTIM -- disabled to reduce power.
;=
;= PTAD = %00000000;
;= PTADD = %00110011;
;= enable_kbi();
;= disable_rti();
;= disable_mtim();
;==============================================================
stop_init:
mov #%00000000,PTAD
mov #%00110011,PTADD
enable_kbi
disable_rti
disable_mtim
;==============================================================
; STOP state
;
; for (;;) {
; $STOP;
; if (KBF) goto wait_init;
; }
;==============================================================
stop_loop:
stop_nop
brset KBISC_KBF,KBISC,prologue_init
bra stop_loop
;==============================================================
;= Initialization for RUN state.
;= KBI -- disabled.
;= RTI -- disabled.
;= MTIM -- enabled to control all timings.
;=
;= disable_kbi();
;= disable_rti();
;= enable_mtim();
;= MTIMMOD = MTIMMOD_1500;
;= flag.PRESSED = 1;
;= speed = MAX_SPEED;
;==============================================================
run_init:
disable_kbi
disable_rti
enable_mtim
mov #MTIMMOD_1500,MTIMMOD
bset PRESSED,flag
mov #MAX_SPEED,speed
;==============================================================
;= RUN state
;==============================================================
run_loop:
;-----------------------------------------------------
;- Wait for MTIM interrupt
;-
;- do {
;- $WAIT;
;- } while (!TOF);
;- accept_mtim();
;-----------------------------------------------------
run_wait_2:
wait_nop
brclr MTIMSC_TOF,MTIMSC,run_wait_2
accept_mtim
;-----------------------------------------------------
;- Beep enabler
;-
;- if (beep_count != 0) {
;- PTAD.BEEP = 1;
;- beep_count--;
;- }
;-----------------------------------------------------
lda beep_count
beq beep_enabler_done
bset BEEP,PTAD
dec beep_count
beep_enabler_done:
;-----------------------------------------------------
;- Speed updater
;-
;- if (--accel_count == 0) {
;- if (!flag.PRESSED) {
;- speed -= speed >> 8;
;- }
;- accel_count = ACCEL_PERIOD;
;- }
;-----------------------------------------------------
dec accel_count
bne speed_updater_done
brset PRESSED,flag,speed_updater_reschedule
lda speedf
sub speed
sta speedf
bcc speed_updater_reschedule
dec speed
speed_updater_reschedule:
mov #ACCEL_PERIOD,accel_count
speed_updater_done:
;-----------------------------------------------------
;- Key handler
;-
;- if (flag.PRESSED) {
;- if (!PTAD[START]) { // PUSH detected.
;- debounce_count = DEBOUNCE_PERIOD;
;- } else if (--debounce_count == 0) {
;- flag.PRESSED = 0;
;- }
;- }
;-----------------------------------------------------
brclr PRESSED,flag,key_handler_done
brset START,PTAD,key_handler_release
key_handler_push:
mov #DEBOUNCE_PERIOD,debounce_count
bra key_handler_done
key_handler_release:
dec debounce_count
bne key_handler_done
bclr PRESSED,flag
key_handler_done:
;-----------------------------------------------------
;- Wait for MTIM interrupt
;-
;- do {
;- $WAIT;
;- } while (!TOF);
;- accept_mtim();
;-----------------------------------------------------
run_wait_1:
wait_nop
brclr MTIMSC_TOF,MTIMSC,run_wait_1
accept_mtim
;-----------------------------------------------------
;- Beep disabler
;-
;- PTAD.BEEP = 0;
;-----------------------------------------------------
bclr BEEP,PTAD
;-----------------------------------------------------
;- Position updater
;-
;- position += speed;
;- if (position >= MOVE_PERIOD) {
;- position -= MOVE_PERIOD;
;- beep_count = BEEP_PERIOD;
;- led_index = (led_index + 1) % LED_AMOUNT;
;- put_led();
;- }
;-----------------------------------------------------
lda positionf
add speed;
sta positionf
bcc position_updater_done
inc position
lda position
sub #MOVE_PERIOD
bcs position_updater_done
sta position
mov #BEEP_PERIOD,beep_count
inc led_index
lda led_index
sub #LED_AMOUNT
bcs position_updater_putled
sta led_index
position_updater_putled:
bsr put_led
position_updater_done:
;-----------------------------------------------------
;- Quit loop control
;-
;- if (speed < min_speed) {
;- $QUIT_LOOP;
;- }
;-----------------------------------------------------
lda speed
cmp #MIN_SPEED
bcs epilogue_init
bra run_loop
;==============================================================
;= Initialization for EPILOGUE state
;= KBI -- disabled.
;= RTI -- enabled to show epilogue.
;= MTIM -- enabled to control beep.
;=
;==============================================================
epilogue_init:
disable_kbi
enable_mtim
enable_rti
mov #HIGH_6_13(FANFARE),sound_page
lda led_index
beq set_sound
mov #HIGH_6_13(MISSED),sound_page
lsra
bcc set_sound
mov #HIGH_6_13(MISSED),sound_page
set_sound:
ldx #$C0
mov #1,rti_count_l
;==============================================================
;= EPILOGUE state
;==============================================================
epilogue_loop:
mov #HIGH_6_13(SIP1),PAGESEL
wait_nop
brclr SIP1_MTIM,MAP_ADDR_6(SIP1),epilogue_checkrti
accept_mtim
lda rti_count_l
cmp #2
bcs epilogue_checkrti
lda PTAD
eor #mBEEP
sta PTAD
epilogue_checkrti:
brclr SIP1_RTI,MAP_ADDR_6(SIP1),epilogue_loop
accept_rti
dec rti_count_l
bne epilogue_loop
mov sound_page,PAGESEL
lda D[X]
beq epilogue_done
sta MTIMMOD
incx
mov D[X],rti_count_l
incx
bra epilogue_loop
epilogue_done:
jmp prologue_loop
;-----------------------------------------------------
;- SUB: Put on an LED at led_index.
;-
;- PTADD = $00;
;- PTAD = PTAD_PATTERN[led_index][0];
;- PTADD = PTAD_PATTERN[led_index][1];
;-----------------------------------------------------
put_led:
clr PTADD
lda led_index
asla
mov #HIGH_6_13(PTAD_PATTERN),PAGESEL
add #MAP_ADDR_6(PTAD_PATTERN)
tax
mov D[X],PTAD
incx
mov D[X],PTADD
rts
;**************************************************************
;* Startup Vector *
;**************************************************************
org $3FFD
jmp _Startup ; Reset
このアプリケーションでは、 光の移動速度を積分することによって光るLEDの位置を計算しています。 さらに、移動速度も積分によって計算しているのですが、 この時に加速度を移動速度の-1/256倍にしています。 つまり、以下の微分方程式に従うことになります。
dv / dt = -(v / 256) / (ACCEL_SPEED / 1500Hz)
これを解くと
v = v0 * exp(-t / 3.41)
という一般式が得られます。 v0は、時刻0の時の移動速度です。 この式は、3.41秒かけて光の移動速度が1/2.7倍になることを示しています。
ここでは、プログラムのデバッグの際に問題になった事柄を取り上げます。
圧電スピーカは、PTA3端子に接続されています。 この端子は、デバッグ時には、BKGD端子として使用されていますので、 デバッグ中は、圧電スピーカから雑音が出ます。 もし、雑音が気になる場合には、抵抗R1(1kΩ)をソケットで実装し、 デバッグ時には取り外すと雑音は出なくなります。
また、同じ理由で、 圧電スピーカから出す音のデバッグをデバッガを使って行うことができません。 端子数の少ないマイコンだから、仕方が無いですね。
このプログラムは、複数の割り込み待ちループによって構成されています。 それぞれの割り込み待ちには、 反応時間の短縮と低消費電力化を狙って WAITとSTOPという命令が使用されています。
STOP命令は、内部クロックを停止させる命令ですが、 デバッグ中、内部クロックが無いとBDMはうまく接続できません。 データシートでは、STOP状態でもBDMがイネーブルされていれば クロックが動き続けるとされているのですが、 実際には、STOP命令を実行するとデバッガが接続されなくなってしまいました。
そこで、wait_nopと stop_nopというアセンブラのマクロを宣言して、 デバッグ中はNOPに置き換えてやることにしました。 こうすると、デバッグ中もクロックが停止せず、 消費電力の削減はできませんが、快適にデバッグを行うことができます。
リチウム型ボタン電池を入れて完成です。
消費電力を測定するため、 STOP状態の消費電流を手持ちのテスタで測定しましたが、 測定不能という結果になってしまいました。 おそらく、1µA以下になったのだろうと推測しています。
2006-06-25 発行。