Flexible Numeric Display의 약자로, LED를 사용하여 숫자 모양을 하나로 만들어 놓은 것이다.
7개의 LED를 아래와 같이 배치하고 그 몇개를 선택하여 조광함으로써 0 ~ 9까지를 표시할 수 있도록 한다.


모듈(쪽보드) = 메인 칩(드라이버)+ 필요한 최소한의 회로
FND 모듈
: TM74HC595 칩 2개(lcd 드라이버) + 7-segment
7-segment에 gpio를 하나씩 연결해서 제어할 수 있지만 gpio가 8개나 필요하다.
그래서 메인칩을 이용해서 7-segment를 제어하는 것이다.


원래는 SPI로 연결할 것이지만 일단 GPIO로 구현먼저 해볼 예정이다


SCLK : 기본클럭
DIO : 기본클럭을 기준으로 원하는 곳에 클럭을 보내면 1 0 0 0 1 이런식으로 데이터를 보냄
STM32에서 SPI 통신을 지원해주지만 일단 이번에는 GPIO를 이용해서 구현할 예정이다.


// 샘플코드
void TM74HC595Display::send(unsigned char X)
{
for (int i = 8; i >= 1; i--)
{
if (X & 0x80)
{
digitalWrite(_DIO, HIGH);
}
else
{
digitalWrite(_DIO, LOW);
}
X <<= 1;
digitalWrite(_SCLK, LOW);
digitalWrite(_SCLK, HIGH);
}
}
void send(uint8_t X){
for (int i = 8; i >= 1; i--)
{
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);
HAL_GPIO_WritePin(FND_SCLK_GPIO_Port, FND_SCLK_Pin, HIGH);
}
}
보내고 싶은 데이터 X (= 0x52 = 0101 0010)
X & 0x80(1000 0000)
: X의 첫번째 비트부터 and 연산해서 0이면 DIO = LOW, 1이면 DIO = HIGH
X를 쉬프트연산해서 2,3,4,...번째 비트 전부 비교한다.
SCLK는 HIGH 상태였다가, DIO로 데이터를 한비트씩 보낼때마다 SCLK가 LOW로 갔다가 HIGH로 돌아온다.(클럭을 만드는 것)
/*
* fnd_controller.c
*
* Created on: Mar 2, 2025
* Author: lnaur
*/
#include "fnd_controller.h"
uint8_t _LED_0F[29];
void fnd_init(){
_LED_0F[0] = 0xC0; //0
_LED_0F[1] = 0xF9; //1
_LED_0F[2] = 0xA4; //2
_LED_0F[3] = 0xB0; //3
_LED_0F[4] = 0x99; //4
_LED_0F[5] = 0x92; //5
_LED_0F[6] = 0x82; //6
_LED_0F[7] = 0xF8; //7
_LED_0F[8] = 0x80; //8
_LED_0F[9] = 0x90; //9
_LED_0F[10] = 0x88; //A
_LED_0F[11] = 0x83; //b
_LED_0F[12] = 0xC6; //C
_LED_0F[13] = 0xA1; //d
_LED_0F[14] = 0x86; //E
_LED_0F[15] = 0x8E; //F
_LED_0F[16] = 0xC2; //G
_LED_0F[17] = 0x89; //H
_LED_0F[18] = 0xF9; //I
_LED_0F[19] = 0xF1; //J
_LED_0F[20] = 0xC3; //L
_LED_0F[21] = 0xA9; //n
_LED_0F[22] = 0xC0; //O
_LED_0F[23] = 0x8C; //P
_LED_0F[24] = 0x98; //q
_LED_0F[25] = 0x92; //S
_LED_0F[26] = 0xC1; //U
_LED_0F[27] = 0x91; //Y
_LED_0F[28] = 0xFE; //hight -
}
void send(uint8_t X){
for (int i = 8; i >= 1; i--)
{
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);
HAL_GPIO_WritePin(FND_SCLK_GPIO_Port, FND_SCLK_Pin, HIGH);
}
}
void send2(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);
}
void digit4(int n, int replay, uint8_t showZero)
{
int n1, n2, n3, n4;
n1 = (int) n % 10;
n2 = (int) ((n % 100)-n1)/10;
n3 = (int) ((n % 1000) - n2 - n1) / 100;
n4 = (int) ((n % 10000) - n3 - n2 - n1) / 1000;
for(int i = 0; i<=replay; i++){
send2(_LED_0F[n1], 0b0001);
if(showZero | n>9)send2(_LED_0F[n2], 0b0010);
if(showZero | n>99)send2(_LED_0F[n3], 0b0100);
if(showZero | n>999)send2(_LED_0F[n4], 0b1000);
}
}
void digit4_replay(int n, int replay)
{
digit4(n,replay,false);
}
void digit4_0(int n)
{
digit4(n,0,false);
}
void digit4showZero_replay(int n, int replay)
{
digit4(n, replay, true);
}
void digit4showZero_0(int n)
{
digit4(n, 0, true);
}
void digit2_replay(int n, int port, int replay)
{
int n1, n2;
n1 = (int) n % 10;
n2 = (int) ((n % 100)-n1)/10;
for(int i = 0; i<=replay; i++){
send2(_LED_0F[n1], port);
send2(_LED_0F[n2], port<<1);
}
}
void digit2_0(int n, int port)
{
digit2_replay(n, port, 0);
}
/*
* fnd_controller.h
*
* Created on: Mar 2, 2025
* Author: lnaur
*/
#ifndef SRC_FND_CONTROLLER_H_
#define SRC_FND_CONTROLLER_H_
#include "main.h"
#define HIGH 1
#define LOW 0
#define true 1
#define false 0
void fnd_init();
void send(uint8_t X);
void send2(uint8_t X, uint8_t port);
void digit4(int n, int replay, uint8_t showZero);
void digit4_replay(int n, int replay);
void digit4_0(int n);
void digit4showZero_replay(int n, int replay);
void digit4showZero_0(int n);
void digit2_replay(int n, int port, int replay);
void digit2_0(int n, int port);
#endif /* SRC_FND_CONTROLLER_H_ */
/* USER CODE BEGIN Includes */
#include "fnd_controller.h"
/* USER CODE END Includes */
-> while(1) 문이여서 계속 돌아감
while (1)
{
fnd_init();
for (int i = 0; i <= 99; i++) {
digit2_replay(i, 0b0001, 50);
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
for (int i = 0; i <= 9999; i++) {
digit4showZero_replay(i, 50);
}
fnd_init();
send2(0xC0,0b1000);
send2(0x80,0b0100);
send2(0xC0,0b0010);
send2(0xF8,0b0001);