초음파센서 드라이브 만들기
2023. 3. 3. 13:27ㆍAVR 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 |