ATtiny861A で 4桁7セグLEDを点灯

ATtiny

今後メインで使うマイコン、AVR(ATtiny) と PIC で迷ってます。
調べてみるとATtinyでも機能をフルに引き出すにはAruduino IDEよりもMPLABが良いらしくて
であれば、Aruduino IDEがMPLABより容易、というのはあまり理由にならないかな。

で、MPLABを使う事が前提ならPICのほうが素直に使えるのか?

よくわからないので、しばらく両方を使ってみる事にしました。

手持ちのATtiny861Aで4桁の7セグLEDを点けてみます。今回はカソードコモンを使用。特に理由はありません。たまたま先に手に取ったのがカソードコモンでした。

まずは配線。

Aruduino UNOをライターにしてATtinyにプログラムを書き込んでいます。図では抵抗が220Ωになっていますが実際に使ったのは820Ωです。ATtinyのHIGHは概ね電源電圧になるそうで、今回はArduino Unoの3.3Vを使ったので概ね3.3V。LEDのデータシートによるとVFが2.0Vなので約1.6mA流れる計算。

まずはピンの定義。こういう書き方は邪道なのかもしれませんが(たぶん、右のコメントのような形を使うのが王道?)ピン番号で書くほうが僕としてはわかりやすいので。。。

#define BAR_A  2 // PA2
#define BAR_B  0 // PA0
#define BAR_C  1 // PA1
#define BAR_D  7 // PA7
#define BAR_E  3 // PA3
#define BAR_F  6 // PA6
#define BAR_G  4 // PA4
#define BAR_P  5 // PA5

#define COM_1 14 // PB7
#define COM_2 13 // PB6
#define COM_3 12 // PB5
#define COM_4 11 // PB4

setup()は、サラッと

void setup() {
  pinMode(BAR_A, OUTPUT);
  pinMode(BAR_B, OUTPUT);
  ・
  ・
  ・
  pinMode(COM_3, OUTPUT);
  pinMode(COM_4, OUTPUT);
}

ここから先は、思いつきのツギハギなので美しくないです。
まずは1桁の表示

void Disp(int p[8])
{
  if (p[0]) digitalWrite(BAR_A, HIGH); else digitalWrite(BAR_A, LOW);
  if (p[1]) digitalWrite(BAR_B, HIGH); else digitalWrite(BAR_B, LOW);
  if (p[2]) digitalWrite(BAR_C, HIGH); else digitalWrite(BAR_C, LOW);
  if (p[3]) digitalWrite(BAR_D, HIGH); else digitalWrite(BAR_D, LOW);
  if (p[4]) digitalWrite(BAR_E, HIGH); else digitalWrite(BAR_E, LOW);
  if (p[5]) digitalWrite(BAR_F, HIGH); else digitalWrite(BAR_F, LOW);
  if (p[6]) digitalWrite(BAR_G, HIGH); else digitalWrite(BAR_G, LOW);
  if (p[7]) digitalWrite(BAR_P, HIGH); else digitalWrite(BAR_P, LOW);
}

void DispNumber(int i)
{
  int p[8];
  switch(i){
    case 0: p[0] = 1; p[1] = 1; p[2] = 1; p[3] = 0; p[4] = 1; p[5] = 1; p[6] = 1; p[7] = 0; break;
    case 1: p[0] = 0; p[1] = 0; p[2] = 1; p[3] = 0; p[4] = 0; p[5] = 1; p[6] = 0; p[7] = 0; break;
    case 2: p[0] = 1; p[1] = 0; p[2] = 1; p[3] = 1; p[4] = 1; p[5] = 0; p[6] = 1; p[7] = 0; break;
    case 3: p[0] = 1; p[1] = 0; p[2] = 1; p[3] = 1; p[4] = 0; p[5] = 1; p[6] = 1; p[7] = 0; break;
    case 4: p[0] = 0; p[1] = 1; p[2] = 1; p[3] = 1; p[4] = 0; p[5] = 1; p[6] = 0; p[7] = 0; break;
    case 5: p[0] = 1; p[1] = 1; p[2] = 0; p[3] = 1; p[4] = 0; p[5] = 1; p[6] = 1; p[7] = 0; break;
    case 6: p[0] = 1; p[1] = 1; p[2] = 0; p[3] = 1; p[4] = 1; p[5] = 1; p[6] = 1; p[7] = 0; break;
    case 7: p[0] = 1; p[1] = 0; p[2] = 1; p[3] = 0; p[4] = 0; p[5] = 1; p[6] = 0; p[7] = 0; break;
    case 8: p[0] = 1; p[1] = 1; p[2] = 1; p[3] = 1; p[4] = 1; p[5] = 1; p[6] = 1; p[7] = 0; break;
    case 9: p[0] = 1; p[1] = 1; p[2] = 1; p[3] = 1; p[4] = 0; p[5] = 1; p[6] = 1; p[7] = 0; break;
  }
  Disp(p);
}

もっと上手い方法があるはず。そのうち考えよう。。。
4桁表示。引数のlengthで表示時間を調整(ループさせてるだけです)

void Disp4digit(int i, unsigned length)
{
  digitalWrite(COM_1, HIGH); digitalWrite(COM_2, HIGH); digitalWrite(COM_3, HIGH); digitalWrite(COM_4, HIGH);
  for (unsigned j = 0; j < length; ++j){
    int n = (int)(i / 1000);
    digitalWrite(COM_1, LOW); DispNumber(n); delay(5); digitalWrite(COM_1, HIGH); 
    int i2 = i % 1000; n = (int)(i2 / 100);
    digitalWrite(COM_2, LOW); DispNumber(n); delay(5); digitalWrite(COM_2, HIGH); 
    i2 %= 100; n = (int)(i2 / 10);
    digitalWrite(COM_3, LOW); DispNumber(n); delay(5); digitalWrite(COM_3, HIGH); 
    i2 %= 10; n = i2;
    digitalWrite(COM_4, LOW); DispNumber(n); delay(5); digitalWrite(COM_4, HIGH); 
  }
}

コモン(カソード)をLOWにして桁数を選択。最初はDispNumber()のあと、すぐにコモンをHIGHにしましたが、ちらつきが強くて読みにくいのでDispNumber()してからコモンをHIGHにするまでの間にdelay()を入れたら表示がきれいになりました。

コメント

タイトルとURLをコピーしました