프로젝트를 하다보니 핀의 사용은 한정적인데 FND의 자릿수는 늘어났다.
단순 무식히 계산하면 8(FND 표현) + n(FND 개수)라 digital pin이 부족하게 된다!
프로그래밍이 간단하지만 최소 8개(단일 FND), 9개(멀티 FND)의 digital pin을 사용해야한다.
이를 해결하기 위해 쉬프트 레지스터를 이용하여 데이터 선을 줄여보고자 하였다.
이 경우 데이터 선을 1(Serial Data) + 1(Serial Clock) + 1(Latch Clock), 즉 3개만 사용하여도 된다.

0b00111011인 경우 아래와 같이 입력된다.| MSB 입력 | LSB 입력 |
|---|---|
| [abcdefgh]11011100 | [abcdefgh]00111011 |


핀 배열이 이상하다. 헷갈리지 않게 주의!
이 프로젝트에서는 FND를 Anode 타입으로 하였다. 자신의 FND 타입에 맞게 하자.


즉, 데이터가 00100000 10101000인 경우, MSB 1byte는 데이터, LSB 1byte는 데이터 위치를 나타낸다.
이 프로젝트에서는 MSB 1byte에서 LSB 7bit인 0100000만 사용하고, 이는 6을 나타낸다. Common Anode를 사용하였기 때문.
LSB 1byte에서 1, 3, 5번째 FND만 출력을 하도록 하였다.
가장 기초적인 동작은 writeFNDBit 함수를 사용한다.
이를 이용하여 1byte 데이터를 쓰는 writeFndByte 함수를 정의하고, 이를 이용하여 writeFND 함수를 정의한다.
void write8digitFND(const unsigned char datas[]) {
unsigned int data = 0;
for (int i = 0; i < 8; i++) {
data = (unsigned int)datas[i] << 8; // display data
data |= 1 << (7 - i); // display position
writeFND(data);
}
}
void writeFND(unsigned int data) {
writeFNDByte( data & 0xff ); // position
writeFNDByte( (data >> 8 ) & 0xff ); // data
// 데이터 출력
digitalWrite(LCH, HIGH);
delay(2); // 최대 delay는 2ms ( 1 / (60*n) )
digitalWrite(LCH, LOW);
}
void writeFNDByte(unsigned char data) {
for (int i = 0; i < BIT_8; i++) {
writeFNDBit(data & 0x01);
data >>= 1;
}
}
void writeFNDBit(unsigned char bit) {
digitalWrite(SER, bit % 2);
digitalWrite(CLK, HIGH);
delayMicroseconds(1);
digitalWrite(CLK, LOW);
}
Common Anode 타입을 사용하여서 FND 출력이 조금 약하다. Common Cathod를 쓰면 다를지도?
MCU에서 나가는 데이터 선은 줄었지만 여전히 회로에서 사용하는 데이터 선은 많다. 이 부분은 PCB로 대체하면 선을 줄일 수 있을 것으로 예상한다.
쉬프트 레지스터에서 다음 쉬프트 레지스터로 넘기는 방법을 배웠다.
처음에는 SR1의 QH' 출력 데이터가 SR2의 SER에 들어가서 SR2의 QA 출력 데이터로 되는 것으로 생각하였다. 이에 따라 SR이 2개 있다면 15개의 bit만, SR이 3개 있다면 22개의 bit만 출력할 수 있다고 생각하였다. 즉 8+7*(n-1)개의 bit만 출력할 수 있다 가정하였다.
하지만 LED로 테스트를 해보니 SR1의 QH' 출력 데이터와 SR2의 QA 출력 데이터는 다른 것으로 판단되었다. 즉 8*n개의 bit를 전부 표현할 수 있다는 것을 알아내었다.
데이터 시트를 보는데도 헷갈리는 부분이 발생하였다. 이때 실제로 출력을 해보며 값이 어떻게 출력되는지 확인을 해보는 것이 중요하다는 것을 깨달았다.
+ 깔끔하게 완성!
