«   2025/06   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
Archives
관리 메뉴

printf("ho_tari\n");

3일차 본문

2025.03.06

 

오늘의 학습 목표

1. 1 button 처리

2. 생태천이 (FSM)

3. switch~case를 함수 포인터로

4. FND 제어

5. Timer INTERRUPT

 

processor : CPU

process : 현재 돌고 있는 program을 의미

 

1 BUTTON LED 제어

<main.c> (switch~case 사용)

#define F_CPU 16000000UL // 16MHZ Unsigned Long
#include <avr/io.h>
#include <util/delay.h> // _delay_ms, _delay_us 헤더파일

#include "button.h"

extern int led_main(void); // 함수가 다른 파일에 들어있으면 extern으로 선언
extern void init_button(void); // 함수가 다른 파일에 들어있으면 extern으로 선언
extern int get_button(int button_num, int button_pin); // 함수가 다른 파일에 들어있으면 extern으로 선언
extern void led_all_on(void);
extern void led_all_off(void);
extern void shift_left_led_on(void);
extern void shift_right_led_on(void);
extern void shift_left_keep_ledon(void);
extern void shift_right_keep_ledon(void);
extern void flower_on(void);
extern void flower_off(void);

// none o/s 방식 또는 loop monitor 방식
int main(void)
{
	// led_main();
	int button0_state = 0; // 초기 상태를 0으로 출발
	// int button1_state = 0;
	// int button2_state = 0;
	// int button3_state = 0;
	
	void (*fp[]) (void) =
	{
		led_all_off,
		led_all_on,
		shift_left_led_on,
		shift_right_led_on,
		shift_left_keep_ledon,
		shift_right_keep_ledon,
		flower_on,
		flower_off
	};
	
	init_button();
		   //76543210
	DDRA = 0b11111111; // PORTA를 출력 모드(1)로 설정
	      // ---- 상위 nibble : 상위 4bits
		  //     ---- 하위 nibble : 하위 4bits
					   // DDR(Data Direction Register) : 방향 설정
					   // 1 : 출력, 0 : 입력을 의미
					   // 0b : 2진수
					   // 0x : hex
					   // DDRA = 0Xff;
	// int count = 0;
#if 1 // switch~case 1 BUTTON
	while(1)
	{
		/*
		if(get_button(BUTTON0, BUTTON0PIN))
		{
			button0_state = !button0_state;
			count += 1;
			switch(count)
			{
				case 1: led_all_on(); break;
				case 2: led_all_off(); break;
				case 3: shift_left_led_on(); break;
				case 4: shift_right_led_on(); break;
				case 5: shift_left_keep_ledon(); break;
				case 6: shift_right_keep_ledon(); break;
				case 7: flower_on(); break;
				case 8: flower_off(); count = 0; break;
			}
		}
		*/
		if(get_button(BUTTON0, BUTTON0PIN))
		{
			button0_state++;
			button0_state %= 8;
		}
		switch(button0_state)
		{
			case 0: led_all_off(); break;
			case 1: led_all_on(); break;
			case 2: shift_left_led_on(); break;
			case 3: shift_right_led_on(); break;
			case 4: shift_left_keep_ledon(); break;
			case 5: shift_right_keep_ledon(); break;
			case 6: flower_on(); break;
			case 7: flower_off(); break;
		}
	}
#endif

#if 0 // 함수 포인터 배열 1 BUTTON
#endif

#if 0 // org 4 BUTTON
#endif

 

<실행 결과>

https://youtube.com/shorts/qJqiCgZt7EM

 

<main.c> (함수 포인터 배열 사용)

#define F_CPU 16000000UL // 16MHZ Unsigned Long
#include <avr/io.h>
#include <util/delay.h> // _delay_ms, _delay_us 헤더파일

#include "button.h"

extern int led_main(void); // 함수가 다른 파일에 들어있으면 extern으로 선언
extern void init_button(void); // 함수가 다른 파일에 들어있으면 extern으로 선언
extern int get_button(int button_num, int button_pin); // 함수가 다른 파일에 들어있으면 extern으로 선언
extern void led_all_on(void);
extern void led_all_off(void);
extern void shift_left_led_on(void);
extern void shift_right_led_on(void);
extern void shift_left_keep_ledon(void);
extern void shift_right_keep_ledon(void);
extern void flower_on(void);
extern void flower_off(void);

// none o/s 방식 또는 loop monitor 방식
int main(void)
{
	// led_main();
	int button0_state = 0; // 초기 상태를 0으로 출발
	// int button1_state = 0;
	// int button2_state = 0;
	// int button3_state = 0;
	
	void (*fp[]) (void) =
	{
		led_all_off,
		led_all_on,
		shift_left_led_on,
		shift_right_led_on,
		shift_left_keep_ledon,
		shift_right_keep_ledon,
		flower_on,
		flower_off
	};
	
	init_button();
		   //76543210
	DDRA = 0b11111111; // PORTA를 출력 모드(1)로 설정
	      // ---- 상위 nibble : 상위 4bits
		  //     ---- 하위 nibble : 하위 4bits
					   // DDR(Data Direction Register) : 방향 설정
					   // 1 : 출력, 0 : 입력을 의미
					   // 0b : 2진수
					   // 0x : hex
					   // DDRA = 0Xff;
	// int count = 0;

#if 0 // switch~case 1 BUTTON
#endif

#if 1 // 함수 포인터 배열 1 BUTTON
	while(1)
	{
		if(get_button(BUTTON0, BUTTON0PIN))
		{
			button0_state++;
			button0_state %= 8;
		}
		fp[button0_state] ();
	}
#endif

#if 0 // org 4 BUTTON
#endif

 

<실행 결과>

https://youtube.com/shorts/ooTQrmFtxFM

 

FND (Flexible Number Display) (7 세그먼트 표시장치)

- 8개의 LED를 배치하여 숫자나 문자를 나타낼 수 있도록 만들어진 표시장치

- 각 LED를 흔히 세그먼트라고 일컬음

- 각 LED는 개별적으로 제어됨 (8개의 데이터 핀 필요)

- 자릿수에 따라 다양한 7 세그먼트 표시장치 존재

- 자릿수에 따라 제어 방식에 차이가 있음

 

공통핀에 VCC/GND를 가하고 제어핀에 GND/VCC를 가하면 해당 세그먼트가 켜지는 공통 양극/음극 방식으로 나눔

 

- 핀 번호와 세그먼트 이름 사이에 연관성 없음

 

FND 극성

1. Common Anode

2. Common Cathode

 

부품 번호 : CL5642AH-33 → Common Cathode

 

<fnd.h>

/*
 * fnd.h
 *
 * Created: 2025-03-06 오후 12:23:18
 *  Author: microsoft
 */ 


#ifndef FND_H_
#define FND_H_

#define F_CPU 16000000UL // 16MHZ Unsigned Long
#include <avr/io.h>
#include <util/delay.h> // _delay_ms, _delay_us 헤더파일

#define FND_DATA_PORT PORTC
#define FND_DATA_DDR DDRC

#define FND_DIGIT_PORT PORTB
#define FND_DIGIT_DDR DDRB
#define FND_DIGIT_D1 4
#define FND_DIGIT_D2 5
#define FND_DIGIT_D3 6
#define FND_DIGIT_D4 7

#endif /* FND_H_ */

 

<fnd.c>

/*
 * fnd.c
 *
 * Created: 2025-03-06 오후 12:22:24
 *  Author: microsoft
 */ 

#include "fnd.h"

void init_fnd(void);
uint32_t ms_count = 0; // ms를 재는 count 변수 unsigned int --> uint32_t
uint32_t sec_count = 0; // 초를 재는 count 변수 unsigned int --> uint32_t
int fnd_main(void);
void fnd_display(void);

int fnd_main(void)
{
	init_fnd();
	
	while(1)
	{
		fnd_display();
		_delay_ms(1);
		ms_count++;
		if(ms_count >= 1000) // 1000ms --> 1s
		{
			ms_count = 0;
			sec_count++;
		}
	}
	
	return 0;
}

void init_fnd(void)
{
	FND_DATA_DDR = 0xff; // 출력 모드로 설정
	// FND_DIGIT_DDR |= 0xf0; // 자릿수 선택 7654
	FND_DIGIT_DDR |= 1 << FND_DIGIT_D1 | 1 << FND_DIGIT_D2 | 1 << FND_DIGIT_D3 | 1 << FND_DIGIT_D4;
	
	// fnd를 all off
#if 1 // common cathode 방식
	FND_DATA_PORT = 0x00; // fnd를 all off
#else // common anode 방식
	FND_DATA_PORT = ~0x00; // fnd를 all off 0xff;
#endif
}

void fnd_display(void)
{
#if 1 // common cathode 방식
						  //  0      1      2      3      4      5      6      7      8      9      .
	uint8_t fnd_font[] = {~0xc0, ~0xf9, ~0xa4, ~0xb0, ~0x99, ~0x92, ~0x82, ~0xd8, ~0x80, ~0x90, ~0x7f};
#else // common anode 방식
						 //  0     1     2     3     4     5     6     7     8     9     .
	uint8_t fnd_font[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xd8, 0x80, 0x90, 0x7f};
#endif

	static int digit_select = 0; // static을 쓰면 전역 변수처럼 함수가 빠져 나갔다가 다시 들어오더라도 값을 유지
	
	switch(digit_select)
	{
		case 0: 
#if 1 // common cathode
			FND_DIGIT_PORT = ~(1 << FND_DIGIT_D4); // 01111111 FND_FIGIT_PORT = ~0x80
#else // common anode
			FND_DIGIT_PORT = 1 << FND_DIGIT_D4; // 10000000 FND_FIGIT_PORT = 0x80
#endif
			FND_DATA_PORT = fnd_font[sec_count % 10]; // 0~9초
			break;
		case 1: 
#if 1 // common cathode
			FND_DIGIT_PORT = ~(1 << FND_DIGIT_D3); // 01111111 FND_FIGIT_PORT = ~0x40
#else // common anode
			FND_DIGIT_PORT = 1 << FND_DIGIT_D3; // 10000000 FND_FIGIT_PORT = 0x40
#endif
			FND_DATA_PORT = fnd_font[sec_count / 10 % 6]; // 10단위초
			break;
		case 2: 
#if 1 // common cathode
			FND_DIGIT_PORT = ~(1 << FND_DIGIT_D2); // 01111111 FND_FIGIT_PORT = ~0x20
#else // common anode
			FND_DIGIT_PORT = 1 << FND_DIGIT_D2; // 10000000 FND_FIGIT_PORT = 0x20
#endif
			FND_DATA_PORT = fnd_font[sec_count / 60 % 10]; // 1단위 분
			break;
		case 3: 
#if 1 // common cathode
			FND_DIGIT_PORT = ~(1 << FND_DIGIT_D1); // 01111111 FND_FIGIT_PORT = ~0x10
#else // common anode
			FND_DIGIT_PORT = 1 << FND_DIGIT_D1; // 10000000 FND_FIGIT_PORT = 0x10
#endif
			FND_DATA_PORT = fnd_font[sec_count / 600 % 6]; // 10단위 분
			break;
	}
	digit_select++;
	digit_select %= 4; // 다음 표시할 자릿수 선택
}

 

<main.c>

/*
 * 01.LED_CONTROL.c
 *
 * Created: 2025-03-04 오후 4:25:29
 * Author : microsoft
 */ 

#define F_CPU 16000000UL // 16MHZ Unsigned Long
#include <avr/io.h>
#include <util/delay.h> // _delay_ms, _delay_us 헤더파일

#include "button.h"

extern int led_main(void); // 함수가 다른 파일에 들어있으면 extern으로 선언
extern void init_button(void); // 함수가 다른 파일에 들어있으면 extern으로 선언
extern int get_button(int button_num, int button_pin); // 함수가 다른 파일에 들어있으면 extern으로 선언
extern void led_all_on(void);
extern void led_all_off(void);
extern void shift_left_led_on(void);
extern void shift_right_led_on(void);
extern void shift_left_keep_ledon(void);
extern void shift_right_keep_ledon(void);
extern void flower_on(void);
extern void flower_off(void);

// none o/s 방식 또는 loop monitor 방식
int main(void)
{
	fnd_main();
	// led_main();
	int button0_state = 0; // 초기 상태를 0으로 출발
	// int button1_state = 0;
	// int button2_state = 0;
	// int button3_state = 0;
	
	void (*fp[]) (void) =
	{
		led_all_off,
		led_all_on,
		shift_left_led_on,
		shift_right_led_on,
		shift_left_keep_ledon,
		shift_right_keep_ledon,
		flower_on,
		flower_off
	};
	
	// init_button();
		   //76543210
	DDRA = 0b11111111; // PORTA를 출력 모드(1)로 설정
	      // ---- 상위 nibble : 상위 4bits
		  //     ---- 하위 nibble : 하위 4bits
					   // DDR(Data Direction Register) : 방향 설정
					   // 1 : 출력, 0 : 입력을 의미
					   // 0b : 2진수
					   // 0x : hex
					   // DDRA = 0Xff;
	// int count = 0;
#if 0 // switch~case 1 BUTTON
	while(1)
	{
		/*
		if(get_button(BUTTON0, BUTTON0PIN))
		{
			button0_state = !button0_state;
			count += 1;
			switch(count)
			{
				case 1: led_all_on(); break;
				case 2: led_all_off(); break;
				case 3: shift_left_led_on(); break;
				case 4: shift_right_led_on(); break;
				case 5: shift_left_keep_ledon(); break;
				case 6: shift_right_keep_ledon(); break;
				case 7: flower_on(); break;
				case 8: flower_off(); count = 0; break;
			}
		}
		*/
		if(get_button(BUTTON0, BUTTON0PIN))
		{
			button0_state++;
			button0_state %= 8;
		}
		switch(button0_state)
		{
			case 0: led_all_off(); break;
			case 1: led_all_on(); break;
			case 2: shift_left_led_on(); break;
			case 3: shift_right_led_on(); break;
			case 4: shift_left_keep_ledon(); break;
			case 5: shift_right_keep_ledon(); break;
			case 6: flower_on(); break;
			case 7: flower_off(); break;
		}
	}
#endif

#if 1 // 함수 포인터 배열 1 BUTTON
	while(1)
	{
		if(get_button(BUTTON0, BUTTON0PIN))
		{
			button0_state++;
			button0_state %= 8;
		}
		fp[button0_state] ();
	}
#endif

#if 0 // org 4 BUTTON
	while (1)   // for(;;)
	{
		// 1 button 처리 (toggle)
		// button0를 1번 누르면 led_all_on
		//			 1번 다시 누르면 led_all_off
		if (get_button(BUTTON0, BUTTON0PIN))
		{
			button0_state = !button0_state; // 반전 0 <--> 1
			if(button0_state)
			{
				led_all_on();
			}
			else
			{
				led_all_off();
			}
		}
		if (get_button(BUTTON1, BUTTON1PIN))
		{
			button1_state = !button1_state; // 반전 0 <--> 1
			if(button1_state)
			{
				shift_left_led_on();
			}
			else
			{
				shift_right_led_on();
			}
		}
		if (get_button(BUTTON2, BUTTON2PIN))
		{
			button2_state = !button2_state; // 반전 0 <--> 1
			if(button2_state)
			{
				shift_left_keep_ledon();
			}
			else
			{
				shift_right_keep_ledon();
			}
		}
		if (get_button(BUTTON3, BUTTON3PIN))
		{
			button3_state = !button3_state; // 반전 0 <--> 1
			if(button3_state)
			{
				flower_on();
			}
			else
			{
				flower_off();
			}
		}
	}
	
#endif
}

 

<실행 결과>

https://youtube.com/shorts/sUrGC9mSCYI

 

FND dp 1초마다 깜빡임

 

<fnd.c>

/*
 * fnd.c
 *
 * Created: 2025-03-06 오후 12:22:24
 *  Author: microsoft
 */ 

#include "fnd.h"

void init_fnd(void);
uint32_t ms_count = 0; // ms를 재는 count 변수 unsigned int --> uint32_t
uint32_t sec_count = 0; // 초를 재는 count 변수 unsigned int --> uint32_t
uint32_t dp_count = 0;
int fnd_main(void);
void fnd_display(void);

int fnd_main(void)
{
	init_fnd();
	
	while(1)
	{
		fnd_display();
		_delay_ms(1);
		ms_count++;
		if(ms_count >= 1000) // 1000ms --> 1s
		{
			ms_count = 0;
			dp_count = !dp_count;
			sec_count++;
		}
	}
	
	return 0;
}

void init_fnd(void)
{
	FND_DATA_DDR = 0xff; // 출력 모드로 설정
	// FND_DIGIT_DDR |= 0xf0; // 자릿수 선택 7654
	FND_DIGIT_DDR |= 1 << FND_DIGIT_D1 | 1 << FND_DIGIT_D2 | 1 << FND_DIGIT_D3 | 1 << FND_DIGIT_D4;
	
	// fnd를 all off
#if 1 // common cathode 방식
	FND_DATA_PORT = 0x00; // fnd를 all off
#else // common anode 방식
	FND_DATA_PORT = ~0x00; // fnd를 all off 0xff;
#endif
}

void fnd_display(void)
{
#if 1 // common cathode 방식
						  //  0      1      2      3      4      5      6      7      8      9      .
	uint8_t fnd_font[] = {~0xc0, ~0xf9, ~0xa4, ~0xb0, ~0x99, ~0x92, ~0x82, ~0xd8, ~0x80, ~0x90, ~0x7f};
#else // common anode 방식
						 //  0     1     2     3     4     5     6     7     8     9     .
	uint8_t fnd_font[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xd8, 0x80, 0x90, 0x7f};
#endif

	static int digit_select = 0; // static을 쓰면 전역 변수처럼 함수가 빠져 나갔다가 다시 들어오더라도 값을 유지
	
	switch(digit_select)
	{
		case 0: 
#if 1 // common cathode
			FND_DIGIT_PORT = ~(1 << FND_DIGIT_D4); // 01111111 FND_FIGIT_PORT = ~0x80
#else // common anode
			FND_DIGIT_PORT = 1 << FND_DIGIT_D4; // 10000000 FND_FIGIT_PORT = 0x80
#endif
			FND_DATA_PORT = fnd_font[sec_count % 10]; // 0~9초
			break;
		case 1: 
#if 1 // common cathode
			FND_DIGIT_PORT = ~(1 << FND_DIGIT_D3); // FND_FIGIT_PORT = ~0x40
#else // common anode
			FND_DIGIT_PORT = 1 << FND_DIGIT_D3; // FND_FIGIT_PORT = 0x40
#endif
			FND_DATA_PORT = fnd_font[sec_count / 10 % 6]; // 10단위초
			if(dp_count)
				FND_DATA_PORT |= fnd_font[10];
			else
				FND_DATA_PORT = fnd_font[sec_count / 10 % 6];
			break;
		case 2: 
#if 1 // common cathode
			FND_DIGIT_PORT = ~(1 << FND_DIGIT_D2); // FND_FIGIT_PORT = ~0x20
#else // common anode
			FND_DIGIT_PORT = 1 << FND_DIGIT_D2; // FND_FIGIT_PORT = 0x20
#endif
			FND_DATA_PORT = fnd_font[sec_count / 60 % 10]; // 1단위 분
			break;
		case 3: 
#if 1 // common cathode
			FND_DIGIT_PORT = ~(1 << FND_DIGIT_D1); // FND_FIGIT_PORT = ~0x10
#else // common anode
			FND_DIGIT_PORT = 1 << FND_DIGIT_D1; // FND_FIGIT_PORT = 0x10
#endif
			FND_DATA_PORT = fnd_font[sec_count / 600 % 6]; // 10단위 분
			break;
	}
	digit_select++;
	digit_select %= 4; // 다음 표시할 자릿수 선택
}

 

<실행 결과>

https://youtube.com/shorts/hQq_IM9UGns

 

 

Common Anode 방식 기준 (Common Cathode 방식은 ~적용)

0.  초기

1.      ㅡ
10분 1111_1111 0xff
1분   1111_1110 0xfe


 2.   ㅡ ㅡ
10분 1111_1110  0xfe
1분   1111_1110 0xfe

 3.ㅣㅡ ㅡ
10분 1101_1110 0xde
1분   1111_1110 0xfe


 4. ㅣㅡ ㅡ
    ㅣ
10분 1100_1110 0xce
1분   1111_1110 0xfe


5. ㅣㅡㅡ
    ㅣㅡ
10분 1100_0110 0xc6
1분   1111_1110 0xfe


6. ㅣㅡㅡ
    ㅣㅡㅡ
10분 1100_0110 0xc6
1분   1111_0110 0xf6


7. ㅣㅡㅡ
    ㅣㅡㅡㅣ
10분 1100_0110 0xc6
1분   1111_0010 0xf2


8. ㅣㅡㅡㅣ
    ㅣㅡㅡㅣ
10분 1100_0110 0xc6
1분   1111_0000 0xf0

 

<fnd.c>

/*
 * fnd.c
 *
 * Created: 2025-03-06 오후 12:22:24
 *  Author: microsoft
 */ 

#include "fnd.h"
#include "button.h"

void init_fnd(void);
extern void init_button(void);
extern int get_button(int button_num, int button_pin);
uint32_t ms_count = 0; // ms를 재는 count 변수 unsigned int --> uint32_t
uint32_t sec_count = 0; // 초를 재는 count 변수 unsigned int --> uint32_t
uint32_t dp_count = 0;

int button0_state = 0;
int button1_state = 0;

int fnd_main(void);
void fnd_display(void);
void circle(void);

int fnd_main(void)
{
	init_fnd();
	init_button();
	
	while(1)
	{
		if (get_button(BUTTON0, BUTTON0PIN))
		{
			button0_state = !button0_state;
		}
		if (get_button(BUTTON1, BUTTON1PIN))
		{
			button1_state = !button1_state;
			if(button1_state)
			{
				sec_count = 0;
				button1_state = 0;
			}
		}
		fnd_display();
		_delay_ms(1);
		ms_count++;
		if(ms_count >= 1000) // 1000ms --> 1s
		{
			ms_count = 0;
			dp_count = !dp_count;
			sec_count++;
		}
	}
	
	return 0;
}

void init_fnd(void)
{
	FND_DATA_DDR = 0xff; // 출력 모드로 설정
	// FND_DIGIT_DDR |= 0xf0; // 자릿수 선택 7654
	FND_DIGIT_DDR |= 1 << FND_DIGIT_D1 | 1 << FND_DIGIT_D2 | 1 << FND_DIGIT_D3 | 1 << FND_DIGIT_D4;
	
	// fnd를 all off
#if 1 // common cathode 방식
	FND_DATA_PORT = 0x00; // fnd를 all off
#else // common anode 방식
	FND_DATA_PORT = ~0x00; // fnd를 all off 0xff;
#endif
}

void fnd_display(void)
{
#if 1 // common cathode 방식
						  //  0      1      2      3      4      5      6      7      8      9      .
	uint8_t fnd_font[] = {~0xc0, ~0xf9, ~0xa4, ~0xb0, ~0x99, ~0x92, ~0x82, ~0xd8, ~0x80, ~0x90, ~0x7f};
		
	static uint8_t fnd_font10[] = {~0xff, ~0xff, ~0xfe, ~0xde, ~0xce, ~0xc6, ~0xc6, ~0xc6, ~0xc6};
	static uint8_t fnd_font1[] = {~0xff, ~0xfe, ~0xfe, ~0xfe, ~0xfe, ~0xfe, ~0xf6, ~0xf2, ~0xf0};
		
#else // common anode 방식
						 //  0     1     2     3     4     5     6     7     8     9     .
	uint8_t fnd_font[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xd8, 0x80, 0x90, 0x7f};
#endif

	static int digit_select = 0; // static을 쓰면 전역 변수처럼 함수가 빠져 나갔다가 다시 들어오더라도 값을 유지
	
	switch(digit_select)
	{
		case 0: 
#if 1 // common cathode
			FND_DIGIT_PORT = ~(1 << FND_DIGIT_D4); // 01111111 FND_FIGIT_PORT = ~0x80
#else // common anode
			FND_DIGIT_PORT = 1 << FND_DIGIT_D4; // 10000000 FND_FIGIT_PORT = 0x80
#endif
			FND_DATA_PORT = fnd_font[sec_count % 10]; // 0~9초
			break;
		case 1: 
#if 1 // common cathode
			FND_DIGIT_PORT = ~(1 << FND_DIGIT_D3); // FND_FIGIT_PORT = ~0x40
#else // common anode
			FND_DIGIT_PORT = 1 << FND_DIGIT_D3; // FND_FIGIT_PORT = 0x40
#endif
			FND_DATA_PORT = fnd_font[sec_count / 10 % 6]; // 10단위초
			if(dp_count)
				FND_DATA_PORT |= fnd_font[10];
			else
				FND_DATA_PORT = fnd_font[sec_count / 10 % 6];
			break;
		case 2: 
#if 1 // common cathode
			FND_DIGIT_PORT = ~(1 << FND_DIGIT_D2); // FND_FIGIT_PORT = ~0x20
#else // common anode
			FND_DIGIT_PORT = 1 << FND_DIGIT_D2; // FND_FIGIT_PORT = 0x20
#endif
			if(button0_state)
				FND_DATA_PORT = fnd_font1[sec_count % 9];
			else
				FND_DATA_PORT = fnd_font[sec_count / 60 % 10]; // 1단위 분
			break;
		case 3: 
#if 1 // common cathode
			FND_DIGIT_PORT = ~(1 << FND_DIGIT_D1); // FND_FIGIT_PORT = ~0x10
#else // common anode
			FND_DIGIT_PORT = 1 << FND_DIGIT_D1; // FND_FIGIT_PORT = 0x10
#endif
			if(button0_state)
				FND_DATA_PORT = fnd_font10[sec_count % 9];
			else
				FND_DATA_PORT = fnd_font[sec_count / 600 % 6]; // 10단위 분
			break;
	}
	digit_select++;
	digit_select %= 4; // 다음 표시할 자릿수 선택
}

 

<실행 결과>

https://youtube.com/shorts/v6ayosStPjI

 

'(Telechips) AI 시스템 반도체 SW 개발자 교육 > ATmega128A 마이크로컨트롤러 프로그래밍' 카테고리의 다른 글

6일차  (0) 2025.03.11
5일차  (0) 2025.03.10
4일차  (0) 2025.03.07
2일차  (0) 2025.03.05
1일차  (0) 2025.03.04