Exam 2 2010 spring - 
...

Info iconThis preview shows page 1. Sign up to view the full content.

View Full Document Right Arrow Icon
This is the end of the preview. Sign up to access the rest of the document.

Unformatted text preview: 
 Section
1
‐
M,
Th
10am‐12:50pm
 Section
2
‐
M,
Th
1‐3:50pm
 Section
3
‐
Tu,
F
10am‐12:50am
 Section
4‐
Tu,
F
1‐3:50pm
 Name:____SOLUTION________________________________
 
 
 
 Section
#:
 
 Professor:
 
 Grading
TA:
 
 Side:
 ______________________________
 
 ______________________________
 
 ______________________________
 
 A‐left
or
B‐right
(Circle
One)
 Laboratory
Introduction
to
Embedded
Control
 Exam
#2
–
Spring
2010
 90
minutes
(3
hours
total
for
both
parts)
 Open
Book,
Open
Notes,
Calculator
but
No
Computer
 and
No
Sharing
Material
 
 Make
 sure
 you
 include
 comments
 with
 all
 your
 code
 statements.
 
 It
 is
 possible
 to
 receive
some
partial
credit
for
correct
comments.
 
 Question
 1
a

 1
b
 1
c
 1
d
 1
e
 1 
 f
 1
g 
 2
a 
 2
b 
 2
c
 TOTAL
 Max
Points
 4
 4
 7
 3
 12
 3
 6
 5
 4
 2
 50
 Earned
Points
 
 
 
 
 
 
 
 
 
 
 
 Grader
 
 
 
 
 
 
 
 
 
 
 
 
 1
 
 Problem
#1
 Name:____SOLUTION________________________________
 Your
employer,
Ford,
has
asked
you
to
build
an
automated
parallel
parking
system
 for
 their
 next
 car
 model.
 
 The
 parking
 system
 will
 allow
 the
 driver
 to
 pull
 up
 alongside
 a
 parked
 stationary
 car,
 and
 tell
 the
 vehicle
 to
 navigate
 itself
 and
 park
 behind
 that
 stationary
 car.
 
 The
 parking
 system
 will
 also
 be
 able
 to
 park
 between
 two
stationary
park
cards,
provided
there
is
adequate
space
between
them
for
the
 driver’s
vehicle
to
fit.
 
 The
 steering
 motor
 is
 controlled
 by
 CEX1
 &
 the
 drive
 motor
 by
 CEX2.
 
 All
 three
 rangers
are
on
the
SMB
with
the
addresses
shown
in
the
diagram.
 (Note:
The
same
 EVB
pin
may
occur
more
than
once.)
 
 
 
 C8051
Bus
connections.
 
 
 
 Ultrasonic
Rangers’
position
on
car.
 
 2
 
 Name:____SOLUTION________________________________
 a) Fill
in
the
blanks
in
the
EVB
Connector
diagram
above
with
the
EVB
pin
numbers
 for
CEX1,
CEX2,
SDA,
SCL,
 and
P1.5.

Assume
the
crossbar
value
is
0x23.

Explain
 what
additional
circuit
components
need
to
be
added
to
the
SDA
and
SCL
lines
 for
 them
 to
 function
 correctly.
 Draw
 a
 circuit
 diagram
 below.
 Include
 all
 devices/components
connected
to
the
SMB
bus.
 
 Must
add
1.8k
pull‐up
resistor
on
SMB
clock
and
data
lines
to
+5V.
 
 
 b) Write
 a
 port
 initialization
 function
 to
 enable
 the
 ports
 (including
 the
 analog
 input)
 and
 Crossbar.
 Do
 not
 initialize
 any
 system
 components
 that
 aren’t
 necessary.
 
 Do
 not
 modify
 port
 pins
 that
 your
 system
 won’t
 be
 using.
 Use
 hex
 values.
 
 
 void
Port_Init()
 {
 
 
 XBR0
=
0x23;
 
 P1MDOUT
&=
~0x20;



//or
0xDF



P1.5
for
input
 
 P1MDIN
&=
~0x20;







//or
0xDF



P1.5
for
analog
input
 
 P1
|=
0x20;























//P1.5
high
impedance
 
 P1MDOUT
|=
0x01;







//P1.0
output
for
CEX2
 
 P0MDOUT
|=
0x80;







//P0.7
output
for
CEX1
 
 
 
 
 
 
 
 
 
 
 }
 
 
 
 3
 
 Name:____SOLUTION________________________________
 
 c) Write
 a
 PCA
 initialization
 function
 that
 sets
 the
 count
 mode,
 enables
 the
 PCA,
 enables
the
PCA
counter,
and
enables
the
global
and
PCA
interrupts.
The
Capture
 Compare
Module
that
is
used
works
as
a
16‐bit
comparator
in
PWM
mode.

Note
 that
it
must
be
consistent
with
your
crossbar
configuration
in
(b).

Also,
define
 the
 pulse
 widths
 for
 driving
 forward
 and
 in
 reverse,
 and
 centering
 the
 wheels
 and
turning
them
left
and
right.

The
pulsewidths
for
both
the
steering
and
drive
 motors
are
summarized
in
the
table
below.

 The
 pulses
 must
 be
 sent
 every
 4ms.
 
 Select
 a
 clock
 divide
 for
 the
 fastest
 frequency
that
will
still
be
capable
of
a
4ms
period
with
the
16‐bit
counter.
 
 Min
PW
(left
or
reverse)
 Steering
Motor
 1.28ms
 Neutral
PW
 Max
PW
(right
or
forward)
 1.54ms
 1.80ms
 Drive
Motor
 0.95ms
 1.11ms
 1.27ms
 
 4 //globally
defined
variables
 22118400 ⋅ 65536 = 11.851852 1.80 int
PW_forward
 =
7023;
 11.851852 ⋅ 65536 = 9953 int
PW_neutral
 =
6138;
 1.54 11.851852 ⋅ 65536 = 8516 int
PW_reverse
 =
5253;
 1.28 int
PW_right
 =
__9953___________;
 11.851852 ⋅ 65536 = 7079 4.0 int
PW_center
 =
__8516___________;
 65536 − 22118 = 43418 11.851852 ⋅ 65536 = 22118 int
PW_left
 =
__7079___________;
 
 int
PCA_start
 =
__43418__________;

//PCA

count
start
value,
used
in
setting
PW
period
 
 void
PCA_Init(void)
 € {
 
 
 PCA0MD
=
0x83;









//SYSCLK/4,
enable
CF
intr.,
suspend
on
idle
 
 PCA0CPM1
=
0xC2;




//16‐bit,
enable
compar.,
enable
PWM
 
 PCA0CPM2
=
0xC2;




//16‐bit,
enable
compar.,
enable
PWM
 
 EIE1
|=
0x08;















//enable
interrupts
 
 PCA0CN
|=
0x40;








//enable
PCA
 
 EA
=
1;



























//enable
all
interrupts
 
 
 
 
 
 
 }
 Assume
you
have
a
PCA
ISR,
PCA_ISR(void),
that
loads
the
PCA0
counter
with
the
 value
PCA_start
and
increments
3
global
variables:
 nCount++
every
10ms
 nRange++
every
100ms
 nSecond++
every
1000ms
 
 All
other
details
in
the
ISR
are
properly
handled.
 
 
 
 Note
 that
 these
 ultrasonic
 rangers
 are
 slightly
 different
 version
 rangers
 than
 were
used
in
class.

They
should
not
be
read
more
frequently
than
every
100ms.

 They
 have
 a
 built‐in
 “auto‐ping”
 so
 a
 separate
 operation
 to
 ping
 them
 isn’t
 needed.

The
data
registers
are
also
different
and
measurements
are
only
8
bits
 long.
 
 
 4
 
 
 Name:____SOLUTION________________________________
 d) Given
the
information
above,
write
a
Read_Ranger
function
to
return
the
result
 from
any
of
the
three
rangers.
The
address
of
the
 ranger
should
be
passed
into
 the
 function.
 
 The
 value
 returned
 from
 the
 ranger
 is
 in
 inches
 instead
 of
 centimeters
 when
a
single
byte
is
read
from
register
5.
 
You
may
use
any
of
 the
provided
library
functions
listed
on
the
last
page.
 
 unsigned
char
Read_Ranger(unsigned
char
rangerAddress)
 {
 
 
 unsigned
char
range,
Data[2];




//or
Data[1]
 
 
 i2c_read_data(rangerAddress,
5,
Data,
1);

//read
1
byte
start
at
reg.
5
 
 range
=
Data[0];










//not
really
necessary
 
 return
range;















//or
return
Data[0]
 
 
 }
 
 e) Write
a
function
called
Park_Car()
which
will
perform
only
the
first
steps
of
the
 procedure
 necessary
 to
 park
 the
 car.
 
 The
 diagram
 shows
 all
 the
 steps
 for
 parking
the
car.
Note
that
you’re
only
responsible
for
parking
on
the
right
hand
 side
of
 the
curb.

The
solid
rectangles
are
two
stationary
cars
you
are
trying
to
 park
between.
The
dotted
rectangle
is
your
car.
 
 1.09 ms 11.851852 ms ⋅ 65536 = 6027 € 
 Your
 code
 should
 perform
 the
 actions
 indicated
 in
 the
 figure
 by
 following
 the
 following
procedure:
 Step
1:
 a) While
 in
 neutral,
 determine
 the
 sideways
 distance
 from
 your
 vehicle
 to
 the
 front
 vehicle.
 b) Turn
the
wheels
to
the
right
at
an
angle
determined
by
the
distance
from
the
front
 vehicle.
 i. The
 wheels
 turn
 maximum
 right
 (30
 degrees)
 if
 the
 car
 is
 18
 inches
 or
 more
from
the
front
vehicle.
 ii. The
wheels
turn
half
the
maximum
(15
degrees)
if
the
car
is
6
inches
from
 the
front
vehicle.
 iii. The
 wheel
 angles
 will
 scale
 linearly
 from
 15‐30
 degrees
 if
 the
 car
 is
 between
6
and
18
inches
from
the
front
vehicle.
 iv. If
your
vehicle
is
closer
than
6
inches
to
the
front
vehicle,
your
car
should
 not
move.

(The
function
should
abort
with
a
“return;”
statement.)
 Step
2:
 a) Drive
in
reverse
for
2
seconds
at
the
speed
determined
by
a
pulsewidth
of
1.09ms.
 Step
3:
 a) Straighten
the
front
wheels.
 b) Continue
 to
 drive
 slowly
 in
 reverse,
 pulsewidth
 of
 1.09
 ms,
 until
 the
 side
 sensor
 detects
a
distance
of
24
inches
from
the
curb.
 Step
4:
 a) Turn
the
wheels
to
the
maximum
left.
 b) Continue
to
drive
in
reverse,
pulsewidth
of
1.09
ms,
until
the
rear
sensor
detects
a
 distance
of
8
inches
from
the
rear
vehicle.
 Step
5:
 a) Put
the
car
in
neutral
(not
moving).
 
 5
 
 Name:____SOLUTION________________________________
 Do
 not
 worry
 about
 centering
 your
 car
 between
 the
 two
 parked
 cars.
 
 Also
 assume
 the
 driver
 needs
 to
 put
 the
 car
 in
 position
 1
 prior
 to
 starting
 the
 automatic
parking
routine.

The
routine
is
designed
to
function
when
the
car
is
 more
 than
 6
 inches
 from
 the
 front
 vehicle.
 
 Note
 that
 this
 is
 an
 oversimplified
 procedure
that
will
have
many
problems
in
reality.
 
 void
Park_Car(void)
 {
 //STEP
1
 
 unsigned
char
range;
 
 long
steering_pw;
 
 
 range
=

Read_Ranger(0xA0);
 
 if
(range
<
6)
return;
 
 else
if
(range
>18)
steering_pw
=
PW_right
 //else:



scale
x
15
deg
+
15
deg,


scale
goes
from
0‐>1
as
range
goes
from
6‐>18
 //(range‐6)/12
x
(PW_right‐PW_center)/2
+
(PW_right‐PW_center)/2
+
PW_center
 //(range‐6)
x
(PW_right‐PW_center)/24
+
(PW_right+PW_center)/2
 
 else
steering_pw
=
(range‐6)*(PW_right–PW_center)/24
+
(PW_right+PW_center)/2;
 
 PCA0CPL1
=
0xFFFF
–
steering_pw;
 
 PCA0CPH1
=
(0xFFFF
–
steering_pw)
>>
8;




//set
steering
 
 //STEP
2
 
 PCA0CPL2
=
0xFFFF
–
6027;
 
 PCA0CPH2
=
(0xFFFF
–
6027)
>>
8;




//set
speed
to
1.09ms
 
 nSecond
=
0;
 
 while
(nSecond
<
2);
































//wait
2
seconds
 
 //STEP
3
 
 PCA0CPL1
=
0xFFFF
–
PW_center;
 
 PCA0CPH1
=
(0xFFFF
–
PW_center)
>>
8;




//set
steering
straight
 
 while
(Read_Ranger(0xA0)
>
24);


















//drive
until
24”
from
curb
 
 //STEP
4
 
 PCA0CPL1
=
0xFFFF
–
PW_left;
 
 PCA0CPH1
=
(0xFFFF
–
PW_left)
>>
8;









//set
steering
to
left
limit
 
 while
(Read_ranger(0xC0)
>
8);





















//
drive
until
8”
from
rear
car
 

 //STEP
5
 
 PCA0CPL2
=
0xFFFF
–
PW_neutral;
 
 PCA0CPH2
=
(0xFFFF
–
PW_neutral)
>>
8;


//set
speed
to
neutral
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }
 
 
 6
 
 Name:____SOLUTION________________________________
 f) The
 collision
 detector
 outputs
 a
 voltage
 if
 there
 has
 been
 pressure
 applied
 on
 either
 the
 front
 or
 rear
 bumper
 (if
 you
 hit
 a
 vehicle).
 
 If
 P1.5
 reads
 a
 voltage
 higher
 than
 1.4V,
 a
 collision
 has
 occurred.
 
 Write
 a
 function
 called
 UhOh
 that
 reads
the
voltage
at
P1.5
and
returns
a
1
if
there
is
a
collision,
and
a
0
otherwise.

 Assume
 a
 unsigned
 char
 read_AD_input(void)
 function
 exists
 which
 returns
 the
 ADC
 value
 of
 P1.5
 and
 the
 ADC
 has
 been
 properly
 initialized
 by
 AD_init(void)
 with
a
gain
of
1
on
the
analog

converter
and
using
a
2.4V
reference.
 
 int
UhOh(void)

 {
 1.4 Volts 2.4 Volts ⋅ 256 = 149 
 
 
 unsigned
char
volts;
 
 
 volts
=
read_AD_input();
 € 
 if
(volts>149)
return
1;




//149
corresponds
to
1.4V
 
 else
return
0;
 
 
 
 
 
 
 
 
 
 
 }
 
 g) Write
 a
 main
 function
 that
 calls
 the
 proper
 A/D,
 PCA,
 Port
 and
 any
 other
 required
initialization
functions.

The
main
function
should
also
call
 Park_Car()
 whenever
the
global
variable,
park_my_car,
is
1
(it
will
be
set
by
an
interrupt
not
 shown).
 
 Check
 UhOh()
 after
 Park_Car()
 and
 print
 the
 message
 “Collision
 Detected”
if
a
collision
occurred.
 
 char
park_my_car
=
0;
 
 void
main()
 {
 
 
 Sys_init();
 
 putchar(‘
‘);
 
 Port_Init();
 
 AD_init();
 
 PCA_Init();
 
 SMB_Init();
 

 
 while
(1)
 
 {
 

 while(~park_my_car);
 

 Park_Car();
 

 park_my_car
=
0;
 

 if
(UhOh())
printf(“\n
Collosion
Detected
\r”);
 
 }
 
 
 
 
 }
 
 
 7
 
 Problem
#2
 Name:____SOLUTION________________________________
 a)
 Write
a
function
that
can
upgrade
and
test
the
Rangers.
 Table 1: Ranger for car Register 0 5 6 7 Reading will return: Software version number Distance to object in inches Distance to object in meters Error code for servicing Writing the value will cause: 1: self-calibration 2: starts firmware upgrade No effect No effect 1: starts self test 
 Assume
that
the
system
has
been
initialized
as
in
problem
#1,
that
PCA0
is
running,
and
 that
PCA0
interrupts
are
enabled.

Write
a
function
that
writes
to
the
ranger
to
perform
a
 firmware
 upgrade
 on
 Ranger
 1,
 then
 starts
 a
 self‐test
 of
 the
 ranger
 to
 make
 sure
 the
 upgrade
 went
 smoothly.
 The
 function
 must
 wait
 for
 70ms
 for
 the
 upgrade
 to
 complete,
 40ms
 for
 the
 self‐test
 to
 complete,
 and
 then
 read
 the
 error
 code
 from
 the
 function.

 Return
that
error
code.

Use
PCA0
interrupts
to
keep
track
of
time.
 You
might
need
to
 add
a
global
 variable
(problem
#1,
part
g).

You
may
use
any
of
the
count
variables
 defined
in
problem
#1,
part
c.
 unsigned
char
ranger_upgrade_test
(unsigned
char
rangerAddress)
 {
 
 
 
 unsigned
char
Data[2];











//or
Data[1]
 
 Data[0]
=
2;
 
 i2c_write_data(0xA0,
0,
Data,
1);

//write
2
to
register
0
 
 nCount
=
0;
 
 while
(nCount<7);

 
 //wait
70ms
 
 Data[0]
=
1;
 
 i2c_write_data(0xA0,
7,
Data,
1);

//write
1
to
register
7
 
 nCount
=
0;
 
 while
(nCount<4);

 
 //wait
40ms
 
 i2c_read_data(0xA0,
7,
Data,
1);

//read
1
byte
from
register
7
 
 return
Data[0]
 
 
 
 }
 b)
 Using
 I2C,
 write
 a
 function
 which
 writes
 one
 byte
 with
 a
 value
 of
 22
 decimal
 to
 register
6
at
address
0xF0.

Then,
read
back
4
bytes
starting
from
the
same
register
 and
return
them
as
a
long
integer.

As
in
class
examples,
the
first
register
is
the
high
 byte
and
the
last
is
the
low
byte.
 long
int
i2c_function(void)
 {
 
 long
int
value;
 unsigned
char
Data[4];
 
 Data[0]
=
22;
 
 i2c_write_data(0xF0,
6,
Data,
1);
 
 i2c_read_data(0xF0,
6,
Data,
4);
 
 value
=
(Data[0]<<24)
||
(Data[1]<<16)
||
(Data[2]<<8)
||
(Data[3]);
 
 OR
 value
=
(Data[0]*16777216)
+
(Data[1]*65536)
+
(Data[2]*256)
+
(Data[3]);
 
 
 return
value;
 }
 c)
Configure
the
crossbar
to
allow
the
use
of
SPI,
SMB0,
and
CEX0
only.
 bits
543
=
001
=>
CEX0
 
 bits
210
=
011
=>
no
UART,
SPI,
SMB
 XBR0=

___0x0B_______


;
 
 bits
7‐0
=
0000
1011
 8
 
 
 Name:____SOLUTION________________________________
 Functions
available
in
i2c.h
 extern
void
delay_time
(unsigned
long
time_end);
 extern
void
lcd_print(const
char
*fmt,
...);
 
 extern
void
lcd_clear(void);
 
 unsigned
char
i2c_read(void);
 unsigned
char
i2c_stop_and_read(void);
 void
i2c_write(unsigned
char
output_data);
 void
i2c_write_and_stop(unsigned
char
output_data);
 void
i2c_write_data(unsigned
char
addr,
unsigned
char
start_reg,
unsigned
char
 *buffer,
unsigned
char
num_bytes);
 void
i2c_read_data(unsigned
char
addr,
unsigned
char
start_reg,
unsigned
char
 *buffer,
unsigned
char
num_bytes);
 unsigned
char
i2c_read_and_stop(void);
 void
i2c_start(void);
 
 
 
 
 
 //Delay
function
 //Print
to
LCD
screen
 //Clear
LCD
screen
 Other
Functions
available
 char
read_AD_input(void);
 AD_init(void);
 PCA_ISR(void);
 SMB_Init(void);
 
 
 9
 ...
View Full Document

This note was uploaded on 04/08/2011 for the course ENGR 2350 taught by Professor Fukanari during the Spring '08 term at Rensselaer Polytechnic Institute.

Ask a homework question - tutors are online