-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathping.c
140 lines (92 loc) · 3.08 KB
/
ping.c
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#include "ping.h"
#include "Timer.h"
volatile unsigned long START_TIME = 0;
volatile int edge = 1;
volatile unsigned long END_TIME = 0;
volatile unsigned long delta = 0;
volatile enum{LOW, HIGH, DONE} STATE = LOW; // State of ping echo pulse
int counter = 0;
void ping_init (void){
//Initialize GPIO port B
SYSCTL_RCGCGPIO_R |= 0x02;
while((SYSCTL_PRGPIO_R & 0x02) == 0) {}
GPIO_PORTB_AFSEL_R |= 0b1000;//
GPIO_PORTB_PCTL_R |= 0x7000;//
GPIO_PORTB_DEN_R |= 0b1000;//
// turn timer on
SYSCTL_RCGCTIMER_R |= 0b1000;
while((SYSCTL_PRTIMER_R) & 0b1000 == 0){}
TIMER3_CTL_R &= ~0x100;
TIMER3_CFG_R |= 0x4;
// count-down
TIMER3_TBMR_R &= ~0x08;
TIMER3_TBMR_R |= 0x7;
TIMER3_TBPR_R |= 0xFF;
TIMER3_TBILR_R |= 0xFFFF;
// enable interrupt mask
TIMER3_IMR_R |= 0x400;
// count both edges
TIMER3_CTL_R |= 0xC00;
TIMER3_ICR_R |= 0x400;
//Enable interrupts for timer 3
NVIC_EN1_R |= 0x10;
NVIC_PRI9_R |= 0x20;
IntRegister(INT_TIMER3B, TIMER3B_Handler);
IntMasterEnable();
// Configure and enable the timer
}
void ping_trigger (void){
STATE = LOW;
// Disable timer and disable timer interrupt
TIMER3_CTL_R &= ~0x100;
TIMER3_IMR_R &= ~0x400; //0b 0000 1111 0000 0000
// Disable alternate function (disconnect timer from port pin)
GPIO_PORTB_AFSEL_R &= ~0b1000;
GPIO_PORTB_DIR_R |= 0x8;
GPIO_PORTB_DATA_R &= ~0x8; //reset
// YOUR CODE HERE FOR PING TRIGGER/START PULSE
GPIO_PORTB_DATA_R |= 0x8;
timer_waitMicros(5);//wait
GPIO_PORTB_DATA_R &= ~0x8; //reset
GPIO_PORTB_DIR_R &= ~0x8; // reset
// Clear an interrupt that may have been erroneously triggered
TIMER3_ICR_R |= 0x400;
// Re-enable alternate function, timer interrupt, and timer
GPIO_PORTB_AFSEL_R |= 0b1000;
TIMER3_IMR_R |= 0x400;
TIMER3_CTL_R |= 0x100;
}
void TIMER3B_Handler(void){
if(TIMER3_MIS_R & 0x400){ //check if handler
TIMER3_ICR_R |= 0x400 ;// this should clear interrupt.
if(STATE == LOW){
// start time
START_TIME = TIMER3_TBR_R;
STATE = HIGH;
}
else if(STATE == HIGH){
// end time
END_TIME = TIMER3_TBR_R;
STATE = DONE;
}
}
}
float ping_getDistance (void){
ping_trigger(); // Trigger the ultrasonic sensor
// Wait until both edges of the signal haven't been detected
while (STATE != DONE) {};
// Calculate the time difference between the rising and falling edges
float difference = 0;
int overflow = (END_TIME > START_TIME);
if (START_TIME > END_TIME) {
difference = START_TIME - END_TIME; // No overflow
}
else {
difference = ((unsigned long) overflow << 24) + START_TIME - END_TIME; // Overflow occurred
counter++;
}
// Convert time difference to distance in centimeters
difference = difference / 16000000; // Convert to seconds
difference = (difference / 2) * 343 * 100; // Distance = speed * time
return difference; // Return the calculated distance
}