* マトリクスLEDの表示方法の原理 [#f905e0e4]

#ref(DD_matrix.png,,20%)

※データシート→http://akizukidenshi.com/download/ds/optosupply/OSL641501-XX.pdf (-BRAのほう)

マトリクスLEDは、↑のようにたくさんのLEDが、格子状に縦横につながっています。
すべてのLEDを一斉に点灯/消灯をすることはできませんので、1列ずつ、表示させます(ダイナミック駆動)。
これは、以下のような手順で、1列ずつ、各8個のLEDを点灯/消灯する、ことを素早く順に行うことで、残像効果よって「すべての列が点灯しているように見える」というものです。
+ COL1のみ"L"、COL2〜8を"H"とする。このとき、一番左の列の縦並び8個のLEDのうち、点灯させたいLEDがつながっている横の線(ROW)を"H"、消灯したいLEDがつながっているものを"L"とする。これにより、一番左の列の8個のLEDを、点灯/消灯でき、それより右の列のLEDはすべて消灯する。(※LEDは順方向に電圧をくわえたときのみ点灯するため)
+ 少し時間がたってから、COL2のみ"L"、COL1,3〜8を"H"とする。このとき、左から2番目の列の縦並び8個のLEDのうち、点灯させたいLEDがつながっている横の線(ROW)を"H"、消灯したいLEDがつながっているものを"L"とする。これにより、左から2番目の列の8個のLEDを、点灯/消灯でき、それ以外の列のLEDはすべて消灯する。
+ 同様に、COL3〜COL8まで繰り返し、その後、COL1から繰り返す。
これを、例えば1列あたり3msごとに行えば、すべての列の表示が終わるまでに3ms×8=24msですので、1秒間に40回ほど表示を更新することができることになります。(いわゆるフレームレートが毎秒40フレームということ)

* タイマ割り込み [#l74b5506]

このような動作は、メインプログラムの動作とは独立に行った方が、メインプログラムの記述が楽ですので、タイマ割り込みという手法を使って、メインプログラムとは独立に行うことにします。
これは、一定時間ごとに、指定した関数が自動的に呼び出される、というもので、一時的にメインプログラムの動作は中断されますが、事実上、メインプログラムは、このようなLED表示動作を気にすることなく、記述・動作することができます。
このタイマ割り込みは、Timer8ユーザモジュールを用います。

#ref(DD_timer8.png,,20%)

↑のようにTimer8_1モジュールのパラメータを設定しておきます。
この中の「InterruptType」が、このTimer8_1が割り込みを起こす条件で、この場合は"Terminal Count"、つまりタイマのカウントが終了したとき、ということになります。タイマのカウントは、VC3をクロック(計算すると76.8kHz)として、Period(周期)が255まで、とありますので、タイマのカウントが終了するまでの時間は、1/(76.8kHz÷255)=3.3ms、となりますので、約3msごとに、タイマ割り込みが発生します。
タイマ割り込みが発生したときには、対応する関数(割り込み処理関数: Interrupt Service Routine; ISR)が呼ばれますが、PSoC1では、「モジュール名_ISR()」という関数名、と決まっています。少しおまじないを加えて、以下のように呼ばれる関数を記述すれば、この関数が約3msごとに、自動的に呼ばれることになります。

 #pragma interrupt_handler Timer8_1_ISR
 void Timer8_1_ISR()
 {
   ....
 }

* ダイナミック駆動のLED制御の準備 [#c3abcd12]

ダイナミック駆動では、行方向(ROW1〜8)と列方向(COL1〜8)を、それぞれ"H"/"L"とする必要があります。
そこでPSoC1のモジュールとして、それぞれに対応するLEDを配置しておきましょう。ちょっと数が多い(合計16個)ですが、がんばって。

#ref(DD_led1.png,,20%)

↑行方向は、こんな感じでLED_R1〜LED_R8を置きます。それぞれのPortとPinは、実際にマトリクスLEDがつながっているポート番号を設定します。
行方向は、点灯したい行を"H"にしますので、ActiveHigh、つまりLED_R1_On()で対応する出力ピンが"H"となるようにしておきます。

#ref(DD_led2.png,,20%)

↑列方向も、同様にLED_C1〜LED_C8を置き、PortとPinを、実際にマトリクスLEDがつながっているポート番号を設定します。
列は、点灯したい列を"L"にしますので、ActiveLow、つまりLED_C1_On()で対応する出力ピンが"L"となるようにしておきます。

* ダイナミック駆動の全体 [#d864d5c4]

以上の準備をふまえて、ダイナミック駆動の全体プログラムは、例えば以下のような感じになります。
pat[]に、各列で表示したいON/OFFのパターンを設定しておきます。例えばpat[0]=0x01(二進数で00000001)ならば、1列目では、ROW1に対応するLEDが点灯することになります。
変数colは、各タイマ割り込みで表示するべき列番号で、タイマ割り込みが呼ばれるごとに、その値に応じた列の表示パターンであるpat[col]に応じて、点灯するべきLEDの行のみOn("H")としています。その後、colを1ずつ増やし、8列の次に1列に戻しています。
main()では、表示するべきパターンの設定をしてタイマ割り込みが起こるように設定したあとは、何もしなくても、自動的にタイマ割り込みでマトリクスLEDのダイナミックが行われるので、main()の処理は、とても楽になります。

 BYTE pat[8];
 BYTE col;
 
 #pragma interrupt_handler Timer8_1_ISR
 void Timer8_1_ISR()
 {
   LED_C1_Off(); LED_C2_Off(); LED_C3_Off(); LED_C4_Off();
   LED_C5_Off(); LED_C6_Off(); LED_C7_Off(); LED_C8_Off();
   if (pat[col] & 0x01) LED_R1_On(); else LED_R1_Off();
   if (pat[col] & 0x02) LED_R2_On(); else LED_R2_Off();
   if (pat[col] & 0x04) LED_R3_On(); else LED_R3_Off();
   if (pat[col] & 0x08) LED_R4_On(); else LED_R4_Off();
   if (pat[col] & 0x10) LED_R5_On(); else LED_R5_Off();
   if (pat[col] & 0x20) LED_R6_On(); else LED_R6_Off();
   if (pat[col] & 0x40) LED_R7_On(); else LED_R7_Off();
   if (pat[col] & 0x80) LED_R8_On(); else LED_R8_Off();
   switch (col){
     case 0 : LED_C1_On(); break;
     case 1 : LED_C2_On(); break;
     case 2 : LED_C3_On(); break;
     case 3 : LED_C4_On(); break;
     case 4 : LED_C5_On(); break;
     case 5 : LED_C6_On(); break;
     case 6 : LED_C7_On(); break;
     case 7 : LED_C8_On(); break;
   }
   col = col + 1; if (col == 8) col = 0;
 }
 
 
 void main(void)
 {
   pat[0] = 0x01; // 00000001
   pat[1] = 0x02; // 00000010
   pat[2] = 0x04; // 00000100
   pat[3] = 0x08; // 00001000
   pat[4] = 0x10; // 00010000
   pat[5] = 0x20; // 00100000
   pat[6] = 0x40; // 01000000
   pat[7] = 0x80; // 10000000
 
   col = 0;
 
   M8C_EnableGInt ; // Uncomment this line to enable Global Interrupts
   Timer8_1_EnableInt();
   Timer8_1_Start();
 
   while (1){
   }
 }

IP:133.28.201.12 TIME:"2016-11-04 (金) 16:08:26" REFERER:"http://ifdl.jp/micon-bu/index.php?cmd=edit&page=%A5%C1%A5%E5%A1%BC%A5%C8%A5%EA%A5%A2%A5%EB%2FPSoC1duino_%A5%DE%A5%C8%A5%EA%A5%AF%A5%B9LED%CA%D4" USER_AGENT:"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36"

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS