====== 7セグでカウンタ表示 ======
===== 7セグで何を表現できるか =====
7セグで表現できるものは、10進数で使う0~9、16進数で使うA~F、High LowのH,L。\\
それから-記号が表現可能です。ドットは必要なときにONします。\\
{{7seg11.gif}}
===== プログラムの作成 =====
まずは、ポートの設定と、7セグの点灯データの記述。
;------------------------------------------------------------------------------
; ポート設定
;------------------------------------------------------------------------------
SSD_NUM EQU 6 ; 7セグの個数
SSD_DIGIT_PORT EQU PA ; 桁切り替えのポート
SSD_DIGIT_DR EQU PADR
SSD_DATA_PORT EQU PB ; データ用のポート
SSD_DATA_DR EQU PBDR
;------------------------------------------------------------------------------
; 7 セグの点灯データ
;------------------------------------------------------------------------------
; *gfedcba
SSD_DATA_0 EQU 11000000B ; 0
SSD_DATA_1 EQU 11111001B ; 1
SSD_DATA_2 EQU 10100100B ; 2
SSD_DATA_3 EQU 10110000B ; 3
SSD_DATA_4 EQU 10011001B ; 4
SSD_DATA_5 EQU 10010010B ; 5
SSD_DATA_6 EQU 10000010B ; 6
SSD_DATA_7 EQU 11111000B ; 7
SSD_DATA_8 EQU 10000000B ; 8
SSD_DATA_9 EQU 10010000B ; 9
SSD_DATA_A EQU 10001000B ; a
SSD_DATA_B EQU 10000011B ; b
SSD_DATA_C EQU 11000110B ; c
SSD_DATA_D EQU 10100001B ; d
SSD_DATA_E EQU 10000110B ; e
SSD_DATA_F EQU 10001110B ; f
SSD_DATA_MI EQU 10111111B ; -
SSD_DATA_H EQU 10001001B ; H
SSD_DATA_L EQU 11000111B ; L
SSD_DATA_SP EQU 11111111B ; 消燈
次に変換テーブル。if文を並べて書くより、小さくて軽くなります。\\
RAMには、桁位置保存用のワークと、描画データ保存用のワークを作成。
;******************************************************************************
; ROM 上のデータ
;******************************************************************************
segment TEXT
;------------------------------------------------------------------------------
; 7セグの変換テーブル
;------------------------------------------------------------------------------
SSD_CODE_TBL: DC.B SSD_DATA_SP ; 0x20
DC.B SSD_DATA_SP ; 0x21 !
DC.B SSD_DATA_SP ; 0x22 "
DC.B SSD_DATA_SP ; 0x23 #
DC.B SSD_DATA_SP ; 0x24 $
DC.B SSD_DATA_SP ; 0x25 %
DC.B SSD_DATA_SP ; 0x26 &
DC.B SSD_DATA_SP ; 0x27 '
DC.B SSD_DATA_SP ; 0x28 (
DC.B SSD_DATA_SP ; 0x29 )
DC.B SSD_DATA_SP ; 0x2a *
DC.B SSD_DATA_SP ; 0x2b +
DC.B SSD_DATA_SP ; 0x2c ,
DC.B SSD_DATA_MI ; 0x2d -
DC.B SSD_DATA_SP ; 0x2e .
DC.B SSD_DATA_SP ; 0x2f /
DC.B SSD_DATA_0 ; 0x30 0
DC.B SSD_DATA_1 ; 0x31 1
DC.B SSD_DATA_2 ; 0x32 2
DC.B SSD_DATA_3 ; 0x33 3
DC.B SSD_DATA_4 ; 0x34 4
DC.B SSD_DATA_5 ; 0x35 5
DC.B SSD_DATA_6 ; 0x36 6
DC.B SSD_DATA_7 ; 0x37 7
DC.B SSD_DATA_8 ; 0x38 8
DC.B SSD_DATA_9 ; 0x39 9
DC.B SSD_DATA_SP ; 0x3a :
DC.B SSD_DATA_SP ; 0x3b ;
DC.B SSD_DATA_SP ; 0x3c <
DC.B SSD_DATA_SP ; 0x3d =
DC.B SSD_DATA_SP ; 0x3e >
DC.B SSD_DATA_SP ; 0x3f ?
DC.B SSD_DATA_SP ; 0x40 @
DC.B SSD_DATA_A ; 0x41 A
DC.B SSD_DATA_B ; 0x42 B
DC.B SSD_DATA_C ; 0x43 C
DC.B SSD_DATA_D ; 0x44 D
DC.B SSD_DATA_E ; 0x45 E
DC.B SSD_DATA_F ; 0x46 F
DC.B SSD_DATA_SP ; 0x47 G
DC.B SSD_DATA_H ; 0x48 H
DC.B SSD_DATA_SP ; 0x49 I
DC.B SSD_DATA_SP ; 0x4a J
DC.B SSD_DATA_SP ; 0x4b K
DC.B SSD_DATA_L ; 0x4c L
DC.B SSD_DATA_SP ; 0x4d M
DC.B SSD_DATA_SP ; 0x4e N
DC.B SSD_DATA_SP ; 0x4f O
DC.B SSD_DATA_SP ; 0x50 P
DC.B SSD_DATA_SP ; 0x51 Q
DC.B SSD_DATA_SP ; 0x52 R
DC.B SSD_DATA_SP ; 0x53 S
DC.B SSD_DATA_SP ; 0x54 T
DC.B SSD_DATA_SP ; 0x55 U
DC.B SSD_DATA_SP ; 0x56 V
DC.B SSD_DATA_SP ; 0x57 W
DC.B SSD_DATA_SP ; 0x58 X
DC.B SSD_DATA_SP ; 0x59 Y
DC.B SSD_DATA_SP ; 0x5a Z
DC.B SSD_DATA_SP ; 0x5b [
DC.B SSD_DATA_SP ; 0x5c \
DC.B SSD_DATA_SP ; 0x5d ]
DC.B SSD_DATA_SP ; 0x5e ^
DC.B SSD_DATA_SP ; 0x5f _
;******************************************************************************
; RAM 上のデータ(初期化なし)
;******************************************************************************
SEGMENT BSS
SSD_DIGIT: DS.B 1 ; 現在描画している桁
;******************************************************************************
; RAM 上のデータ(初期化あり)
;******************************************************************************
SEGMENT DATA
SSD_DATA: DCB.B SSD_NUM,SSD_DATA_SP ; 表示データ
プログラム部分は、まず初期化ルーチンから。桁位置保存用のワークの初期化と、ポート設定。\\
あとは、各桁を切り替えながら自動で描画するために、タイマを1msで回します。
;******************************************************************************
; 7セグの初期化
;
; _SsdInit
; 2004/12/30 : 初期バージョン完成
;
; [書式] void SsdInit(void) ;
;
; [IN] なし
;
; [OUT] なし
;
; [DED] R0
;******************************************************************************
public _SsdInit
_SsdInit: SUB.B R0L,R0L
MOV.B R0L,@SSD_DIGIT
DEC.B R0L
MOV.B R0L,@SSD_DIGIT_DR
MOV.B R0L,@SSD_DATA_DR
;------------------------------------------------------------------------------
; タイマ 2 を 1ms で回す
;------------------------------------------------------------------------------
MOV.B #00100011B,R0L ; GRA のコンペアマッチ
MOV.B R0L,@TCR2 ; b6-b5 : インプットキャプチャで TCNT をクリア
; b4-b3 : 立上がりエッジでカウント
; b2-b0 : 内部クロック:φ/8 でカウント
SUB.W R0,R0
MOV.W R0,@TCNT2 ; カウンタをクリア
MOV.B R0L,@TIOR2 ; 出力端子無効
INC.B R0L ; タイマ割り込み有効
MOV.B R0L,@TIER2
MOV.W #CPU_CLOCK_8 / 1000,R0 ; 1ms(1000Hz) にカウンタを合わせる
MOV.W R0,@GRA2
BCLR #0,@TSR2 ; 割り込み要求ののクリア
BSET.B #2,@TSTR ; ITU2 のタイマスタート
RTS
文字列を7セグ用のデータに変換します。桁数オーバーのチェックは行ってますが、足りない場合の\\
処理は入れていないので、文字列が短い場合は足りない部分は古いデータが出たままになってしまいます。\\
また、. が来た場合は、一つ前のデータにビットを立てて処理しています。
;******************************************************************************
; 7セグの描画用に文字列変換
;
; _SsdDraw
; 2005/01/05 : 初期バージョン完成
;
; [書式] void SsdDraw(char *str) ;
;
; [IN] char *str = 文字列のポインタ
;
; [OUT] なし
;
; [DED] R0,ER1,ER2,ER3
;******************************************************************************
public _SsdDraw
_SsdDraw: MOV.L @(4,ER7),ER1 ; ER1 = *str
SUB.L ER2,ER2 ; ER2 = 0
MOV.L #SSD_DATA,ER3 ; ER3 = *SSD_CODE_TBL
MOV.B #SSD_NUM,R0H ; R0H = 桁数
MOV.B @ER1+,R2L ; 1 文字取得
SSD_DRAW_LOOP: MOV.B #SSD_DATA_SP,R0L ; R0L = ' '
BLD.B #7,R2L ; 0x80 以上?
BCS CHECK_DOT:8
CMP.B #60H,R2L ; 0x60 以上?
BCS SKIP_SUB_20:8
ADD.B #-20H,R2L ; 小文字を大文字に変換
SKIP_SUB_20:
ADD.B #-20H,R2L ; 0x20 未満?
BCC CHECK_DOT:8
MOV.B @(SSD_CODE_TBL,ER2),R0L ; 7セグ点灯データに変換
CHECK_DOT: MOV.B @ER1+,R2L ; 次の 1 文字取得
CMP.B #'.',R2L ; . かチェック
BNE SSD_SET:8
BNOT.B #7,R0L ; . のビットを反転
MOV.B @ER1+,R2L ; 次の文字の再取得
SSD_SET: MOV.B R0L,@ER3
INC.L #1,ER3
DEC.B R0H
BNE SSD_DRAW_LOOP:8
RTS
割り込み処理(ベクタ 32)は、一桁分のデータをセットし、桁を進めるだけの単純なものです。\\
注意点は、桁を変える前にデータOFFにしておき、桁が変わった瞬間に前の桁が出ないようにします。
;******************************************************************************
; 7セグの描画割り込み
;
; INT_SSD_DRAW
; 2005/01/05 : 初期バージョン完成
;
; [IN] なし
;
; [OUT] なし
;
; [DED] なし
;******************************************************************************
public INT_SSD_DRAW
INT_SSD_DRAW: PUSH.L ER0
PUSH.L ER1
MOV.B #SSD_DATA_SP,R0L ; 桁を切り替える前にデータクリア
MOV.B R0L,@SSD_DATA_PORT
MOV.B @SSD_DIGIT,R0L ; 桁の切り替え
MOV.B R0L,@SSD_DIGIT_PORT
EXTU.W R0
EXTU.L ER0
MOV.L #SSD_DATA + (SSD_NUM - 1),ER1
SUB.L ER0,ER1
MOV.B @ER1,R0H
MOV.B R0H,@SSD_DATA_PORT
INC.B R0L ; 桁を進めておく
CMP.B #SSD_NUM,R0L
BNE INT_SSD_SKIP:8
SUB.B R0L,R0L
INT_SSD_SKIP: MOV.B R0L,@SSD_DIGIT
POP.L ER1
POP.L ER0
BCLR.B #0,@TSR2
RTE
動作チェック用のサンプル。
extern void SsdInit(void) ;
extern void SsdDraw(char *str) ;
void main(void) {
int num = 0 ;
_di() ;
SsdInit() ;
_ei() ;
while(1) {
char str[8] ;
sprintf(str,"%03d-%02x",num,num) ;
if(++ num > 255) num = 0 ;
SsdDraw(str) ;
Wait1ms(500) ;
}
}
===== 実行結果 =====
{{7seg12.jpg}}