«   2025/11   »
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");

2일차 본문

2025.03.05

 

Notepad 다운

 

KiCAD 다운

 

오늘의 학습 목표

- LED 제어 / Button 제어 / LED -- Button 연동

 

아스키코드

 

/*
 * 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 헤더파일

// none o/s 방식 또는 loop monitor 방식
void main(void)
{
		   //76543210
	DDRA = 0b11111111; // PORTA를 출력 모드(1)로 설정
	      // ---- 상위 nibble : 상위 4bits
		  //     ---- 하위 nibble : 하위 4bits
					   // DDR(Data Direction Register) : 방향 설정
					   // 1 : 출력, 0 : 입력을 의미
					   // 0b : 2진수
					   // 0x : hex
					   // DDRA = 0Xff;
	
    while (1)   // for(;;)
    {
		PORTA = 0b11111111; // LED 8개 all on
							// PORTA = 0xff;
							// 255(DEC) = ff(HEX) = 1111 1111(BIN)
		_delay_ms(1000);
		PORTA = 0b00000000; // LED 8개 all off
							// PORTA = 0x00;
		_delay_ms(1000);
    }
}

 

함수 분할 컴파일

 

<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 헤더파일

extern int led_main(void); // 함수가 다른 파일에 들어있으면 extern으로 선언

// none o/s 방식 또는 loop monitor 방식
int main(void)
{
	led_main();
		   //76543210
	DDRA = 0b11111111; // PORTA를 출력 모드(1)로 설정
	      // ---- 상위 nibble : 상위 4bits
		  //     ---- 하위 nibble : 하위 4bits
					   // DDR(Data Direction Register) : 방향 설정
					   // 1 : 출력, 0 : 입력을 의미
					   // 0b : 2진수
					   // 0x : hex
					   // DDRA = 0Xff;
	
    while (1)   // for(;;)
    {
		PORTA = 0b11111111; // LED 8개 all on
							// PORTA = 0xff;
							// 255(DEC) = ff(HEX) = 1111 1111(BIN)
		_delay_ms(1000);
		PORTA = 0b00000000; // LED 8개 all off
							// PORTA = 0x00;
		_delay_ms(1000);
    }
}

 

<led.c>

/*
 * led.c
 *
 * Created: 2025-03-05 오전 10:23:48
 *  Author: microsoft
 */ 

#include "led.h"

int led_main(void); // 선언
void led_all_on(void);
void led_all_off(void);

int led_main(void) // 정의
{
	DDRA = 0xff; // PORTA에 연결된 pin8개를 output mode로 
	
	while(1)
	{
		led_all_on();
		_delay_ms(1000);
		led_all_off();
		_delay_ms(1000);
	}
}

void led_all_on(void)
{
	PORTA = 0xff;
}

void led_all_off(void)
{
	PORTA = 0x00;
}

 

<led.h>

/*
 * led.h
 *
 * Created: 2025-03-05 오전 10:20:12
 *  Author: microsoft
 */ 


#ifndef LED_H_
#define LED_H_

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

#endif /* LED_H_ */

 

LED 순차적으로 점등

 

<led.c>

/*
 * led.c
 *
 * Created: 2025-03-05 오전 10:23:48
 *  Author: microsoft
 */ 

#include "led.h"

int led_main(void); // 선언
void led_all_on(void);
void led_all_off(void);
void shift_left_led_on(void);
void shift_right_led_on(void);

int led_main(void) // 정의
{
	DDRA = 0xff; // PORTA에 연결된 pin8개를 output mode로 
	
	while(1)
	{
		led_all_on();
		_delay_ms(500);
		led_all_off();
		_delay_ms(500);
		shift_left_led_on();
		shift_right_led_on();
	}
}

void led_all_on(void)
{
	PORTA = 0xff;
}

void led_all_off(void)
{
	PORTA = 0x00;
}

void shift_left_led_on(void)
{
	for(int i = 0; i < 8; i++)
	{
		PORTA = 0b00000001 << i;
		//               1 i=0;
		//              1  i=1;
		//             1   i=2;
		//        10000000 i=7;
		_delay_ms(300);
	}
}

void shift_right_led_on(void)
{
	PORTA = 0;
	for(int i = 0; i < 8; i++)
	{
		PORTA = 0b10000000 >> i;
		//        10000000 i=0;
		//         1       i=1;
		//          1      i=2;
		//               1 i=7;
		_delay_ms(300);
	}
}

 

<led.h>

/*
 * led.h
 *
 * Created: 2025-03-05 오전 10:20:12
 *  Author: microsoft
 */ 


#ifndef LED_H_
#define LED_H_

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

#endif /* LED_H_ */

 

<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 헤더파일

extern int led_main(void); // 함수가 다른 파일에 들어있으면 extern으로 선언

// none o/s 방식 또는 loop monitor 방식
int main(void)
{
	led_main();
		   //76543210
	DDRA = 0b11111111; // PORTA를 출력 모드(1)로 설정
	      // ---- 상위 nibble : 상위 4bits
		  //     ---- 하위 nibble : 하위 4bits
					   // DDR(Data Direction Register) : 방향 설정
					   // 1 : 출력, 0 : 입력을 의미
					   // 0b : 2진수
					   // 0x : hex
					   // DDRA = 0Xff;
	
    while (1)   // for(;;)
    {
		PORTA = 0b11111111; // LED 8개 all on
							// PORTA = 0xff;
							// 255(DEC) = ff(HEX) = 1111 1111(BIN)
		_delay_ms(1000);
		PORTA = 0b00000000; // LED 8개 all off
							// PORTA = 0x00;
		_delay_ms(1000);
    }
}

 

<실행결과>

https://youtube.com/shorts/emRCSJOyokk?feature=share

 

LED 순차점등 (누적)

 

<led.c>

/*
 * led.c
 *
 * Created: 2025-03-05 오전 10:23:48
 *  Author: microsoft
 */ 

#include "led.h"

int led_main(void); // 선언
void led_all_on(void);
void led_all_off(void);
void shift_left_led_on(void);
void shift_right_led_on(void);
void shift_left_keep_ledon(void);
void shift_right_keep_ledon(void);

int led_main(void) // 정의
{
	DDRA = 0xff; // PORTA에 연결된 pin8개를 output mode로 
	
	while(1)
	{
		led_all_on();
		_delay_ms(500);
		led_all_off();
		_delay_ms(500);
		// shift_left_led_on();
		// shift_right_led_on();
		shift_left_keep_ledon();
		shift_right_keep_ledon();
	}
}

void led_all_on(void)
{
	PORTA = 0xff;
}

void led_all_off(void)
{
	PORTA = 0x00;
}

void shift_left_led_on(void)
{
	for(int i = 0; i < 8; i++)
	{
		PORTA = 0b00000001 << i;
		//               1 i=0;
		//              1  i=1;
		//             1   i=2;
		//        10000000 i=7;
		_delay_ms(300);
	}
}

void shift_right_led_on(void)
{
	PORTA = 0;
	for(int i = 0; i < 8; i++)
	{
		PORTA = 0b10000000 >> i;
		//        10000000 i=0;
		//         1       i=1;
		//          1      i=2;
		//               1 i=7;
		_delay_ms(300);
	}
}

void shift_left_keep_ledon(void)
{
	for(int i = 0; i < 8; i++)
	{
		// PORTA += 0b00000001 << i;
		PORTA |= 0b00000001 << i;
		_delay_ms(200);
	}
}

void shift_right_keep_ledon(void)
{
	PORTA = 0;
	for(int i = 0; i < 8; i++)
	{
		// PORTA += 0b10000000 >> i;
		PORTA |= 0b10000000 >> i;
		_delay_ms(200);
	}
}

 

<실행 결과>

https://youtube.com/shorts/kpYQcBxuhHE

 


LED flower 점등

 

<led.c>

/*
 * led.c
 *
 * Created: 2025-03-05 오전 10:23:48
 *  Author: microsoft
 */ 

#include "led.h"

int led_main(void); // 선언
void led_all_on(void);
void led_all_off(void);
void shift_left_led_on(void);
void shift_right_led_on(void);
void shift_left_keep_ledon(void);
void shift_right_keep_ledon(void);
void flower_on(void);
void flower_off(void);


int led_main(void) // 정의
{
	DDRA = 0xff; // PORTA에 연결된 pin8개를 output mode로 
	
	while(1)
	{
		// led_all_on();
		// _delay_ms(500);
		// led_all_off();
		// _delay_ms(500);
		// shift_left_led_on();
		// shift_right_led_on();
		// shift_left_keep_ledon();
		// shift_right_keep_ledon();
		flower_on();
		flower_off();
	}
}

void led_all_on(void)
{
	PORTA = 0xff;
}

void led_all_off(void)
{
	PORTA = 0x00;
}

void shift_left_led_on(void)
{
	for(int i = 0; i < 8; i++)
	{
		PORTA = 0b00000001 << i;
		//               1 i=0;
		//              1  i=1;
		//             1   i=2;
		//        10000000 i=7;
		_delay_ms(300);
	}
}

void shift_right_led_on(void)
{
	PORTA = 0;
	for(int i = 0; i < 8; i++)
	{
		PORTA = 0b10000000 >> i;
		//        10000000 i=0;
		//         1       i=1;
		//          1      i=2;
		//               1 i=7;
		_delay_ms(300);
	}
}

void shift_left_keep_ledon(void)
{
	for(int i = 0; i < 8; i++)
	{
		// PORTA += 0b00000001 << i;
		PORTA |= 0b00000001 << i;
		_delay_ms(200);
	}
}

void shift_right_keep_ledon(void)
{
	PORTA = 0;
	for(int i = 0; i < 8; i++)
	{
		// PORTA += 0b10000000 >> i;
		PORTA |= 0b10000000 >> i;
		_delay_ms(200);
	}
}

void flower_on(void)
{
	int left = 0;
	int right = 0;
	
	for(int i = 0; i < 4; i++)
	{
		left |= 0b00001000 >> i;
		_delay_ms(200);
		
		right |= 0b00010000 << i;
		_delay_ms(200);
		
		PORTA = left | right;
	}
}

/*
void flower_on(void)
{
	PORTA = 0;
	for (int i = 0; i < 4; i++)
	{
		PORTA |= 0x10 << i | 0x08 >> i;
		_delay_ms(50);
	}
}
*/

void flower_off(void)
{
	int left = 0b11110000;
	int right = 0b00001111;
	
	for(int i = 0; i < 5; i++)
	{
		left &= 0b11110000 >> i;
		_delay_ms(200);
		
		right &= 0b00001111 << i;
		_delay_ms(200);
		
		PORTA = left | right;
	}
}

/*
void flower_off(void)
{
	unsigned char h = 0xf0;
	unsigned char l = 0x0f;
	
	PORTA = 0;
	for (int i = 0; i < 4; i++)
	{
		PORTA = (h >> i) & 0xf0 | (l << i) & 0x0f;
		_delay_ms(50);
	}
	PORTA = 0;
	_delay_ms(200);
}
*/

 

<실행 결과>

https://youtube.com/shorts/obLDugxgONg

 

noise 제거 : debounce

 

Polling

- 대상을 주기적으로 감시하여 상황을 발생하면 해당 처리 루틴을 실행해 처리한다면, 인터럽트는 상대가 CPU에게 일을 처리해달라고 요청하는 수단

- 주기적으로 마이크로프로세서가 상태를 파악하기 위해 장치의 레지스터를 읽어야 하고, 이 작업이 진행되는 동안은 다른 장치의 체크는 힘들다

 

Interrupt

- CPU가 프로그램을 실행하고 있을때, 입출력 어떠한 주변장치들의 입출력이나 하드웨어 문제가 발생하여 처리가 필요한 경우, 프로그램에서 예외 등이 발생했을때 CPU에게 이를 알려주는 방식

 

LED BUTTON 조작

 

<button.h>

/*
 * button.h
 *
 * Created: 2025-03-05 오후 2:30:03
 *  Author: microsoft
 */ 


#ifndef BUTTON_H_
#define BUTTON_H_

#define F_CPU 16000000UL // 16MHZ Unsigned Long
#include <avr/io.h> // PORTA, PORTB 등의 I/O 관련 register 등이 있다.
#include <util/delay.h> // _delay_ms, _delay_us 헤더파일

#define LED_DDR DDRA // 이렇게 하는 이유 : LED PORT가 변경되면 #define만 바꿔주면 compiler가 변경

#define LED_PORT PORTA

#define BUTTON_DDR DDRD
#define BUTTON_PIN PIND // PIND는 PORTD를 읽는 register 5v:1 0v:0

#define BUTTON0PIN 3  // PORTD.3
#define BUTTON1PIN 4  // PORTD.4
#define BUTTON2PIN 5  // PORTD.5
#define BUTTON3PIN 6  // PORTD.6

#define BUTTON0 0 // PORTD.3의 가상의 index(S/W번호)
#define BUTTON1 1 // PORTD.4의 가상의 index(S/W번호)
#define BUTTON2 2 // PORTD.5의 가상의 index(S/W번호)
#define BUTTON3 3 // PORTD.6의 가상의 index(S/W번호)

#define BUTTON_NUMBER 4 // button의 개수

#define BUTTON_PRESS 1 // 버튼을 누르면 high(active-high)
#define BUTTON_RELEASE 0 // 버튼을 떼면 low

#endif /* BUTTON_H_ */

 

<button.c>

/*
 * button.c
 *
 * Created: 2025-03-05 오후 2:30:25
 *  Author: microsoft
 */ 
#include "button.h"
// 버튼 초기화 (방향설정 : 입력)
// PORTD 76543210
//		  1010     초기값
//		 10000111  &
// DDRD &= 0x87    // 3, 4, 5, 6을 input으로 설정한다. (1) 가독성이 떨어진다. (코드 해석이 어렵다)
//													  (2) port를 변경 시 프로그램 수정이 어렵다.

void init_button(void);
int get_button(int button_num, int button_pin);

void init_button(void)
{
	BUTTON_DDR &= ~(1 << BUTTON0PIN | 1 << BUTTON1PIN | 1 << BUTTON2PIN | 1 << BUTTON3PIN);
}

// 예)
// BUTTON0 : S/W 번호 --> button_num
// BUTTON0PIN : button pin
// return 값 1 : 버튼을 눌렀다 떼면 1을 return
//           0 : idle 상태

int get_button(int button_num, int button_pin)
{
	static unsigned char button_status[] = {BUTTON_RELEASE, BUTTON_RELEASE, BUTTON_RELEASE, BUTTON_RELEASE}; // 지역 변수에 static을 쓰면 전역 변수처럼 함수를 빠져 나갔다 다시 들어와도 값을 유지한다.
		
	int current_state;
	
	current_state = BUTTON_PIN & (1 << button_pin); // 버튼을 읽는다.
	if(current_state && button_status[button_num] == BUTTON_RELEASE) // 버튼이 처음 눌려진 noise high 상태
	{
		_delay_ms(60); // noise가 지나가기를 기다린다.
		button_status[button_num] = BUTTON_PRESS; // noise가 지나간 상태의 high 상태
		return 0; // 아직은 완전히 눌렸다 떼어진 상태가 아니다.
	}
	else if(current_state == BUTTON_RELEASE && button_status[button_num] == BUTTON_PRESS)
	{
		_delay_ms(60);
		button_status[button_num] = BUTTON_RELEASE; // 다음 버튼 체크를 위해서 초기화
		return 1; // 완전히 1번 눌렸다 떼어진 상태로 인정
	}
	
	return 0; // 버튼이 open된 상태
}

 

<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);

// none o/s 방식 또는 loop monitor 방식
int main(void)
{
	// led_main();
	int button0_state = 0; // 초기 상태를 0으로 출발
	
	init_button();
		   //76543210
	DDRA = 0b11111111; // PORTA를 출력 모드(1)로 설정
	      // ---- 상위 nibble : 상위 4bits
		  //     ---- 하위 nibble : 하위 4bits
					   // DDR(Data Direction Register) : 방향 설정
					   // 1 : 출력, 0 : 입력을 의미
					   // 0b : 2진수
					   // 0x : hex
					   // DDRA = 0Xff;
	
    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();
			}
		}
    }
}

 

<실행 결과>

https://youtube.com/shorts/QHCEE7I6xMU

 

LED BUTTON 제어 (4개의 버튼으로 4개의 LED 동작 실행)

 

<button.h>

/*
 * button.h
 *
 * Created: 2025-03-05 오후 2:30:03
 *  Author: microsoft
 */ 


#ifndef BUTTON_H_
#define BUTTON_H_

#define F_CPU 16000000UL // 16MHZ Unsigned Long
#include <avr/io.h> // PORTA, PORTB 등의 I/O 관련 register 등이 있다.
#include <util/delay.h> // _delay_ms, _delay_us 헤더파일

#define LED_DDR DDRA // 이렇게 하는 이유 : LED PORT가 변경되면 #define만 바꿔주면 compiler가 변경

#define LED_PORT PORTA

#define BUTTON_DDR DDRD
#define BUTTON_PIN PIND // PIND는 PORTD를 읽는 register 5v:1 0v:0

#define BUTTON0PIN 3  // PORTD.3
#define BUTTON1PIN 4  // PORTD.4
#define BUTTON2PIN 5  // PORTD.5
#define BUTTON3PIN 6  // PORTD.6

#define BUTTON0 0 // PORTD.3의 가상의 index(S/W번호)
#define BUTTON1 1 // PORTD.4의 가상의 index(S/W번호)
#define BUTTON2 2 // PORTD.5의 가상의 index(S/W번호)
#define BUTTON3 3 // PORTD.6의 가상의 index(S/W번호)

#define BUTTON_NUMBER 4 // button의 개수

#define BUTTON_PRESS 1 // 버튼을 누르면 high(active-high)
#define BUTTON_RELEASE 0 // 버튼을 떼면 low

#endif /* BUTTON_H_ */

 

<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)
{
	// led_main();
	int button0_state = 0; // 초기 상태를 0으로 출발
	int button1_state = 0;
	int button2_state = 0;
	int button3_state = 0;
	
	init_button();
		   //76543210
	DDRA = 0b11111111; // PORTA를 출력 모드(1)로 설정
	      // ---- 상위 nibble : 상위 4bits
		  //     ---- 하위 nibble : 하위 4bits
					   // DDR(Data Direction Register) : 방향 설정
					   // 1 : 출력, 0 : 입력을 의미
					   // 0b : 2진수
					   // 0x : hex
					   // DDRA = 0Xff;
	
    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();
			}
		}
    }
}

 

<button.c>

/*
 * button.c
 *
 * Created: 2025-03-05 오후 2:30:25
 *  Author: microsoft
 */ 
#include "button.h"
// 버튼 초기화 (방향설정 : 입력)
// PORTD 76543210
//		  1010     초기값
//		 10000111  &
// DDRD &= 0x87    // 3, 4, 5, 6을 input으로 설정한다. (1) 가독성이 떨어진다. (코드 해석이 어렵다)
//													  (2) port를 변경 시 프로그램 수정이 어렵다.

void init_button(void);
int get_button(int button_num, int button_pin);

void init_button(void)
{
	BUTTON_DDR &= ~(1 << BUTTON0PIN | 1 << BUTTON1PIN | 1 << BUTTON2PIN | 1 << BUTTON3PIN);
}

// 예)
// BUTTON0 : S/W 번호 --> button_num
// BUTTON0PIN : button pin
// return 값 1 : 버튼을 눌렀다 떼면 1을 return
//           0 : idle 상태

int get_button(int button_num, int button_pin)
{
	static unsigned char button_status[] = {BUTTON_RELEASE, BUTTON_RELEASE, BUTTON_RELEASE, BUTTON_RELEASE}; // 지역 변수에 static을 쓰면 전역 변수처럼 함수를 빠져 나갔다 다시 들어와도 값을 유지한다.
		
	int current_state;
	
	current_state = BUTTON_PIN & (1 << button_pin); // 버튼을 읽는다.
	if(current_state && button_status[button_num] == BUTTON_RELEASE) // 버튼이 처음 눌려진 noise high 상태
	{
		_delay_ms(60); // noise가 지나가기를 기다린다.
		button_status[button_num] = BUTTON_PRESS; // noise가 지나간 상태의 high 상태
		return 0; // 아직은 완전히 눌렸다 떼어진 상태가 아니다.
	}
	else if(current_state == BUTTON_RELEASE && button_status[button_num] == BUTTON_PRESS)
	{
		_delay_ms(60);
		button_status[button_num] = BUTTON_RELEASE; // 다음 버튼 체크를 위해서 초기화
		return 1; // 완전히 1번 눌렸다 떼어진 상태로 인정
	}
	
	return 0; // 버튼이 open된 상태
}

 

<led.c>

/*
 * led.c
 *
 * Created: 2025-03-05 오전 10:23:48
 *  Author: microsoft
 */ 

#include "led.h"

int led_main(void); // 선언
void led_all_on(void);
void led_all_off(void);
void shift_left_led_on(void);
void shift_right_led_on(void);
void shift_left_keep_ledon(void);
void shift_right_keep_ledon(void);
void flower_on(void);
void flower_off(void);


int led_main(void) // 정의
{
	DDRA = 0xff; // PORTA에 연결된 pin8개를 output mode로 
	
	while(1)
	{
		//led_all_on();
		//_delay_ms(50);
		//led_all_off();
		//_delay_ms(50);
		//shift_left_led_on();
		//shift_right_led_on();
		//shift_left_keep_ledon();
		//shift_right_keep_ledon();
		//flower_on();
		//flower_off();
	}
}

void led_all_on(void)
{
	PORTA = 0xff;
}

void led_all_off(void)
{
	PORTA = 0x00;
}

void shift_left_led_on(void)
{
	for(int i = 0; i < 8; i++)
	{
		PORTA = 0b00000001 << i;
		//               1 i=0;
		//              1  i=1;
		//             1   i=2;
		//        10000000 i=7;
		_delay_ms(50);
	}
}

void shift_right_led_on(void)
{
	PORTA = 0;
	for(int i = 0; i < 8; i++)
	{
		PORTA = 0b10000000 >> i;
		//        10000000 i=0;
		//         1       i=1;
		//          1      i=2;
		//               1 i=7;
		_delay_ms(50);
	}
}

void shift_left_keep_ledon(void)
{
	PORTA = 0;
	for(int i = 0; i < 8; i++)
	{
		// PORTA += 0b00000001 << i;
		PORTA |= 0b00000001 << i;
		_delay_ms(50);
	}
}

void shift_right_keep_ledon(void)
{
	PORTA = 0;
	for(int i = 0; i < 8; i++)
	{
		// PORTA += 0b10000000 >> i;
		PORTA |= 0b10000000 >> i;
		_delay_ms(50);
	}
}

void flower_on(void)
{
	int left = 0;
	int right = 0;
	
	for(int i = 0; i < 4; i++)
	{
		left |= 0b00001000 >> i;
		_delay_ms(50);
		
		right |= 0b00010000 << i;
		_delay_ms(50);
		
		PORTA = left | right;
	}
}

/*
void flower_on(void)
{
	PORTA = 0;
	for (int i = 0; i < 4; i++)
	{
		PORTA |= 0x10 << i | 0x08 >> i;
		_delay_ms(50);
	}
}
*/

void flower_off(void)
{
	int left = 0b11110000;
	int right = 0b00001111;
	
	for(int i = 0; i < 5; i++)
	{
		left &= 0b11110000 >> i;
		_delay_ms(50);
		
		right &= 0b00001111 << i;
		_delay_ms(50);
		
		PORTA = left | right;
	}
}

/*
void flower_off(void)
{
	unsigned char h = 0xf0;
	unsigned char l = 0x0f;
	
	PORTA = 0;
	for (int i = 0; i < 4; i++)
	{
		PORTA = (h >> i) & 0xf0 | (l << i) & 0x0f;
		_delay_ms(50);
	}
	PORTA = 0;
	_delay_ms(200);
}
*/

 

<실행 결과>

https://youtube.com/shorts/OYOCHglhcf4

 

FND 회로 연결

 

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

6일차  (0) 2025.03.11
5일차  (0) 2025.03.10
4일차  (0) 2025.03.07
3일차  (0) 2025.03.06
1일차  (0) 2025.03.04