거북이처럼 천천히

LED 가지고 놀기 (1) 본문

Embedded Programming/Atmega 128A 이것저것

LED 가지고 놀기 (1)

유로 청년 2024. 6. 29. 15:15

그 동안 Verilog를 공부하면서 AVR 에 대한 지식이 머리속에서 점차 사라지는 것 같았다.

따라서 LED를 가지고 이것저것하면서 AVR 에 관한 지식 및 감(?)을 쌓기 위해 "LED을 통한 뱀(?)을 출력" 하는 것을 해보았다.

 

 

1. 환경

  • PORT F에 LED(KR-1008SR)을 연결

 

2. 동작

  • LED에 일렬로 LED를 키는데, 이는 유한한 길이를 갖는다.
    따라서 유한한 길이를 갖고, 일직선 형태를 갖기 때문에 뱀(?)이라고 하겠다.
  • 뱀의 길이는 define 키워드를 사용하여 상수로 지정하였고, 원하는 뱀의 길이로 조정 가능
  • 뱀의 머리가 LED에 나타났다가 뱀의 꼬리가 LED에서 사라지면 그제서야 다시 뱀이 LED에 나타난다.
    ( 이해가 되지 않는다면 구현 영상을 보는 것을 추천 )

 

 

3. 구현 영상

 

 

 

4. 소스 코드

#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>

// Substitute Constant
#define LED_DDR			DDRF
#define LED_PORT		PORTF
#define DELAY_TIME		150
#define LENGTH_SNACK    4

// Function prototype
void init_LED();

// Main method
int main(void) {
	init_LED();
	
	// current_length_of_snack : 현재 출력되는 뱀의 길이 
	// data : LED_PORT로 출력한 데이터
	// can_i_print_snack : 뱀을 출력할 지 여부를 결정
	//                     0이면 zero padding, 1이면 1을 padding
	uint8_t current_length_of_snack = 0, data = 0x00;
	uint8_t can_i_print_snack = 1;
	
	while(1) {
		// padding 하면 MSB bit 의 데이터가 사라지기 때문에 
		// padding 하기 전에 미리 데이터를 가져온다.
		int8_t temp_contain = (data & 0x80);
		
		if(can_i_print_snack) {
			data = (data<<1) | (0x01);
			current_length_of_snack++;
			
			// 원하는 뱀의 길이 만큼 출력하면 더이상 1을 padding 하지 않고,
			// can_i_print_snack = 0 대입하여 0을 padding 하도록 한다.
			if(current_length_of_snack>=LENGTH_SNACK) can_i_print_snack = 0;
		}else data = (data<<1) & ~(0x01);
		
		LED_PORT = data;
		_delay_ms(DELAY_TIME);
		
		// temp_contain은 padding 하기전 MSB 의 정보를 갖고 있다.
		// temp_contain이 1이면 뱀이 영역 밖을 넘어간것이다.
		if(temp_contain) {
			current_length_of_snack--;
			
			// current_length_of_snack <= 0 이면 더이상 LED에 출력되는 뱀이 없다.
			if(current_length_of_snack<=0) can_i_print_snack = 1;
		}
	}
	
	return 0;
}

// Initialization of LED.
void init_LED() {
	LED_DDR = 0xff;
}