7セグでカウンタ表示

7セグで何を表現できるか

7セグで表現できるものは、10進数で使う0~9、16進数で使うA~F、High LowのH,L。
それから-記号が表現可能です。ドットは必要なときにONします。

プログラムの作成

まずは、ポートの設定と、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

h8/7セグでカウンタ表示.txt · 最終更新: 2018/03/18 09:56 (外部編集)
 
特に明示されていない限り、本Wikiの内容は次のライセンスに従います: CC Attribution-Share Alike 4.0 International
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki