FND 소스 분석(2)

김지성·2022년 7월 25일
1

Embedded

목록 보기
13/19
post-thumbnail

저번 포스팅에서는 FND를 작동시키는데 초점을 뒀다면 이번 포스팅에선 FND가 어떤 방식으로 작동하는지를 볼것이다.
(FND_controller.c위주로 볼 것이다.)

1.1 오실로스코프를 이용해여 0xF8 펄스 보기

void send(uint8_t X){

  for (int i = 8; i >= 1; i--)				//DIO를 8bit로 나눈다음 펄스 전송	
  {
	if (X & 0x80)
	{
	  HAL_GPIO_WritePin(FND_DIO_GPIO_Port, FND_DIO_Pin, HIGH);
	}
	else
	{
		HAL_GPIO_WritePin(FND_DIO_GPIO_Port, FND_DIO_Pin, LOW);
	}
	X <<= 1;
    
    
	HAL_GPIO_WritePin(FND_SCLK_GPIO_Port, FND_SCLK_Pin, LOW);		//CLK만들기
	HAL_GPIO_WritePin(FND_SCLK_GPIO_Port, FND_SCLK_Pin, HIGH);
  }
}
while(1)
{
	send(0xF8);
}

0xF8를 비트로 나타내면 "1111 1000"이고, 그 펄스를 오실로스코프로 확인해봤다.

  • 노란색은 SCLK(클럭)이고 파랑색은 DIO(데이터)이다.
  • SCLK는 평상시에 HIGH를 유지하다가 LOW에서 HIGH로 올라갈 때 데이터가 전송되는걸 볼 수 있다.

**SPI 통신은 클럭이 서로 일치하지 않아도 어느정도 신호가 간다. 클럭이 서로 일치하지 않은 이유는 클럭을 소프트웨어적으로 보냈기 때문이다. 하드웨어로 보낸다면 일치한다.

1.2 FND 첫 번째 칸에 7출력하고 오실로스코프로 펄스보기

while(1)
{
	  send(0xF8);			
	  send(0b0001);
	  HAL_GPIO_WritePin(FND_RCLK_GPIO_Port, FND_RCLK_Pin, LOW);
	  HAL_GPIO_WritePin(FND_RCLK_GPIO_Port, FND_RCLK_Pin, HIGH);
	  HAL_Delay(1000);
}

  • 노란색은 SCLK(클럭)이고, 파란색은 DIO(데이터)이다.
  • 여기서 중요한건 while문에서 send를 두 번 작성했기 때문에 SCLK이 " 8bit X 2 = 16bit" 된다는 점이다. 첫 번째 8bit는 DIO가 전송될 때 사용되고, 두 번째 8bit는 FND 자릿수를 결정하는데 사용된다.
  • DIO는 8bit씩 쪼개서 보내는데, 첫 번째 DIO에서는 0b11111000를 보내고 두 번째 DIO는 0b00000001를 보내는걸 확인할 수 있다.
    (그림에서는 FND 세 번째 자리를 출력하고 있다. 다시 오실로스코프를 찍어 수정하자)

RCLK이 LOW에 있다가 HIGH로 올라가는데 무슨 의미를 갖는지는 모르겠다. 아무튼 SCLK, RCLK, DIO의 펄스가 있어서 MCU에서 FND로 데이터가 전송되는 것이다.

1.3 FND 8개핀 제어해보기

void send_port(uint8_t X, uint8_t port)
{
  send(X);				//출력하고자 하는 글자(숫자)
  send(port);			//출력 자리
  HAL_GPIO_WritePin(FND_RCLK_GPIO_Port, FND_RCLK_Pin, LOW);
  HAL_GPIO_WritePin(FND_RCLK_GPIO_Port, FND_RCLK_Pin, HIGH);
}
while(1)
{
	  send_port(0b11111110, 0b0001);
	  HAL_Delay(1000);

	  send_port(0b11111101, 0b0001);
	  HAL_Delay(1000);

	  send_port(0b11111011, 0b0001);
	  HAL_Delay(1000);

	  send_port(0b11110111, 0b0001);
	  HAL_Delay(1000);

	  send_port(0b11101111, 0b0001);
	  HAL_Delay(1000);

	  send_port(0b11011111, 0b0001);
	  HAL_Delay(1000);

	  send_port(0b10111111, 0b0001);
	  HAL_Delay(1000);

	  send_port(0b01111111, 0b0001);			// .을 나타내는 방법
	  HAL_Delay(1000);
 }

FND가 풀업 저항으로 연결되있기 때문에 ON이 될려면 0이 되야한다.

ex) 0xF8은 왜 7일까? ---> 0b11111000이고, A/B/C가 켜지게 될 것이다.

1.3 digit4_show 분석해보기

void digit4_show(int n, int replay, uint8_t showZero)
{
  int n1, n2, n3, n4;
  n1 = (int)  n % 10;
  n2 = (int) (n % 100) / 10;
  n3 = (int) (n % 1000) / 100;
  n4 = (int) (n % 10000) / 1000;

 for(int i = 0; i<=replay; i++){
	 send_port(_LED_0F[n1], 0b0001);					//n이 9보다 작으면 첫번째 자리 on
    if(showZero | n>9)send_port(_LED_0F[n2], 0b0010);	//n이 9보다 크면 두번째 자리 on
    if(showZero | n>99)send_port(_LED_0F[n3], 0b0100);	//n이 99보다 크면 세번째 자리 on
    if(showZero | n>999)send_port(_LED_0F[n4], 0b1000);	//n이 999보다 크면 네번째 자리 on
 }
}
//만약 789가 켜진다면 알아서 자릿수에 맞춰 들어갈 것이다. 어디에 출력시킬건지 자릿수만 맞춰주면 됨
void digit4_replay(int n, int replay)
{
	digit4_show(n,replay,false);		//showzero = false
}

void digit4(int n)
{
	digit4_show(n,0,false);				//showzero = false
}

void digit4showZero_replay(int n, int replay)
{
	digit4_show(n, replay, true);		//showzero = true
}

void digit4showZero(int n)
{
	digit4_show(n, 0, true);			//showzero = true
}
while(1)
{
	for(int i = 0; i<=9999; i++)
	{
	digit4_replay(i, 50);				//애초에 digit4_replay는 digit4_show를 포함하고
    									  있고, digit4_show는 false로 정의하고 있다. 
	}
}

1) int n = int i이므로 i가 789라면 n도 789이다.

n1 = 789 % 10 = 9
n2 = (789 % 100) / 10 = 8
n3 = (789 % 1000) / 100 = 7
n4 = (789 % 10000) / 1000 = 0

2) showzero가 0 or 1일 경우

showzero가 true(1)이라면 0이여도 FND에 불빛이 들어올 것이고,
showzero가 false(0)이라면 FND에 불빛이 들어오지 않을 것이다.

1.4 온도 표시 잠깐 맛보기

void digit4_temper(int n, int replay, uint8_t showZero)
{
  int n1, n2, n3;
  n1 = (int)  n % 10;
  n2 = (int) ((n % 100)-n1)/10;
  n3 = (int) ((n % 1000) - n2 - n1) / 100;

 for(int i = 0; i<=replay; i++)
 {
	send_port(_LED_0F[n1], 0b0001);
    if(n>9)send_port(_LED_0F[n2] & 0x7F, 0b0010);
    if(n>99)send_port(_LED_0F[n3], 0b0100);
 }
}
void digit_temper(int n, int replay)
{
	digit4_temper(n, replay, true);
}
while(1)
{
	  for(int i=0; i<=999; i++)
	  {
		  digit4_temper(i, 50);
	  }
}
profile
JUST DO IT

0개의 댓글