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 |