ATmega128_ Stand Light 설계

JS·2023년 2월 21일
0

ATmega128

목록 보기
1/9


위의 계층구조를 기반으로 Stand Light를 설계해보자.

레지스터 DDR, PORT, PIN

DDR 레지스터: 
- 포트의 입출력을 결정 -> 0(Low)이면 INPUT, 1(High)이면 OUTPUT이며, A ~ G의 포트 중 선택할 수 있음. 
- 기본 값은 0이다.

PORT: 
- DDR을 통해 출력으로 설정될 경우, PORT 레지스터를 통해서 포트의 값을 출력한다. 
- 읽고 쓰는 것이 모두 가능한 레지스터

PIN: 
- DDR을 통해 입력으로 설정될 경우, PIN 레지스터를 통해서 포트의 값을 입력한다. 
- 읽고 쓰는 것만 가능한 레지스터

main code

//Stand_Light main

#include <avr/io.h>
#include "ap/Stand_Light/StandLight.h"

int main(void)
{
	StandLight_init();
	
	while (1)
	{
		StandLight_excute();
	}
}

StandLight code

#include "StandLight.h"

uint8_t standLightState;
button_t btnMode, btnOff;

void StandLight_init()
{
	Button_init(&btnOff, &DDRA, &PINA, 0);
	Button_init(&btnMode, &DDRA, &PINA, 1);
	Led_initPort(&LIGHT_DDR);
	standLightState = LIGHT_OFF;
}

void StandLight_excute()
{
	StandLight_eventCheck();
	StandLight_run();
}

void StandLight_eventCheck()
{
	switch (standLightState)
	{
		case LIGHT_OFF:
		if (Button_getState(&btnMode) == ACT_RELEASED) {
			standLightState = MODE_1;
		}
		break;
		case MODE_1:
		if (Button_getState(&btnMode) == ACT_RELEASED) {
			standLightState = MODE_2;
		}
		else if (Button_getState(&btnOff) == ACT_RELEASED) {
			standLightState = LIGHT_OFF;
		}
		break;
		case MODE_2:
		if (Button_getState(&btnMode) == ACT_RELEASED) {
			standLightState = MODE_3;
		}
		else if (Button_getState(&btnOff) == ACT_RELEASED) {
			standLightState = LIGHT_OFF;
		}
		break;
		case MODE_3:
		if (Button_getState(&btnMode) == ACT_RELEASED) {
			standLightState = MODE_4;
		}
		else if (Button_getState(&btnOff) == ACT_RELEASED) {
			standLightState = LIGHT_OFF;
		}
		break;
		case MODE_4:
		if (Button_getState(&btnMode) == ACT_RELEASED) {
			standLightState = LIGHT_OFF;
		}
		else if (Button_getState(&btnOff) == ACT_RELEASED) {
			standLightState = LIGHT_OFF;
		}
		break;
	}
}

void StandLight_run()
{
	switch (standLightState)
	{
		case LIGHT_OFF:
		StandLight_off();
		break;
		case MODE_1:
		StandLight_Mode_1();
		break;
		case MODE_2:
		StandLight_Mode_2();
		break;
		case MODE_3:
		StandLight_Mode_3();
		break;
		case MODE_4:
		StandLight_Mode_4();
		break;
	}
}

void StandLight_off()
{
	Led_allOff(&LIGHT_PORT);
}

void StandLight_Mode_1()
{
	Led_writePort(&LIGHT_PORT, 0b00000011);
}

void StandLight_Mode_2()
{
	Led_writePort(&LIGHT_PORT, 0b00001111);
}

void StandLight_Mode_3()
{
	Led_writePort(&LIGHT_PORT, 0b00111111);
}

void StandLight_Mode_4()
{
	Led_writePort(&LIGHT_PORT, 0xff);
}

StandLight 헤더파일

#ifndef STANDLIGHT_H_
#define STANDLIGHT_H_

#include <avr/io.h>
#include "../../driver/Button/Button.h"
#include "../../driver/Led/Led.h"

#define LIGHT_DDR	DDRD
#define LIGHT_PORT	PORTD

enum {LIGHT_OFF, MODE_1, MODE_2, MODE_3, MODE_4};

void StandLight_init();
void StandLight_excute();
void StandLight_eventCheck();
void StandLight_run();
void StandLight_off();
void StandLight_Mode_1();
void StandLight_Mode_2();
void StandLight_Mode_3();
void StandLight_Mode_4();


#endif /* STANDLIGHT_H_ */

Led code

#include "Led.h"

void Led_initPort(volatile uint8_t *DDR)
{
	Gpio_initPort(DDR, OUTPUT);
}

void Led_writePort(volatile uint8_t *PORT, uint8_t data)
{
	Gpio_writePort(PORT, data);
}

void Led_allOn(volatile uint8_t *PORT)
{
	Gpio_writePort(PORT, 0xff);
}

void Led_allOff(volatile uint8_t *PORT)
{
	Gpio_writePort(PORT, 0x00);
}

Led 헤더파일

#ifndef LED_H_
#define LED_H_

#include <avr/io.h>
#include "../../periph/GPIO/Gpio.h"

void Led_initPort(volatile uint8_t *DDR);
void Led_writePort(volatile uint8_t *PORT, uint8_t data);
void Led_allOn(volatile uint8_t *PORT);
void Led_allOff(volatile uint8_t *PORT);


#endif /* LED_H_ */

Button code

#include "Button.h"

void Button_init(button_t *btn, volatile uint8_t *DDR, volatile uint8_t *PIN, uint8_t pinNum)
{
	btn->DDR = DDR;
	btn->PIN = PIN;
	btn->pinNum = pinNum;
	btn->prevState = RELEASED;
	Gpio_initPin(btn->DDR, btn->pinNum, INPUT);
}

uint8_t Button_getState(button_t *btn)
{
	uint8_t curState = Gpio_readPin(btn->PIN, btn->pinNum);
	if ( (curState == PUSHED) && (btn->prevState == RELEASED) ) {
		_delay_ms(10); // debounce code
		btn->prevState = PUSHED;
		return ACT_PUSHED;
	}
	else if ( (curState != PUSHED) && (btn->prevState == PUSHED) ){
		_delay_ms(10); // debounce code
		btn->prevState = RELEASED;
		return ACT_RELEASED;
	}
	return ACT_NONE;
}

Button 헤더파일

#ifndef BUTTON_H_
#define BUTTON_H_

#define F_CPU	16000000UL
#include <avr/io.h>
#include <util/delay.h>
#include "../../periph/GPIO/Gpio.h"

enum {PUSHED, RELEASED};
enum {ACT_NONE, ACT_PUSHED, ACT_RELEASED};

typedef struct _button {
	volatile uint8_t *DDR;
	volatile uint8_t *PIN;
	uint8_t pinNum;
	uint8_t prevState;
}button_t;

void Button_init(button_t *btn, volatile uint8_t *DDR, volatile uint8_t *PIN, uint8_t pinNum);
uint8_t Button_getState(button_t *btn);




#endif /* BUTTON_H_ */

GPIO code

#include "Gpio.h"

void Gpio_initPort(volatile uint8_t *DDR, uint8_t dir)
{
	if (dir == OUTPUT) {
		*DDR = 0xff;
	}
	else {
		*DDR = 0x00;
	}
}

void Gpio_initPin(volatile uint8_t *DDR, uint8_t pinNum, uint8_t dir)
{
	if (dir == OUTPUT) {
		*DDR |= (1 << pinNum); // OUTPUT mode
	}
	else {
		*DDR &= ~(1 << pinNum); // INPUT mode
	}
}

void Gpio_writePort(volatile uint8_t *PORT, uint8_t data)
{
	*PORT = data;
}

uint8_t Gpio_readPort(volatile uint8_t *PIN)
{
	return *PIN;
}

void Gpio_writePin(volatile uint8_t *PORT, uint8_t pinNum, uint8_t state)
{
	if (state == GPIO_PIN_SET) {
		*PORT |= (1 << pinNum); // GPIO_PIN_SET
	}
	else {
		*PORT &= ~(1 << pinNum); // GPIO_PIN_RESET
	}
}

uint8_t Gpio_readPin(volatile uint8_t *PIN, uint8_t pinNum)
{
	return ((*PIN & (1 << pinNum)) != 0); // xxx1xxxx & 00010000 => 16
}

GPIO 헤더파일

#ifndef GPIO_H_
#define GPIO_H_

#include <avr/io.h>

enum {INPUT, OUTPUT};
enum {GPIO_PIN_RESET, GPIO_PIN_SET};

void Gpio_initPort(volatile uint8_t *DDR, uint8_t dir);
void Gpio_initPin(volatile uint8_t *DDR, uint8_t pinNum, uint8_t dir);
void Gpio_writePort(volatile uint8_t *PORT, uint8_t data);
uint8_t Gpio_readPort(volatile uint8_t *PIN);
void Gpio_writePin(volatile uint8_t *PORT, uint8_t pinNum, uint8_t state);
uint8_t Gpio_readPin(volatile uint8_t *PIN, uint8_t pinNum);



#endif /* GPIO_H_ */

0개의 댓글