7セグメントLEDドライバTM1637は電子工作の代名詞的なLED表示器をシリアル通信で6桁までドライブできて安価なので重宝しています。
TM1637を表示だけに使っていたのですが,16個までキースキャニングできる機能もあるので試してみました。
機材は手持ちの以下です。
MPU:ATtiny402
7segLED:TOT5321BS-9B(3桁)
LEDドライバ:TM1637
スイッチ:タクトスイッチ,5個
大まかな構成と接続です。
キースキャニングして1byteのスキャン値を表示してみました。
何も押されていない時の値は"255"で,各スイッチは3bitとK1, K2の組み合わせで表現されます。
TM1637の表示とキースキャンのソフトの概要
TM1637のシリアル通信はI2Cのようでスレイブアドレスなどが無い独自の様式ですね(^^)。
1.表示のコマンドと流れ
2.キースキャンニングのコマンドと流れ
☆ 注意が必要な点
・TM1637のACKは8回目のクロックを終えた時にデータ線のLOWで表現されます。この時はホスト側の出力もLOWにしておき,その後ホストからクロックを1回出してACKを終了させます。
・キースキャンのバイトを読み込み,ACKを終えたらデータピンを出力に戻さないと"END"の出力もできません(^^;;;;;;;。
ま,何とか無事にキースキャンもできました。8pinのMPUなどでボタンスイッチが何個か欲しい時には便利そうです。
以下に,チェックプログラムをメモしておきます。1KB未満のプログラムなのでATtiny202でも動かしてみようかなと思っています。
TM1637を表示だけに使っていたのですが,16個までキースキャニングできる機能もあるので試してみました。
機材は手持ちの以下です。
MPU:ATtiny402
7segLED:TOT5321BS-9B(3桁)
LEDドライバ:TM1637
スイッチ:タクトスイッチ,5個
大まかな構成と接続です。
キースキャニングして1byteのスキャン値を表示してみました。
何も押されていない時の値は"255"で,各スイッチは3bitとK1, K2の組み合わせで表現されます。
TM1637の表示とキースキャンのソフトの概要
TM1637のシリアル通信はI2Cのようでスレイブアドレスなどが無い独自の様式ですね(^^)。
1.表示のコマンドと流れ
2.キースキャンニングのコマンドと流れ
☆ 注意が必要な点
・TM1637のACKは8回目のクロックを終えた時にデータ線のLOWで表現されます。この時はホスト側の出力もLOWにしておき,その後ホストからクロックを1回出してACKを終了させます。
・キースキャンのバイトを読み込み,ACKを終えたらデータピンを出力に戻さないと"END"の出力もできません(^^;;;;;;;。
ま,何とか無事にキースキャンもできました。8pinのMPUなどでボタンスイッチが何個か欲しい時には便利そうです。
以下に,チェックプログラムをメモしておきます。1KB未満のプログラムなのでATtiny202でも動かしてみようかなと思っています。
/**** Check_Program for ATtiny402, 412
3digit LED & Key (TM1637) */
// I/O Pin for TM1637 LED Driver
#define dataPin 0
#define clockPin 1
// 7Seg LED Data 0,1,,,9
byte segData[10]={0x3F,0x06,0x5B,0x4F,0x66,
0x6D,0x7D,0x07,0x7F,0x6F};
byte dispN[3]; // 3digit
void setup() {
pinMode(dataPin, OUTPUT ); // Set Pin for TM1637
pinMode(clockPin, OUTPUT );
delay (100); // waiting 100ms
/* Init TM1637, Command1 */
// 0b0100 0S00, S=0/1(Auto increment /fix Address)
sStart();
s1byte(0b01000000);
sEnd();
}
void loop() {
byte nm=rData(); // Read Key status
dispN[0]=segData[nm/100];
dispN[1]=segData[(nm%100)/10];
dispN[2]=segData[nm%10];
// send data (start position, number of digits)
sData(0, 3);
sCommand3(); // show the data
delay (50);
}
/* send data: Command2(set RAM Address) and write data */
void sData(byte st, byte dig){
sStart();
s1byte(0xC0+st); // TM1637 Address (0xC0-C5)
for(byte i=0; i < dig; i++){
s1byte(dispN[i]);
}
sEnd();
}
/* read Key : command1 (key enable), read key */
byte rData(){
byte kv=0; // key value
// 0b0100 0SR0, S=0/1(Auto increment /fix Address), R=1(Read)
sStart();
s1byte(0b01000010); // set read key mode
pinMode(dataPin, INPUT ); // Set Pin for read key
kv=shiftIn(dataPin, clockPin, LSBFIRST); // Read 1byte
digitalWrite(clockPin,HIGH); // 9th pulse
digitalWrite(clockPin,LOW);
pinMode(dataPin, OUTPUT ); // Reset Pin for output
digitalWrite(dataPin,LOW);
sEnd();
sStart();
s1byte(0b01000000); // Reset write mode
sEnd();
return kv;
}
// Command3,Display and Brightness setting
void sCommand3(){
sStart();
// 0b1000 DBBB (D:on/off Brightness:000-111)
s1byte(0b10001011);
sEnd();
}
/* Start signal of serial comm. */
void sStart(){
digitalWrite(dataPin,HIGH) ; // DIO High
digitalWrite(clockPin,HIGH) ; // Clock High
digitalWrite(dataPin,LOW); // DIO High->Low
}
/* End signal of serial comm. */
void sEnd(){
digitalWrite(clockPin,HIGH) ; // Clock High
digitalWrite(dataPin,HIGH); // DIO Low->High
}
/* send 1byte of command or data */
void s1byte(byte byteData){
digitalWrite(clockPin,LOW); // Set clockPin LOW
shiftOut(dataPin, clockPin, LSBFIRST, byteData); // send 1byte
digitalWrite(dataPin,LOW); // for Ack
digitalWrite(clockPin,HIGH); // 9th pulse
digitalWrite(clockPin,LOW);
}