-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutil.c
More file actions
executable file
·232 lines (201 loc) · 4.65 KB
/
Copy pathutil.c
File metadata and controls
executable file
·232 lines (201 loc) · 4.65 KB
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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
/**
* @file util.c
* @brief utility functions for the Atmel platform
*
* For an overview of how timer based interrupts work, see
* page 111 and 133-137 of the Atmel Mega128 User Guide
*
* @author Zhao Zhang & Chad Nelson
* @date 06/26/2012
*/
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include "lcd.h"
#include <math.h>
/// period of the fast PWM for sonar sensor
#define pulse_period 43000
// Global used for interrupt driven delay functions
volatile unsigned int timer2_tick;
void timer2_start(char unit);
void timer2_stop();
/**
* Blocks for a specified number of milliseconds
* @author Zhao Zhang & Chad Nelson
* @date 06/26/2012
* @param time_val number of milliseconds to wait
*/
void wait_ms(unsigned int time_val)
{
//Seting OC value for time requested
OCR2=250; //Clock is 16 MHz. At a prescaler of 64, 250 timer ticks = 1ms.
timer2_tick=0;
timer2_start(0);
//Waiting for time
while(timer2_tick < time_val);
timer2_stop();
}
/**
* Start timer2
* @author Zhao Zhang & Chad Nelson
* @date 06/26/2012
* @param unit determines fast or slow
*/
void timer2_start(char unit)
{
timer2_tick=0;
if ( unit == 0 ) { //unit = 0 is for slow
TCCR2=0b00001011; //WGM:CTC, COM:OC2 disconnected,pre_scaler = 64
TIMSK|=0b10000000; //Enabling O.C. Interrupt for Timer2
}
if (unit == 1) { //unit = 1 is for fast
TCCR2=0b00001001; //WGM:CTC, COM:OC2 disconnected,pre_scaler = 1
TIMSK|=0b10000000; //Enabling O.C. Interrupt for Timer2
}
sei();
}
/**
* Stop timer2
* @author Zhao Zhang & Chad Nelson
* @date 06/26/2012
*/
void timer2_stop()
{
TIMSK&=~0b10000000; //Disabling O.C. Interrupt for Timer2
TCCR2&=0b01111111; //Clearing O.C. settings
}
// Interrupt handler (runs every 1 ms)
ISR (TIMER2_COMP_vect)
{
timer2_tick++;
}
/**
* This function moves the servo to a fixed degree.
* @author Yuixiang Chen
* @date 4/12/2015
* @param degree fixed degree that servo moves to
*/
void move_servo(double degree)
{
degree = 180 - degree;
unsigned int pulse_width = round(-(degree / 180.0) * 3250 + 4300);
OCR3B = pulse_width - 1;
wait_ms(20);
}
/**
* This function initializes fast PWM registers to control the servo.
* @author Yuixiang Chen
* @date 4/12/2015
*/
void servo_init(void)
{
TCCR3A = 0x23;
TCCR3B = 0x1A;
OCR3A = pulse_period - 1;
OCR3B = 2700;
DDRE = 0x10;
}
/**
* This function sends the sonar pulse
* @author Yuixiang Chen
* @date 4/12/2015
*/
void send_pulse()
{
//Disable IC Interrupt
TIMSK &= 0;
//Config PD4 to output
DDRD |= 0x10;
//Set signal to high
PORTD |= 0x10;
wait_ms(1);
//Set signal to low
PORTD &= 0XEF;
//Config PD4 to input
DDRD &= 0XEF;
//Clear IC Flag
TIFR &= 0xDF;
//Enable IC Interrupt
TIMSK |= 0x24;
}
/**
* This function initializes the input capture registers for sonar.
* @author Yuixiang Chen
* @date 4/12/2015
*/
void sonar_init(void)
{
TCCR1A = 0;
TCCR1B = 0xC2;
TCCR1C = 0;
TIMSK = 0x24;
}
/**
* This function initializes the ADC registers for reading the IR sensor.
* @author Yuixiang Chen
* @date 4/12/2015
*/
void IR_init()
{
ADMUX |= (0b01000010);
}
/**
* This function reads the average of 5 ADC values.
* @author Yuixiang Chen
* @date 4/12/2015
* @return returns the average ADC value over 5 reads
*/
double IR_read()
{
int sum = 0;
int avg = 0;
ADCSRA |= 0xC7;
for (int i = 0; i < 5; i++)
{
while((ADCSRA & 0b01000000) == 0b01000000)
;
sum += ADC;
}
avg = sum/5;
double dist = 34272.0 * pow(avg, -1.376);
return dist;
}
/**
* This function initializes the USART registers for transmitting
* and receiving information through serial communication.
*
* @author Yuixiang Chen
* @date 4/12/2015
* @param ubrr The calculated baud rate
*/
void USART_Init(unsigned int ubrr)
{
UBRR0H = (unsigned char) (ubrr>>8);
UBRR0L = (unsigned char) ubrr;
UCSR0B = (1<<RXEN0) | (1 << TXEN0);
UCSR0C = (1<<USBS0)|(3 << UCSZ00);
UCSR0A = (1 << U2X0);
}
/**
* This function receives one byte of data.
* @author Yuixiang Chen
* @date 4/12/2015
* @return the received byte of data
*/
unsigned char USART_Receive(void)
{
while(!(UCSR0A & (1 << RXC0)));
return UDR0;
}
/**
* This function transmitts one byte of data
* @author Yuixiang Chen
* @date 4/12/2015
* @param data The byte of data being transmitted
*/
void USART_Transmit(unsigned char data)
{
while(!(UCSR0A & (1 << UDRE0)))
;
UDR0 = data;
}