#define F_CPU 16000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <util/delay.h>
#define ENABLE (PORTA |= 0x04) // LCD ENable 또는 PORTA_Bit2=1;
#define DISABLE (PORTA &= 0xFB) // LCD DIsable 또는 PORTA_Bit2=0;
volatile unsigned int count=0; //count는 1cm마다 증가하는 변수. 즉, count 값이 곧 물체와의 거리이다.
volatile unsigned int length; //거리를 저장 할 변수
void init_PORTA(void)
{
DDRA = 0xFF; // PORTA 출력
PORTA=0xFF; // 초기 값
}
void delay(int dly)
{
while(dly--){
int i,n;
for(i=0;i<50;i++){
n=600;
while(n--);
}
}
}
void wait_busy_flag(void)
{
unsigned int i;
for(i=0;i<10000;i++);
}
void m_delay(unsigned int m) //딜레이 루틴
{
cli();
unsigned int i, j;
for(i=0;i<m;i++)
for(j=0;j<2650;j++); //16MHz : 1msec
sei();
}
void ddelay(unsigned int p)
{
unsigned int i;
for(i=0;i<p;i++);
}
void instruction_out(unsigned char b)//명령어 쓰기 함수
{
PORTA=b&0xF0; //상위 4BIT 출력
ENABLE; //ENABLE
DISABLE; //DISABLE
PORTA=(b<<4)&0xF0; //하위 4BIT 출력
ENABLE; //ENABLE
DISABLE; //DISABLE
//명령어 수행이 완료될때까지 지연
_delay_ms(2);
}
void char_out(unsigned char b) //LCD에 한문자 출력 함수
{
PORTA=(b&0xF0)|0x01; //상위 4BIT 출력
ENABLE; //ENABLE
DISABLE; //DISABLE
PORTA=((b<<4)&0xF0)|0x01; //하위 4BIT 출력
ENABLE; //ENABLE
DISABLE; //DISABLE
//명령어 수행이 완료될때까지 지연
_delay_ms(2);
}
void string_out(unsigned char b, unsigned char *str) //문자열 출력 함수
{
unsigned int i=0;
instruction_out(b); //LCD 위치 지정
do{
char_out(str[i]);
}while(str[++i]!='\0'); // NULL 문자를 만날 때 까지
}
void init_LCD(void) //LCD초기화 루틴
{
init_PORTA(); // LCD를 연결한 포트 초기화
_delay_ms(15);
ddelay(600);
instruction_out(0x28); //LCD FUNCTION SET(16X2 LINE, 4 BIT, 5X8 DOT)
_delay_ms(2);
instruction_out(0x28); //LCD FUNCTION SET(16X2 LINE, 4 BIT, 5X8 DOT)
_delay_ms(2);
instruction_out(0x0C); //LCD DISPLAY ON, CURSOR OFF, BLINK OFF
instruction_out(0x06); //LCD ENTRY MODE SET
instruction_out(0x02); //RETURN HOME
instruction_out(0x01); //LCD CLEAR
instruction_out(0x01); //LCD CLEAR
}
void init_SERIAL(void) // 시리얼 함수 초기화
{
DDRE=0xFE; // PE1(TXD) 출력(1), PE0(RXD) 입력(0)
UCSR0A=0x00;
UCSR0B=0x98; // Receive enable, Transmitte enable
UCSR0C=0x06; // 비동기 방식, No parity bit, 1 stop bit
UBRR0H=0;
UBRR0L=0x08; // 16MHz에서 9600 bps (10진수 103)
}
void lcd_decimal(unsigned int hex) //lcd 10진수 표기
{
unsigned int h;
//instruction_out(b); //lcd lotate
h=(hex/10000); //5자리수에서 첫째 자리 분리.
if (h!=0) char_out(h+0x30);
else char_out(0x30);
h=((hex%10000)/1000); //4
if (h!=0) char_out(h+0x30);
else char_out(0x30);
h=(((hex%10000)%1000)/100); //3
if (h!=0) char_out(h+0x30);
else char_out(0x30);
h=((((hex%10000)%1000)%100)/10); //2
if (h!=0) char_out(h+0x30);
else char_out(0x30);
h=((((hex%10000)%1000)%100)%10); //1
if (h!=0) char_out(h+0x30);
else char_out(0x30);
}
// 시리얼 포트로 한문자를 송신한다.
char getch(void)
{
unsigned char data;
while(!(UCSR0A & 0x80));
data=UDR0;
UCSR0A |=0x80;
return(data);
}
void putch(unsigned char data)
{
while(!(UCSR0A & 0x20));
UDR0=data;
UCSR0A |= 0x20; // 클리어 UDRE0
}
SIGNAL(SIG_OVERFLOW0)//타이머 0번 인터럽트 함수부분.
{
TCNT0 = 0x8b; //138; //(1/16us)*8분주*(256-138) =59us 마다 인터럽트를 발생 0x8a
count++; //cm 단위 srf04의 경우 59us가 1cm 이다 타이머 카운터0 레지스터 (읽기 쓰기가 가능) // 이곳도 잘되고있는지 궁금해요..
}
SIGNAL(SIG_INTERRUPT1) //에코신호가 들어오면...
{
SREG = 0x80;
DDRB= 0xff; //led입력
TIMSK = 0x01; // 타이머 정지
length = count; //지금까지 잰 거리를 length변수에 넣음.
EIMSK = 0; // 외부 인터럽트1 정지
if(length > 10){
PORTB =0x80; // 이곳이 작동이 안됨.
}else {
PORTB = 0x11; //물체가 그 사이에 없으면 led oFF
}
instruction_out(0xC1);
lcd_decimal(length);
count = 0;
cli();
}
int main(void)
{
unsigned char data;
DDRD = 0x02; //INT1(인터럽트)에 echo연결
DDRD= 0x01; //trigger연결
init_SERIAL(); //LCD 초기화
init_LCD();
instruction_out(0x01); // LCD clear
string_out(0x81,"USART0");
while(1){
EICRA = 0x02; // 외부 인터럽트 제어 레지스터 하강에지설정 ok
TCCR0 = 0x02; //8(8분주) -> 타이머 카운터 0 제어 레지스터 ok
SREG = 0x80; //set global interrupt enable 전역 인터럽트 인에이블 비트셋
PORTD= 0x01; //트리거 신호를 10us만큼 보낸다.
delay(1);
PORTD= 0x00;
//TCNT0 = 0x8b;
//(1/16us)*8분주*(256-138) =59us 마다 인터럽트를 발생
TIMSK = 0x01; //타이머 카운트 활성화 -> 이 때 부터 시간을 잰다.
EIMSK = 0b00000001; //오버플로우 인터럽트
EIMSK = 0b00000010; // 외부 인터럽트1 인에이블설정
delay(5);
}
}
제가 지금 하는 초음파모듈 거리 값 받아오는 건데요 아무리 해봐도 도저히 안되네요
방법좀 알려주세요
led 도 안켜지구요 ㅠㅠ
초음파거리측정 인테넷에 자료는 많아도 다 거기서 거기죠 소스와 설명이....... 저도 애를먹었죠 아무것도 없는 상태에서 하려다가 ㅎㅎ