초음파센서 드라이브 만들기

2023. 3. 3. 13:27AVR ATmega128

같은 폴더 안에 driver 폴더를 만들고 초음파 폴더를 만들어준다.

 

이전 코드의 초음파센서 관련 함수를 모두 복붙해서 Ultrasonic.c에 복사해준다.

/*
 * Ultrasonic.c
 *
 * Created: 2023-03-03 오후 1:13:48
 *  Author: yrt12
 */ 


#include "Ultrasonic.h"
uint8_t ultrasonicDistanceFlag;
void Ultrasonic_timerStart()
{
	USONIC_TCNT = 0;
	TCCR1B |= 1<<CS11 | 1<<CS10;
}

void Ultrasonic_timerStop()
{
	TCCR1B &= ~(1<<CS11 | 1<<CS10 | 1<<CS12);
}

uint16_t Ultrasonic_getDistance()
{
	return USONIC_TCNT * 0.068; // cm단위
}
void Ultrasonic_init()
{
	USONIC_DDR |= 1<<USONIC_TRIG; //Trig
	USONIC_DDR &= ~1<<USONIC_ECHO; //Echo
	EICRA |= 1<<USONIC_ISC0 | 1<<USONIC_ISC1;//Rising Edge
	EIMSK |= 1<<USONIC_INT; //Interrupt 2 enable
	TCCR1B = 1<<CS11 | 1<<CS10; //PreScaler 64
	ultrasonicDistanceFlag = 0;
}

void Ultrasonic_trigger()
{
	USONIC_PORT |= 1<<USONIC_TRIG;
	_delay_us(15);
	USONIC_PORT &= ~(1<<USONIC_TRIG);
}


void Ultrasonic_switchInterrupt(uint8_t mode)
{
	if(mode == FALLING_EDGE)
	{
		EICRA |= 1<<USONIC_ISC1;
		EICRA &= ~(1<<USONIC_ISC0);
	}
	else
	{
		EICRA |= 1<<USONIC_ISC0 | 1<<USONIC_ISC1; //Rising Edge
	}
}

uint8_t Ultrasonic_getCompleteFlag()
{
	return ultrasonicDistanceFlag;
}
void Ultrasonic_setCompleteFlag()
{
	ultrasonicDistanceFlag = 1;
}

void Ultrasonic_clearCompleteFlag()
{
	ultrasonicDistanceFlag = 0;
}

void Ultrasonic_ISRProcess()
{
	if(USONIC_PIN & (1<<USONIC_ECHO)) //ECHO핀이 HIGH이면
	//if(((USONIC_EICR & (1<<USONIC_ISC0)) == 1)&&((USONIC_EICR & (1<<USONIC_ISC1)) == 1)) EICRA의 레지스터에 저장된 값이 라이징 엣지 였을때
	{
		Ultrasonic_timerStart();
		Ultrasonic_switchInterrupt(FALLING_EDGE);
	}
	else
	{
		Ultrasonic_timerStop();
		Ultrasonic_setCompleteFlag();
		Ultrasonic_switchInterrupt(RISING_EDGE);
	}
}

헤더 파일에는 Define으로 정한 값들과 함수 이름을 넣어준다. 함수 이름을 넣을 때 세미콜론을 넣지 않으면 컴파일 오류가 발생한다. 

/*
 * Ultrasonic.h
 *
 * Created: 2023-03-03 오후 1:14:12
 *  Author: yrt12
 */ 


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

#define USONIC_PIN PIND
#define USONIC_PORT PORTD
#define USONIC_DDR DDRD
#define USONIC_TRIG 3
#define USONIC_ECHO 2
#define USONIC_ISC0 ISC20
#define USONIC_ISC1 ISC21
#define USONIC_EICR EICRA
#define USONIC_INT INT2
#define USONIC_TCNT TCNT1
enum {FALLING_EDGE, RISING_EDGE};

void Ultrasonic_ISRProcess();
void Ultrasonic_clearCompleteFlag();
void Ultrasonic_setCompleteFlag();
uint8_t Ultrasonic_getCompleteFlag();
void Ultrasonic_switchInterrupt(uint8_t mode);
void Ultrasonic_trigger();
void Ultrasonic_init();
uint16_t Ultrasonic_getDistance();
void Ultrasonic_timerStop();
void Ultrasonic_timerStart();

#endif /* ULTRASONIC_H_ */

이제 메인 함수에 include 시켜준다. 

/*
 * SuperSonic.c
 *
 * Created: 2023-03-03 오전 9:15:30
 * Author : yrt12
 */ 
#define F_CPU 16000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "driver/LCD/LCD.h"
#include "driver/Ultrasonic/Ultrasonic.h"
#include <stdio.h>

ISR(INT2_vect)
{
	Ultrasonic_ISRProcess();
}



int main(void)
{
	Ultrasonic_init();
	LCD_init();
	sei();
	char buff[30];
	uint16_t distance;

    /* Replace with your application code */
    while (1) 
    {
		Ultrasonic_trigger(); //트리거 신호 보냄
		_delay_ms(500);
		if(Ultrasonic_getCompleteFlag()) //거리측정 완료
		{
			Ultrasonic_clearCompleteFlag(); 
			distance = Ultrasonic_getDistance(); //cm거리계산
			sprintf(buff, "distance = %03dcm", distance);
			LCD_writeStringXY(1,0,buff);
		}
		
    }
}

'AVR ATmega128' 카테고리의 다른 글

UART 활용  (0) 2023.03.06
UART  (0) 2023.03.06
I2C(TWI) LCD  (1) 2023.03.03
AVR초음파 센서  (0) 2023.03.03
Timer를 이용한 Fan만들기  (0) 2023.03.02