BASIC4MCU | 질문게시판 | atmega128 초음파 센서 신장 측정
페이지 정보
작성자 가나다라 작성일2022-12-12 11:15 조회697회 댓글0건본문
여러명이 붙어서 잘못된 부분을 찾으려 했으나 눈에 띄지않아 올려봅니다
메인함수 그리고 세미클론 오류가 난다고 하는데 도저히 눈에 안보여서 올립니다.
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>
#include <avr/interrupt.h>
#define LCD_DB_PORT PORTA // LCD_DATABUS
#define LCD_DB_DDR DDRA
#define LCD_CMD_PORT PORTC // LCD_COMMAND
#define LCD_CMD_DDR DDRC
unsigned int default_position = 190; // 신장 측정기가 설치될 기준높이
volatile unsigned int distance = 0; // 58us 마다 ++증가될 카운터변수
volatile unsigned char togle =0; // PE4 가 반사파로 인해 HIGH 일때 1, 반사파가 끝나거나 없을땐 0
char str1[16]; // CLCD 1행의 문자열 배열
char str2[16]; // CLCD 2행의 문자열 배열
void pulse(void) // 초음파 센서에 5us input trigger pulse를 주는 함수
{
DDRE = 0xF0; // PORTE의 4-7번 핀을 출력으로
PORTE = 0x10; // 4번 핀에 HIGH
_delay_us(5); // 5us 동안
PORTE = 0x00;
DDRE = 0x00; // PORTE를 입력으로 전환(반사파로 인한 센서의 신호를 받기위한)
}
ISR(TIMER0_OVF_vect) // T/C 0 오버플로우 인터럽트 함수
{
distance++; // 58us 마다 증가
TCNT0 = 140; // TCNT0의 값을 140으로 초기화시켜준다.
}
ISR(INT4_vect) // PORTE 4번핀에 Rising edge OR Falling edge가 감지되면 INT4 ISR이 호출
{
if(togle == 0) // Rising edge일때
{
distance = 0; //distance 초기화
TCCR0= 0x02; //분주비 8ck
TCNT0 = 140;
EICRB=0x02; // EXT_int4 를 Falling edge 에서 호출되도록 설정
togle = 1;
TIMSK = 0x01; // T/C 0 Enable
}
else // Falling edge일때
{
TIMSK = 0x00; // T/C 4 Disable
togle = 0;
EICRB = 0x03; // EXT_int4 를 Rising edge 에서 호출되도록 설정
}
}
void LCD_cmd(unsigned char cmd) // LCD에 command를 입력함수
{
LCD_CMD_PORT = 0x00; // Instruction register 선택, Write Disable
LCD_DB_PORT = cmd; // LCD data bus에 command 출력
LCD_CMD_PORT = 0x01; // Write Enable
_delay_us(1); // LCD 명령처리 지연시간
LCD_CMD_PORT = 0x00; // Write Disable
_delay_us(100); // LCD 명령처리 지연시간
}
void LCD_init(void) // LCD 초기화 함수(Initialize)
{
LCD_cmd(0x38); // Function set (data length-8bit, 2행, 5x8dote)
LCD_cmd(0x0C); // Display on/off control(화면출력 ON, 커서표시 & 커서깜빡임 OFF)
LCD_cmd(0x06); // Entry mode set(커서 오른쪽 이동, 화면이동 OFF)
LCD_cmd(0x01); // Clear display
_delay_ms(2);
}
void LCD_data(unsigned char data) // LCD Data 전송 함수
{
LCD_CMD_PORT = 0x02; // Data register 선택, Write Disable
LCD_DB_PORT = data; // LCD data bus에 Data 출력
LCD_CMD_PORT = 0x03; // Write Enable
_delay_us(1);
LCD_CMD_PORT = 0x02; // Write Disable
_delay_us(100);
}
void LCD_print(unsigned char cmd, char *str) // LCD 문자출력 함수
{
LCD_cmd(cmd); // 출력위치 지정
while(*str != 0) // 문자열의 끝이 올때까지
{ LCD_data(*str);
str++;
}
}
ISR(INT0_vect) // default_position 증가 스위치 인터럽트
{
_delay_ms(200); // 키 디바운싱을 위한 딜레이
if( default_position >= 250) default_position = 190; // 250 이상이면 190으로 초기화
else default_position++;
sprintf(str1,"Position: %d cm ", default_position);
LCD_print(0x80,str1); // 스위치를 누르고 있을 때 값의 변화가 표시될 수 있도록 LCD 출력
}
ISR(INT1_vect) // default_position 감소 스위치 인터럽트
{
_delay_ms(200); // 키 디바운싱을 위한 딜레이
if( default_position <= 50) default_position = 190; // 50 이하면 190으로 초기화
else default_position--;
sprintf(str1,"Position: %d cm ", default_position);
LCD_print(0x80,str1); // 스위치를 누르고 있을 때 값의 변화가 표시될 수 있도록 LCD 출력
}
void IHM_Opening() // 시스템 시작 시 오프닝 출력함수
{
LCD_print(0x80," ULTRASONIC "); // 1행 문자열 출력
LCD_print(0xC0," HEIGHT METER "); // 2행 문자열 출력
_delay_ms(3000);
LCD_cmd(0x01); // Clear display
}
int main(void) // 메인함수
{
DDRD = 0x00;
PORTD = 0b00000011; // 스위치 연결포트 내부 풀업 설정
unsigned int height; // 신장 측정값 변수
LCD_DB_DDR = 0xFF; // LCD data bus, LCD command port 출력모드
LCD_CMD_DDR = 0xFF;
LCD_DB_PORT = 0x00;
LCD_CMD_PORT = 0x00;
_delay_us(50); // 명령처리 대기시간
LCD_init();
EICRB = 0x03; // EXT_int4 를 Rising edge 에서 호출되도록 설정
EIMSK = 0x10; // INT4 EXT_Interrupt Enabel
ACSR = 0x80; //아날로그 비교기 disable
EICRA = 0x00; // INT0,1 - Low level trigger 설정
EIMSK = EIMSK | 0b00000011; // INT0,1 Enable
EIFR = 0xFF; // External Interrupt Flags clear
sei(); // 전체 인터럽트 Enable
IHM_Opening();
while(1)
{
pulse();
_delay_ms(18); //펄스가 나갔다가 돌아올때까지
if (distance < 5 || distance > 200 ) continue;
//측정값의 최소값과 최대값을 정해서 범위를 벗어나는 값은 제거함.
height = default_position - distance;
sprintf(str1,"Position: %d cm ", default_position); // str에 출력문자 저장
sprintf(str2,"Height: %d cm ", height);
LCD_print(0x80,str1); // 1행 문자열 출력
LCD_print(0xC0,str2); // 2행 문자열 출력
_delay_ms(200); // CLCD 출력 주기를 위한 딜레이타임
}
}
댓글 0
조회수 697등록된 댓글이 없습니다.