반응형
J-kit, 초음파센서 SR04 3개를 이용한 GPS 센서
센서에서 전방을 향해 초음파를 발사,
물체에 부딪혀 반사되는 초음파가 돌아오는 시간의 길이를 계산,
ECHO 핀에서 시간의 길이에 비례하는 펄스를 출력한다.
// MCU에서 해 줄 작업은,
10us길이의 TRIGGER 파형을 센서로 출력하고,
그 결과 센서에서 출력되는 ECHO 파형을 감지해 이를 거리로 계산하는 것이다.
if(EICRB==3){ // 라이징엣지에서 인터럽트가 걸리면
start=TCNT1; // TCNT1값을 저장해두고
EICRB=2; // 다음번 인터럽트는 폴링엣지로 설정
}
else{ // 폴링엣지에서 인터럽트가 걸리면
end=TCNT1; // TCNT1값을 저장해두고
EICRB=3; // 다음번 인터럽트는 라이징엣지로 설정
dist= (int)( (float)(end-start) / 14.5 ); // 58us / 4us = 14.5, cm로 변환
}
uS / 58 = centimeters or uS / 148 =inch
왕복거리이기 때문에 1/2하여 29uS당 1cm
//
// ControlSet.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | #ifndef _CONTROL_SET_ #define _CONTROL_SET_ #include <avr/io.h> #include <avr/interrupt.h> #include <util/delay.h> #define TEMPERATURE 25 #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) /*** Send start signal to ultrasonic sensor(NT-TS601) ***/ // number = quantity void SendSignal_0() { // Step 1. send signal during 10us sbi(PORTD,1); _delay_us(10); cbi(PORTD,1); } void SendSignal_1(){ sbi(PORTD,3); _delay_us(10); cbi(PORTD,3); } void SendSignal_2(){ sbi(PORTE,7); _delay_us(10); cbi(PORTE,7); } #endif | cs |
//RegSet.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | #ifndef _REGISTER_SET_ #define _REGISTER_SET_ #include <avr/io.h> #include <avr/interrupt.h> #include <util/delay.h> /*** Port Setting ***/ // Quantity of Sonar Sensors : 6 // INT0 ~ INT6 void PortInit() { DDRD = 0b00001010; // PD0 ~ PD3 PORTD = 0b00000000; DDRE = 0b10000000; PORTE = 0b00000000; } /*** Timer Register Setting ***/ // 1 cycle(20us) = 1/(16M/(2*8*(19+1)) void TimerInit() { TCCR0 = (1<<WGM01)|(1<<CS01); // CTC mode, clk/8 OCR0 = 58; // 58번째 비교 매치 인터럽트 발생 TCNT0 = 0; // 0부터 시작 TIMSK = (1<<OCIE0); // compare match enable TIFR = 0x00; // flag 초기화 //29uS } /*** External Interrupt Setting ***/ // Refer to the following comments. void ExtInit() { EICRA = 0b00110011; // INT0 ~ INT3 -> Rising Edge Default EICRB = 0b00110000; // INT4 ~ INT7 -> Rising Edge Default EIMSK = 0b01000101; // INT0 ~ INT5 -> INT0, INT2, INT4 enable EIFR = 0xff; } #endif /*** �� Reference 1 : External Interrupt Control Register (EICR) A, B BIT : [ 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 ] EICRA : [ ISC31 | ISC30 | ISC21 | ISC20 | ISC11 | ISC10 | ISC01 | ISC00 ] BIT : [ 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 ] EICRB : [ ISC71 | ISC70 | ISC61 | ISC60 | ISC51 | ISC50 | ISC41 | ISC40 ] �� Reference 2 : Interrupt Sense Control (A) [ISCn1 | ISCn0 | Description ] 0 | 0 | The low level of INTn generates an Interrupt request. 0 | 1 | Reserved 1 | 0 | The falling edge of INTn generates asynchronously an interrupt request. 1 | 1 | The rising edge of INTn generates asynchronously an interrupt request. �� Reference 3 : Interrupt Sense Control (B) [ISCn1 | ISCn0 | Description ] 0 | 0 | The low level of INTn generates an Interrupt request. 0 | 1 | Any logical change on INTn generates an interrupt request. 1 | 0 | The falling edge of INTn generates asynchronously an interrupt request. 1 | 1 | The rising edge of INTn generates asynchronously an interrupt request. ***/ | cs |
//SerialSet.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | #ifndef _SERIAL_COMMUNICATION_SET_ #define _SERIAL_COMMUNICATION_SET_ #include <avr/io.h> /*** Serial Port Setting ***/ // USART0 (PE0 - RXD, PE1 - TXD) void SerialOpen(long BaudRate) { UBRR0H = 0; switch(BaudRate) { case 115200: UBRR0L = 8; break; case 57600: UBRR0L = 16; break; case 38400: UBRR0L = 25; break; case 19200: UBRR0L = 51; break; case 14400: UBRR0L = 68; break; case 9600: UBRR0L = 103; break; // Default 57600 default: UBRR0L = 16; break; } UCSR0A = 0x00; UCSR0B = 0x18; UCSR0C = 0x06; // 8 bit } /*** Function for sending 1 byte ***/ void SendByte(char data) { while((UCSR0A & 0x20) == 0x00); UDR0 = data; } /*** Function for sending line ***/ void SendLine(char *string) { while(*string != '\0') { SendByte(*string); string++; } } #endif | cs |
// main
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | #define F_CPU 16000000 #include <avr/io.h> #include <avr/interrupt.h> #include <util/delay.h> #include <stdio.h> #include "RegSet.h" #include "SerialSet.h" #include "ControlSet.h" unsigned int tick_0 = 0; unsigned int pulse_end_0 = 0; unsigned int tick_1 = 0; unsigned int pulse_end_1 = 0; unsigned int tick_2 = 0; unsigned int pulse_end_2 = 0; /*** Timer Interrupt ***/ ISR (TIMER0_COMP_vect) { tick_0++; tick_1++; tick_2++; } /*** External Interrupt (INT0) ***/ ISR(INT0_vect) { unsigned int pulse_tick = 0; pulse_tick = tick_0; if ((EICRA & 0b00000011) == 0b00000011) { cbi(EICRA,0); tick_0 = 0; } else { sbi(EICRA,0); pulse_end_0 = pulse_tick; } } ISR(INT2_vect){ unsigned int pulse_tick = 0; pulse_tick = tick_1; if ((EICRA & 0b00110000) == 0b00110000) { cbi(EICRA,4); tick_1 = 0; } else { sbi(EICRA,4); pulse_end_1 = pulse_tick; } } ISR(INT6_vect){ unsigned int pulse_tick = 0; pulse_tick = tick_2; if ((EICRB & 0b00110000) == 0b00110000) { cbi(EICRB,4); tick_2 = 0; } else { sbi(EICRB,4); pulse_end_2 = pulse_tick; } } int main(void) { PortInit(); TimerInit(); ExtInit(); SerialOpen(115200); _delay_us(20); // for System Stability. int pulse0 =0; int pulse1 =0; int pulse2 =0; sei(); while(1) { SendSignal_0(); for (int i =0; i<10;i++){ pulse0 += pulse_end_0; } pulse0/=10; // 10회 평균값 pulse0 -=8; // calibration _delay_ms(10); SendSignal_1(); for (int i =0; i<10;i++){ pulse1 += pulse_end_1; } pulse1/=10; // 10회 평균값 _delay_ms(10); SendSignal_2(); for (int i=0;i<10;i++){ pulse2 += pulse_end_2; } pulse2/=10; // 10회 평균값 pulse2 -=6; // calibration char str[20]; sprintf(str,"%u,%u,%u\r\n",pulse0,pulse1,pulse2); SendLine(str); _delay_ms(50); } } | cs |
반응형
'Project > j-kit-128-1실습' 카테고리의 다른 글
[j-kit-128] jkit 128 기능구현하기 (0) | 2018.12.10 |
---|---|
Sonar_GPS - C#Window Form (0) | 2018.10.21 |
Serial 통신_ 문자열 전송 (0) | 2018.10.01 |
Serial 통신_Uart0_문자 1개 (0) | 2018.10.01 |
FND_Display with Timer/Counter (0) | 2018.10.01 |