PICでCの練習 2007.06.01(金)〜 LessonC_23。7セグメントLEDで4桁の数字を表示します。
著作者名: 中野 良知 作成開始: 2007.06.01(金)
目次 1. 目的 2. ゼネラルフローチャート 3. プログラムソースコード 4. キーワード 4.1. ダイナミック点灯 4.2. セグメント点灯データ 4.3. セグメント電流 5. 実行結果 6. 実験回路 1. 目的 7セグメントの数字表示用LEDを使用して、4桁の16進数を表示します。 ダイナミック点灯方式を採用、1桁当り1msec、4msecで一巡します。 表示する4桁の16進数は10msecごとにインクリメントします。 2. ゼネラルフローチャート (main) ↓ プルアップ許可 ↓ TMR0割り込み許可 ↓ ポートの初期化 ↓ ├←──────────┐ ↓ no │ <10msec経過?>→─────┤ ↓yes │ 表示Noインクリメント │ ↓ │ 表示Noを4ビット単位で │ 表示バッファーに格納 │ ↓ │ └───────────┘ (TMR0割り込み) ↓ TMR0=1msec ↓ 割り込みフラグリセット ↓ 全桁消灯 ↓ 走査順の桁データを セグメントデータに変換 ↓ セグメントデータ出力 ↓ 走査順の桁を点灯 ↓ 走査順を更新 ↓ 1msecカウンタインクリメント ↓ (終了) 3. プログラムソースコード //***************************************************************************** // タイトル : LesssonC_23 // 作者 : ioio // 目的 : 4桁の7セグメントLEDをダイナミック方式で駆動します。 // マイコン : PIC16F84A // クロック : 20MHz // Config : PROTECT=OFF, WDTE=OFF, XTAL // Compiler : PICC Lite(V9.6)。 HI-TEC software製。 // Compile : >picl -16f84a lesson.c // ASM List : >picl -16f84a --ASMLIST lesson.c //***************************************************************************** // 変更履歴 // 2007.05.30(水) 作成 // 2007.06.01(金) カソードコモンLED用データを追加 //***************************************************************************** //----------------------------------------------------------------------------- // ヘッダーファイル #include "pic.h" // デバイス関連の定義を展開 //----------------------------------------------------------------------------- // コンフィグレーション定義 __CONFIG(0x3FFA); // PROTECT=OFF, WDTE=OFF, HS_OSILLATOR //----------------------------------------------------------------------------- // 関数定義 //----------------------------------------------------------------------------- // 定数の定義 #define ANODE_COMM 1 // 7segLEDがアノードコモンの場合に1 #define CATHORD_COMM 0 // 7segLEDがカソードコモンの場合に1 #if ANODE_COMM == 1 // セグメント変換(アノードコモン用) const unsigned char seg_data[16] = { 0x40, 0x79, 0x24, 0x30, 0x19, 0x12, 0x02, 0x58, 0x00, 0x18, 0x08, 0x03, 0x27, 0x21, 0x06, 0x0E }; // 桁走査ビット(アノードコモン用) const unsigned char scan[4] = {1,2,4,8}; #endif #if CATHORD_COMM == 1 // セグメント変換(カソードコモン用) const unsigned char seg_data[16] = { 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x27, 0x7F, 0x67, 0x77, 0x7C, 0x58, 0x5E, 0x79, 0x71 }; // 桁走査ビット(カソードコモン用) const unsigned char scan[4] = {0xE,0xD,0xB,0x7}; #endif #define SET_TMR0 256-156 // TMR0設定=156*32*200ns=998.4us //----------------------------------------------------------------------------- // グローバル変数定義 unsigned char digit_no; // 表示走査桁指定 unsigned char dsp_buf[4]={0,0,0,0}; // 表示バッファー int t_cnt; // TMR0割込み回数 int dsp_cnt; // 表示用カウント //----------------------------------------------------------------------------- // ビットフィールド構造体定義 //----------------------------------------------------------------------------- // ポートマップ // NAME PIN NO I/O USE // -----+--------+-----+----------------------------------------- // RA0 17 O 1st Digit。d0 // RA1 18 O 2nd Digit。d1 // RA2 1 O 3rd Digit。d2 // RA3 2 O 4th Digit。d3 // RA4 3 I - // RB0 6 O a segment // RB1 7 O b segment // RB2 8 O c segment // RB3 9 O d segment // RB4 10 O e segment // RB5 11 O f segment // RB6 12 O g segment // RB7 13 I - //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void main(void) { INTCON = 0b10100000; // 割り込み制御初期化設定 OPTION = 0b01000100; // プリスケール=1/32 TMR0 = SET_TMR0; // タイマー0設定 TRISA = 0x10; // PortA b3,b2,b1,b0=Out。b4=In TRISB = 0x80; // PortB b7=In、b6,b5,b4,b3,b2,b1,b0=Out PORTB = 0x80; // ポートB初期化。b7=プルアップ。 PORTA = 0x00; // ポートA初期化。 digit_no = 0; // 走査桁NoをLSDに初期化 t_cnt = 0; // TMR0割込み回数を初期化 dsp_cnt = 0; // 表示カウンタを初期化 while(1){ if(t_cnt == 10){ // 10msec経過したら t_cnt = 0; // TMR0割込み回数初期化 dsp_cnt++; // 表示カウンタをインクリメント // 表示バッファーに4ビット単位で設定 dsp_buf[0] = (unsigned char)(dsp_cnt & 0x0F); dsp_buf[1] = (unsigned char)((dsp_cnt >> 4) & 0x0F); dsp_buf[2] = (unsigned char)((dsp_cnt >> 8 ) & 0x0F); dsp_buf[3] = (unsigned char)((dsp_cnt >> 12) & 0x0F); } } } //----------------------------------------------------------------------------- // 機能 : TMR0割り込み関数 // 引数 : なし // 戻値 : なし // 作成 : 2007.05.30(水) //----------------------------------------------------------------------------- static void interrupt isr(void) { TMR0 = SET_TMR0; // タイマー0設定 T0IF = 0; // タイマー0オーバーフローフラグリセット PORTA = 0x10; // 走査ビットオフ。全桁消灯 // セグメントデータ出力。b7=プルアップ PORTB = seg_data[dsp_buf[digit_no]] + 0x80; PORTA = scan[digit_no]; // 走査ビット出力 if(++digit_no == 4){ // 一巡したら digit_no = 0; // 表示桁を1桁目に設定 } t_cnt++; // TMR0割込み回数インクリメント } //***************************************************************************** //***************************************************************************** 4. キーワード 4.1. ダイナミック点灯 │←─────────→│4msec →│─│←1msec ┌─┐ ┌─┐ 桁走査d0───┘ └─────────┘ └────────────── ┌─┐ ┌─┐ 桁走査d1───────┘ └─────────┘ └────────── ┌─┐ ┌─┐ 桁走査d2───────────┘ └─────────┘ └────── ┌─┐ ┌─┐ 桁走査d3───────────────┘ └─────────┘ └── →│─│←ブランク期間 セグメント ┌───┬───┬───┬───┬───┬───┬───┬─ a〜g ──┴───┴───┴───┴───┴───┴───┴───┴─ 桁走査信号で各桁を順に表示します。 桁走査に先行して、セグメントデータを出力します。 ブランク期間で全桁を消灯して表示のちらつきを防止します。 上記のタイミングチャートでは、ブランク期間を分かりやすくする為に拡大していま す。 桁走査信号を各桁ごとに、セグメント信号を各桁共通に接続します。 桁走査d0 ─────────────────┐ 桁走査d1 ─────────────┐ │ 桁走査d2 ─────────┐ │ │ 桁走査d3 ─────┐d3 │d2 │d1 │d0 ┌┴┐ ┌┴┐ ┌┴┐ ┌┴┐ │8│ │8│ │8│ │8│ セグメント └┬┘ └┬┘ └┬┘ └┬┘ a〜g ─────┴───┴───┴───┘ 桁走査信号はTMR0のオーバーフロー割込みで切り換えます。 4.2. セグメント点灯データ 7セグメントLED表示器の各セグメントの名称 a ━ f┃g ┃b ━ e┃ ┃c ━ d 駆動データ active High active Low 表示 g f e d c b a g f e d c b a 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 1 0 0 0 0 1 1 0 1 1 1 1 0 0 1 2 1 0 1 1 0 1 1 0 1 0 0 1 0 0 3 1 0 0 1 1 1 1 0 1 1 0 0 0 0 4 1 1 0 0 1 1 0 0 0 1 1 0 0 1 5 1 1 0 1 1 0 1 0 0 1 0 0 1 0 6 1 1 1 1 1 0 1 0 0 0 0 0 1 0 7 0 1 0 0 1 1 1 1 0 1 1 0 0 0 8 1 1 1 1 1 1 1 0 0 0 0 0 0 0 9 1 1 0 0 1 1 1 0 0 1 1 0 0 0 A 1 1 1 0 1 1 1 0 0 0 1 0 0 0 b 1 1 1 1 1 0 0 0 0 0 0 0 1 1 c 1 0 1 1 0 0 0 0 1 0 0 1 1 1 d 1 0 1 1 1 1 0 0 1 0 0 0 0 1 E 1 1 1 1 0 0 1 0 0 0 0 1 1 0 F 1 1 1 0 0 0 1 0 0 0 1 1 1 0 例: activ Low用(アノードコモン) const unsigned char seg_data[16] = { 0x40, 0x79, 0x24, 0x30, 0x19, 0x12, 0x02, 0x58, 0x00, 0x18, 0x08, 0x03, 0x27, 0x21, 0x06, 0x0E }; activ High用(カソードコモン) const unsigned char seg_data[16] = { 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x27, 0x7F, 0x67, 0x77, 0x7C, 0x58, 0x5E, 0x79, 0x71 }; 4.3. セグメント電流 Is ┌─┐ ┌─┐ │ │ │ │ │ │ │ │ Ia - -│ │- - - - - - - - - │ │- - - - - - ──┘ └─────────┘ └────── 点灯中の1つのセグメントの電流はIs、平均するとIa=Is/4です。 ポート出力=4.5V、LEDの順方向電圧=1.8V、電流制限抵抗=820Ωの時、 Is=(4.5-1.8)/820=3.29mA。Ia=3.29mA/4=0.823mAです。 "8"を表示中の7セグメントの合計電流=3.29mA×7=23.03mA です。 5. 実行結果 上:d0信号 下:d1信号 ブランク期間は5usecです。 6. 実験回路 PIC16F84A ┌────┐14 │ VDD├──────●──────●────●───← +5V │ │ │ │0.1u │ │ │ R10K ┴ /50V │┴│100u/16V │ │4 │ 0.1u/50V ┬ └┬┘ │ -MCLR├──────●─┤├───●────●──── 0V │ │ │ │ │16 ┌ ─ ─ ─ ┐ │ │ OSC1├───●─┤├──┐ │ │ │ │┴ ││ │ │ │ □ 20MHz │ │ │ │15 │┬ ││ │ │ OSC2├───●─┤├──● │ │ │ └ ─ ─ ─│┘ │ │ │5 ┌───────┘ │ │ Vss├─●───────────┘ │ │ │ │17 │ RA0├─────────────────────┐ │ │18 │ │ RA1├────────────────┐ │ │ │1 │ │ │ RA2├───────────┐ │ │ │ │2 │ │ │ │ RA3├──────┐ │ │ │ │ │ │d3 │d2 │d1 │d0 │ │ ┌┴─┐ ┌┴─┐ ┌┴─┐ ┌┴─┐ │ │ │ 8 │ │ 8 │ │ 8 │ │ 8 │ │ │ └┰┰┘ └┰┰┘ └┰┰┘ └┰┰┘ │ │6 a ┃┃a〜g ┃┃a〜g ┃┃a〜g ┃┃a〜g │ RB0├──R820━━╋┻━━━┻┻━━━┻┻━━━┻┛ │ │7 b ┃ │ RB1├──R820━━┫ │ │8 c ┃ │ RB2├──R820━━┫ │ │9 d ┃ │ RB3├──R820━━┫ │ │10 e ┃ │ RB4├──R820━━┫ │ │11 f ┃ │ RB5├──R820━━┫ │ │12 g ┃ │ RB6├──R820━━┛ │ │ └────┘ 電源パスコン0.1u/50VのセラミックコンデンサーはVDDとVssの近くに接続します。 発振子のGNDはVssの直ぐ近くに接続します。
LessonCのTopへ
サイトのTopへ
法律条項 この資料により生じたいかなる障害や損害に対し、著者は全てを免責されるものとします。 この資料は、著作権法の下で保護され、入手先、著者、日付、法律条項を含んだ場合にのみ複製が可能です。
inserted by FC2 system