day25

jae up·2024년 11월 19일


struct문 사용뒤 붙어있는 LED는
typedef struct(led)에 있던 led를 들고온것

<버튼작동

/main.c/
#include "button.h"

int main(void)
{
LED_DDR=0xff;
BUTTON btnon;
BUTTON btnoff;
BUTTON btnTog;

Button_init(&btnon,&BUTTON_DDR,&BUTTON_PIN, BUTTON_ON);	//주소값주고, 등등등 BTN은 0번
Button_init(&btnoff,&BUTTON_DDR,&BUTTON_PIN, BUTTON_OFF);
Button_init(&btnTog,&BUTTON_DDR,&BUTTON_PIN, BUTTON_TOGGLE);

while (1) 
{
	if (BUTTON_getstate(&btnon)==ACT_RELEASE)
	{
		LED_PORT = 0xff;
	}
	if (BUTTON_getstate(&btnoff)==ACT_RELEASE)
	{
		LED_PORT = 0x00;
	}
	if (BUTTON_getstate(&btnTog)==ACT_RELEASE)
	{
		LED_PORT ^= 0xff;
	}
}
return 0;

}


<BUTTON.H>
#ifndef BUTTONH
#define BUTTONH

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

// LED 핀과 버튼 핀 관련 매크로
#define LED_DDR DDRB
#define LED_PORT PORTB
#define BUTTON_DDR DDRD
#define BUTTON_PIN PIND
#define BUTTON_ON 0
#define BUTTON_OFF 1
#define BUTTON_TOGGLE 2

// 버튼 상태를 표현하는 열거형
enum {PUSHED, RELEASED};
enum{NO_ACT, ACT_PUSH, ACT_RELEASE};

// BUTTON 구조체 정의
typedef struct _button {
volatile uint8_t ddr; // 버튼 핀의 DDR 레지스터
volatile uint8_t
pin; // 버튼 핀의 PIN 레지스터
uint8_t btnpin; // 버튼 핀 번호
uint8_t prevstate; // 이전 버튼 상태
} BUTTON;

void Button_init(BUTTON button, volatile uint8_t ddr, volatile uint8_t pin, uint8_t pinnum);
uint8_t BUTTON_getstate(BUTTON
button);

#endif / BUTTONH /

/button.c/
#include "button.h"

void Button_init(BUTTON button, volatile uint8_t ddr, volatile uint8_t pin, uint8_t pinnum)
{
button->ddr =ddr;
button->pin =pin;
button->btnpin = pinnum;
button->prevstate =RELEASED; //초기 값을 아무것도 안누른상태로 시작
button->ddr &= ~(1<btnpin); //버튼 핀을 입력을 설정한다
//button button >>>>ddr,pin의 주소를 받기위해
}
uint8_t BUTTON_getstate(BUTTON
button)
{
uint8_t curstate = *button->pin&(1<btnpin); //버튼의 현재 상태를 읽어옴
if((curstate ==PUSHED)&&(button->prevstate==RELEASED)) //안누른상태에서 누르면
{
_delay_ms(50); //디바운스코드
button->prevstate = PUSHED; // 버튼의 상태를 누름으로 변경
return ACT_PUSH; //리턴 값을 누름으로 반환
}
else if((curstate!=PUSHED)&&(button->prevstate==PUSHED)) //버튼을 누른 상태에서 떼면
{
_delay_ms(50); //디바운스코드
button->prevstate = RELEASED; // 버튼의 상태를 누름으로 변경
return ACT_RELEASE; //리턴 값을 누름으로 반환
}
return NO_ACT; //아무것도 안했을 때... 또는 누르고 있을때

}

개별포트에서 불 밝히기

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

int main(void)
{
DDRB = 0Xff; //0b11111111->출력 설정
DDRA = 0Xff;

PORTA = 0x00;
PORTB = 0x00;

while (1) 
{
	PORTB ^=0xff;
	_delay_ms(1000);
	PORTA^= 0xff;
	_delay_ms(500);
}

}


밀리초 카운터를 이용한 전구 밝히기
#define F_CPU 16000000UL
#include <avr/io.h>
#include <avr/interrupt.h>

static volatile uint32_t timer0_millis = 0; // 밀리초 카운터는 32비트로 확장

// 타이머 초기값 계산
const uint8_t TIMER0_INITIAL_VALUE = 256 - (F_CPU / 64 / 1000);

void millsinit()
{
TCCR0 &= ~((1 << WGM01) | (1 << WGM00)); // 일반 모드 설정 (CTC 모드 아님)
TCCR0 |= (1 << CS02); // 분주비 64 설정 (16 MHz / 64 = 250kHz)
TIMSK |= (1 << TOIE0); // 타이머0 오버플로우 인터럽트 활성화
TCNT0 = TIMER0_INITIAL_VALUE; // 타이머0 초기화
sei(); // 전역 인터럽트 활성화
}

ISR(TIMER0_OVF_vect)
{
TCNT0 = TIMER0_INITIAL_VALUE; // 오버플로우 시 초기화
timer0_millis++; // 1ms마다 증가
}

uint32_t millis()
{
uint32_t millis_return;
cli(); // 인터럽트 비활성화

millis_return = timer0_millis;  // 현재 millis 값 저장

sei();  // 인터럽트 활성화
return millis_return;

}

int main(void)
{
millsinit(); // 타이머 초기화

DDRA = 0xFF;  // PORTA를 출력으로 설정
DDRB = 0xFF;  // PORTB를 출력으로 설정
PORTA = 0x00; // PORTA 초기화 (모두 0)
PORTB = 0x00; // PORTB 초기화 (모두 0)

uint32_t prevTime1 = 0;
uint32_t prevTime2 = 0;

while (1)
{
	uint32_t currentTime = millis();

	// PORTB 1초 간격으로 토글
	if (currentTime - prevTime1 >= 1000)
	{
		prevTime1 = currentTime;
		PORTB ^= 0xFF;  // PORTB의 모든 핀 상태를 반전시킴
	}

	// PORTA 0.5초 간격으로 토글
	if (currentTime - prevTime2 >= 500)  // 0.5초 간격
	{
		prevTime2 = currentTime;
		PORTA ^= 0xFF;  // PORTA의 모든 핀 상태를 반전시킴
	}
}

}


VSCODE: EXIT EDITION
CMAKE : BUILD
MAKE : BUILD
AVRTUDE : PROGRAMING
AVR GCC : COMPIRIER

vs코드에서 위에 ㅌ테마 다운로드

다운로드 다 되면 cmake 다운

최종적으로 위와 같이 설치

profile
gullove

0개의 댓글