반응형

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


//



Sonar_GPS.zip


// 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

+ Recent posts