====== 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}}