[Arduino] HT1621 LCD Segment 아두이노와 연결하기
[Arduino] HT1621 LCD Segment 아두이노와 연결하기
네트워크로 온습도를 실시간으로 기록하는 온습도계를 만들일이 있어서 아두이노를 가지고 끄적끄적 하는데 LCD 패널도 있으면 좋겠다 싶어서 한진데이터에서 나온 TF4-8B LCD 세그먼트를 싼맛에 하나 사서 박았다... 문제는 일반 LCD패널도 아니고 7 세그먼트형식? 아무튼 이놈을 돌리는 방법을 모른다는 것이었다...
그래서 구글신에게 부탁드렸더니 답변들이 죄다 데이터시트 보고 알아서 만들라는 말들뿐... 나는 전자과 근처에는 얼씬도 못해본 컴퓨터전공인데... 데이터시트를 보고 만들기는 커녕.. 무슨뜻인지도 잘 모르는데...
아무튼 2시간동안의 계속되는 헤딩끝에 결국 구글신이 중국사이트 하나를 알려주심!!
(http://blog.sina.com.cn/s/blog_569a20780101hqoa.html)
여기가니까 내가 산 TF4-8B 모듈은 아니지만 HT1621칩을 쓰는 다른 LCD 세그먼트 구동방법이 올라와있어서 얼릉 복사해서 돌려봤는데 LCD가 안들어온다..ㅠㅠ 그래서 뭐가문제지 하고 소스를 뜯고 별짓을 다했는데 결국 아두이노에 들어가는 볼트가 3볼트 미만이라서 LCD가 정신못차리고 깨어나지 못하는것이었다...
정말 만날 어플리케이션만 개발하다가 임베디드관련된걸 하게되니 뭐가뭔지 모르겠음ㅠㅠ
아무튼 나처럼 HT1621칩을 쓰는 LCD 세그먼트를 아두이노와 연결못하는 사람들을 위해 위 소스를 살짝 고친 소스를 공개
// LCD 관련 변수
int CS =2 ;
int WR = 3;
int DATA =4 ;
int led = 5;
#define ComMode 0x52
#define RCosc 0x30
#define LCD_on 0x06
#define LCD_off 0x04
#define Sys_en 0x02
#define CTRl_cmd 0x80
#define Data_cmd 0xa0
#define WDTDIS 0X0A
#define SYSDIS 0X00
int cnt = 0;
void setup() {
Serial.begin(9600);
while (!Serial) {;}
pinMode(led, OUTPUT);
pinMode(CS,OUTPUT);
pinMode(WR,OUTPUT);
pinMode(DATA,OUTPUT);
Init_1621() ;
delay(2000);
}
void loop()
{
displays(0, 1);
displays(2, 2);
displays(4, 3);
displays(6, 4);
delay(3000);
}
void Init_1621(void)
{
SendCmd_1621(Sys_en);
SendCmd_1621(RCosc);
SendCmd_1621(ComMode);
SendCmd_1621(LCD_on);
}
void SendCmd_1621(uint8_t command)
{
digitalWrite(CS,LOW);
SendBit_1621(0x80,4);
SendBit_1621(command,8);
digitalWrite(CS,HIGH);
}
void SendBit_1621(uint8_t sdata,uint8_t cnt)
{
uint8_t i;
for(i=0;i<cnt;i++) {
digitalWrite(WR,LOW);
delay(1);
if(sdata&0x80) digitalWrite(DATA,HIGH);
else digitalWrite(DATA,LOW);
delay(1);
digitalWrite(WR,HIGH);
delay(1);
sdata<<=1;
}
delay(1);
}
void Write_1621(uint8_t addr,uint8_t sdata)
{
addr<<=2;
digitalWrite(CS,LOW);
SendBit_1621(0xa0,3);
SendBit_1621(addr,6);
SendBit_1621(sdata,8);
digitalWrite(CS,HIGH);
}
void displays(int location, int displayednum)
{
if(displayednum == 0)
{
Write_1621(location,0b10111110);
}
else if(displayednum == 1)
{
Write_1621(location,0b00000110);
}
else if(displayednum == 2)
{
Write_1621(location,0b01111100);
}
else if(displayednum == 3)
{
Write_1621(location,0b01011110);
}
else if(displayednum == 4)
{
Write_1621(location,0b11000110);
}
else if(displayednum == 5)
{
Write_1621(location,0b11011010);
}
else if(displayednum == 6)
{
Write_1621(location,0b11111010);
}
else if(displayednum == 7)
{
Write_1621(location,0b00001110);
}
else if(displayednum == 8)
{
Write_1621(location,0b11111110);
}
else if(displayednum == 9)
{
Write_1621(location,0b11011110);
}
else if(displayednum == -10)
{
Write_1621(location,0b10111111);
}
else if(displayednum == 11)
{
Write_1621(location,0b10111000);
}
else if(displayednum == 12)
{
Write_1621(location,0b11100110);
}
else if(displayednum == 13)
{
Write_1621(location,0b10111111);
}
else if(displayednum == -1)
{
Write_1621(location,0b00000111);
}
else if(displayednum == -2)
{
Write_1621(location,0b01111101);
}
else if(displayednum == -3)
{
Write_1621(location,0b01011111);
}
else if(displayednum == -4)
{
Write_1621(location,0b11000111);
}
else if(displayednum == -5)
{
Write_1621(location,0b11011011);
}
else if(displayednum == -6)
{
Write_1621(location,0b11111011);
}
else if(displayednum == -7)
{
Write_1621(location,0b00001111);
}
else if(displayednum == -8)
{
Write_1621(location,0b11111111);
}
else if(displayednum == -9)
{
Write_1621(location,0b11011111);
}
}
원 개발자가 만든 소스에 보면 Write_1621()라는 함수가 있는데 이녀석이 바로 숫자를 출력해주는 역할을 한다.
매개변수의 맨 앞쪽은 자릿수, 두번째 0b0000...는 숫자를 구성하는 각각의 비트를 의미한다.(아래그림 참고)
예를 들어 비트가 0b11111010 으로 입력되어 있다면 (0)번째와 (2)번째 부분만 0이고 나머지는 모두 1이니 6 형태의 디지털 숫자가 출력된다.
소스에 보면 displays()라는 함수를 하나 새로 만들었는데 Write_1621함수에서 숫자를 어떻게 하면 편하게 출력할수 있을까 하다가 만든 함수로 앞의 매개변수에 자리수, 뒤에 출력하고자 하는 숫자를 쓰면 된다. 단 자릿수는 소수점 표시때문인지는 몰라도 내가 사용한 LCD는 자리수를 0, 2, 4, 6과 같이 2의 배수로 써야 제대로 동작했다. 음수도 구별하는데 이건 그냥 소수점 표기때문에 넣은것으로 없어도 무방하다.
예를들어 사진과 같이 4자리수 LCD에 1234라고 쓰고싶다면
Write_1621(0, 1);
Write_1621(2, 2);
Write_1621(4, 3);
Write_1621(6, 4);
이렇게 쓰고 실행하면 성공!!