Professional Documents
Culture Documents
Program
Explanation Manual
kit05.c Version
1.00E Edition
19/06/2006
Japan Micom Car Rally Executive Committee
Program Explanation Manual “kit05.c”
Important Notice
Copyright
*Copyright concerning this manual belongs to the Japan Micom Car Rally Executive Committee.
*This manual is protected by the copyright law and the international copyright agreement.
Prohibited Use
User must not do the following things.
*Selling, advertisement to sell, use, trading, reproduction of this manual for the third party
*Assigning the usage right or approval of this manual to the third party
*Change or remove part or whole of this manual
*Translate this manual without authorization
*Use wherein harm might be caused to life and human body by using the content of this manual
Reprinting, reproduction
Prior approval of Japan Micom Car Rally Executive Committee is necessary for reprinting and reproduction of
this manual.
Liability Restrictions
The information described in this manual is carefully prepared to ensure accuracy. However, Japan Micom Car
Rally Executive Committee does not assume any responsibility, if any damage occurs due to the description
error of this manual.
Other
In this manual the model car controlled by microcomputer is defined as the micom car. The information
contained in this manual represents information at the time of publication of the manual, and Japan Micom Car
Rally Executive Committee is liable to occasionally change this information or specification described in this
manual without prior notice. Refer to the information published on the official homepage
(http://www.mcr.gr.jp/) of Micom Car Rally when manufacturing micon car.
Contact Address
Head Office, Renesas Technology Micom Car Rally Executive Committee
162-0824 Tokyo Shinjukuku, Ageba cho,2-1 Karuko saka, MN Building
TEL (03)-3266-8510
E-mail : official@mcr.gr.jp
- I -
Program Explanation Manual “kit05.c”
- III -
Program Explanation Manual “kit05.c”
1. Outline
This manual explains about Micom car rally kit Vol.3 and drive program kit05.c designed in 2005.
Recently, in the program of the microcomputer, (excluding the cases when timing and the execution speed are
strict), there has been substantial development in the high-level language, especially in C language. It is because
more students learn C language in information process classes, program coded by C language out of hardware can
be used when CPU is replaced, and it is able to perform hardware control better than other languages.
This manual describes how the micom car control program with the development environment moves/controls
CPU and related micom car.
-1-
Program Explanation Manual “kit05.c”
Servo C
B
Sub PortA
board
Port7
CPU board
Left gear
To Servo
A
Driving system
Battry box
Micom car consists of CPU board, sensor board, sensor sub board, motor drive board (Circuit control part) of
control system and right motor, left motor, servo motor of driving system.
SW LED LED
Right motor
Sensor A Sensor B CPU board C Motor drive
board sub board H8/3048F-ONE board Left motor
servo
Black and white of course is read, and it is converted into digital signal of “0" or “1" and
Sensor board
output. Output signal is white: “0", black: “1". 8 sensors are attached.
Output by reversing input signal. Output signal becomes white colour: “1", black colour: “0"
because input signal is signal from sensor. As the output is an open collector output, it is
Sensor sub board
pulled-up in the sub board. Since the signal from sensor board is not very clear, sensor sub
board has implications of wave form shaping and chattering prevention also.
Sensor value is read from port 7, output value of right and left motor and cut angle of servo is
calculated and outputted to motor drive board, connected to port B.
Program is created for finding out how the output value of the motor and the servo is decided
CPU board
from this sensor value.
Port A is not used in standard kit. Therefore, the equipments for tune up such as the
DIPswitch, LED, and the rotary encoders etc. , can be connected.
Weak electric signal from CPU board is converted into strong electric signal to operate the
Motor drive motor. The drive of the servo also uses the power supply for the motor.
board Push switch is connected and the program is created in such that, pushing this switch starts
the micom car. In addition, 2 LED are attached and can be used for debugging.
* Control system (CPU)power supply ...4 pieces of secondary AA batteries (1.2V x 4 nos. =4.8V) are used
*Driving system (motor and servo) power supply ...4 pieces of secondary AA batteries or 4 pieces of alkaline
Battery batteries (1.5V x 4 nos. =6.0V) are used.
ÚCPU power supply shall have the voltage of 5.0V)10%.
-2-
Program Explanation Manual “kit05.c”
In a standard kit, Power supply system is seperated in a control system and drive system and CPU cannot be reset,
regardless of the quantity of the electric current consumed on the motor & servo side.
Power supply configuration of standard kit is as shown in following diagrams.
Right motor
PB
5V
P
A
CPU board Motor drive board
P
7
Left motor
Sensor sub board
5V
It is 5V to the servo.
-3-
Program Explanation Manual “kit05.c”
2.3. Power supply configuration for raising the drive system voltage.
The rotation speed of the motor can be increased by raising voltage of drive system (If no.of batteries are
increased). If 6 batteries are used for motor power supply, the voltage is 7.2V and if 8 batteries are used then the
voltage will become 9.6V. However, more batteries cannot be added, since the maximum number of batteries that
can be used cannot exceed 8. The battery is common for control system as well as drive system. There is no
problem on the motor side even with 9.6V. However since the certified operation voltage for CPU is between
4.5-5.5V, it will get damaged if exceeded. Three terminal regulators are installed and the control system voltage of
CPU is adjusted to a constant of 5.0V.
However, when battery is common (shared), motor etc. consume large amount of current and if the voltage drops
below 4.5V, the CPU gets reset. Care must be taken while resetting the CPU, when the battery is shared.
When parts of "LM350 addition set" are added, common battery's voltage of 6V or more is used and LM2940-5
generates voltage of 5V that is used by the control system of CPU etc. and LM350 generates voltage of 6V used
by the servo.
Right motor
PB
9.6V
P
A Motor drive board
CPU board
P
7 +
LM350 addition set
Left motor
6V to the servo
9.6V is for the
9.6V secondary battery
Sensor board
use. In case of
8 common powers alkaline battery it
Supply batteries becomes 12V.
circuit circuits
5.0V
Control system power supply 6V
LM2940-5 LM350 Servo
Driving system power supply
9.6V
Power supply
8 nos. AA batteries
-4-
Program Explanation Manual “kit05.c”
Truth Table
OUTPUT
INPUT
LEVEL
Light ON LOW
Light
HIGH
OFF
-5-
Program Explanation Manual “kit05.c”
*Circuit
To CPU
board
1.U1 is photo sensor. Light receiving part and oscillation circuit of infrared ray’s emmission LED are combined.
2.Infrared rays emmission LED (LED 2) is connected with 1 pin of U1. The emitted light from LED2 is
received by U1. Output adjustment of infrared rays emmission LED is done by volume VR1.
3.It is 3 pin of U1 which outputs whether or not the light is received. LED (LED1) is connected and it can be
confirmed visually whether it is “0" or “1".
4.When the light of infrared rays emmission LED reaches U1 (The course is white), “0" is output from 3 pin.
LED1 glows because anode side of LED1 is “+" and cathod side is “ –“ .
5.If the infrared rays emmission LED does not reach U1 (The course is a black), “1" is output (Refer to following
no.6 for details). LED1 does not glow because the anode side of LED1 is always “+" and the cathode side
becomes"+".
6.Actually, 3 pin of U1 is open collector output though it has been mentioned that if light does not reach it is “1".
Usually in the digital world, “0"=0V, and “1"=5V. Open collector output is open state except when “0"=0V, and
it is called non-connected state. There cannot be a value which it is neither “0" nor “1" in the digital world.
Therefore, when photo sensor is opened it is made in such a way to become “1" by pull-up resistor (RA11) on
the sensor sub board.
7.Output of 3 pins of U1 becomes “0" when course lights up LED1 in white and becomes “1" output when course
turns off LED1 in black. However, it is reversed by NOT circuit (U11) as it is easy to understand that white="1"
and black="0". While incorporating in CPU white= “1" and black= “0".
-6-
Program Explanation Manual “kit05.c”
*Actual incorporation
b it 0 1 2 3 4 5 6 7
B W W W B B B B
7 6 5 4 3 2 1 0
B B B B W W W B 1
S en so r b o a rd T o di gital va lu e
7 6 5 4 3 2 1 0
1 1 1 1 0 0 0 1 2
(Hexadeci mal no : 0xf1)
In ve rsio n
Se n so r su b
b o ard
7 6 5 4 3 2 1 0
0 0 0 0 1 1 1 0 3
(Hexadeci mal no : 0x0e
C PU Rig ht an d left
b o ard re placem ent
7 6 5 4 3 2 1 0
0 1 1 1 0 0 0 0 4
P o rt7 Po rtA
B: Black
W: White
-7-
Program Explanation Manual “kit05.c”
PortB
Port7 PortA
LED 0
LED 1
Servo SW
M otor
Drive Board
Left Ge ar Right Ge ar
The motor drive board operates the motor according to the instructions of the microcomputer. The signal “turn
motor, stop motor" from the microcomputer is very weak, and even if the motor is directly connected to that signal
wire, there is no response from the motor. This weak signal is converted to signal which induces a large current of
few hundreds to few thousands mA which is necessary for operating the motor.
× ○
Motor
CPU board
M CPU board
Drive Board M
The motor does not turn because the Convert to large current, motor is
signal is weak. activated!
It is OK if voltage is added when motor is to be rotated. If the motor is to be stopped, there is no need to add the
voltage. Then, how can the fine speed adjustment such as intermediate speed or 10%, 20%--etc of the speed be
achieved ? The voltage can be dropped by using the volume. However, the volume which has very large thermal
capacity , is necessary since a large current may flow to the motor. The surplus voltage which is not added to the
motor, is consumed as a large heat radiation on the resistor. Here, repeated ON, OFF operations at high speed
carries out the control as if the intermediate voltage is being outputted. The repeated ON, OFF operations control
the change of ON and OFF ratio under the constant cycle. This is called “Pulse width modulation".
It is abbreviated as PWM control. ON ratio for pulse width is called duty ratio. When the ON width in cycle is
made to 50%, it is called duty ratio 50%. In other words , it is called PWM 50% or simply motor 50%.
-8-
Program Explanation Manual “kit05.c”
Pulse width
Though “PWM" feels somewhat difficult to hear, but manual “Connect", “Disconnect" to the motor and battery
wire is also called PWM. The motor rotates fast when the connected time is long. The motor rotates only a little
when the disconnection time is long. “Connect", “Disconnect" operation can be carried out in just few seconds
in case of humans, but in case of microcomputer, it is carried out within a few milliseconds.
Battery
Motor
OFF ON
Let’s assume that the waveform by which 0V and 5V are output is as shown in the figure below. The longer the
ON time for 1 cycle, the average value becomes larger. If all are made 5V then average is also 5V, this is the
maximum voltage.
What does the the average become if the time of turning on is adjusted to 50% as half of 1 cycle? When average is
taken 5V x 0.5 = 2.5V, the voltage appears to have changed.
Thus when ON time is made 90%, 80%, ---0% of 1 cycle, the average voltage goes on decreasing and becomes 0
in the end.
When this signal is connected to the motor, the rotation speed of the motor can be changed a little, and subtle
speed control is possible. The brightness of LED can be changed by PWM when connected with LED. If CPU is
used, this work can be done in the units of microsecond and milliseconds. A very smooth motor control can be
achieved by this micro or milli order control.
Why is it that the speed of the motor is controlled by pulse width control and not voltage control? Though the
CPU is good at handling the digital values “0" and “1", analog value like xV is difficult. Hence it behaves as
though voltage is controlled by changing width of “0" and “1".This is PWM control.
-9-
Program Explanation Manual “kit05.c”
In the motor drive board (Vol.3), the “normal rotation, reverse and brake" are controlled. Motor control is
possible by changing the volatge added to the terminal of motor as shown in the figure below.
1 2 1 2 1 2
M M M
正転
Normal rotation 逆転
Reverse ブレーキ
Brake
*H Bridge Circuit
The actual method is follows. As shown in the following figure, keeping motor in the center, 4 switches are
fixed in H shape. It is called “H bridge circuit" since H is formed.
Normal rotation, reverse and brake are controlled by turning each of these 4 switches ON/OFF.
10V 10V 10V 10V 10V 10V
M M M
正転
Normal rotation 逆転
Reverse ブレー
Brake キ
*The switch of H bridge circuit is made FET.
FET can flow current when voltage is impose on D to S regardless N or P-channel.
This component which changes into the switch is
done by FET. P-channel FET (2SJ type) is used
for plus side of power supply and N-channel FET
(2SK type) is used for minus side.
P-channel FET passes the current between D-S
(drain source) when VG (gate voltage)< VS
(source voltage)
N-channel FET passes the current between D-S
(drain source) when VG (gate voltage)> VS
(source voltage)
That is to say, either N-channel or P-channel, FET
passes the current when the voltage between D-S
is added.
- 10 -
Program Explanation Manual “kit05.c”
Normal rotation, reverse, brake operations are carried out by changing the voltage added to these 4 FET gates.
0V 10V 10V 0V
0V 10V 10V 0V
Brake1 Brake 2
0V 0V 10V 10V
0V 0V 10V 10V
Care should be taken that the left and right FET should not be turned ON simultaneously. Since it is connected
without any load to GND from 10V, it issimilar to becoming short. It will however, either burn the FET or line.
If the voltage at 4 gates in above figures, is observed, it is seen that voltage added to P-channel FET and
N-channel FET on the right side, P-channel FET and N-channel FET on the left side is common.Hence, the
following circuit was prepared.
A B Operation
0V 0V Brake
0V 10V Reverse
Normal
10V 0V
rotation
0V 0V Brake
*Power supply voltage of 10V for motor or GND
voltage of 0V is applied to G (gate) terminal.
Precaution must be taken as the control signal “0"
and “1" are different from these gate voltage.
FET became very hot when this circuit was actually joined and the PWM waveform was added and operated. Why
was it so? When the signal is input from the gate of FET, and when ON/OFF operation is carried out between the
drain and source , according to the figure on the left “Ideal waveform", the normal rotation and brake seem to
change smoothly because P-channel FET and N-channel FET respond immediately.
However, there is time delay and they do not actually operate at once. This delay is longer when FET is ON->OFF
- 11 -
Program Explanation Manual “kit05.c”
than when OFF->ON. Hence, as per the figure on the right below “actual waveform", the delay is small but, both
FET become ON and becomes the same as the short status.
理想的な波形
Ideal waveform Actual waveform
実際の波形
Normal Normal
モータ Brake
ブレーキ rotation
正転 Brake
ブレーキ モータ Brake
ブレーキ rotation
正転 Brake
ブレーキ
Motor Motor
Gate
ゲート Gate
ゲート
200ns 87ns
PchFET ON PchFET ON
Operation
動作 OFF Operation
動作 OFF
120ns 225ns
NchFET ON NchFET ON
動作
Operation OFF 動作
Operation OFF
ショート
Short-circuit ショー ト
Short-circuit
Duration of the delay time of turning ON to actually starting reaction is called “Turn on delay time", from turing
ON for the first time to becoming actually ON is called “Rise time". Delay from turning off to actually starting the
action is called “Turn off delay time"and from turing OFF for the first time to becoming actually OFF is called
“Fall time".
Time until actually becoming OFF->ON is “turn on delay time + rise time", time until ON->OFF is “turn on delay
time + fall time". The delay time in the above figure to the right is this time. An electrical characteristic of FET is
shown below for the reference.
2SJ530 (P-channel)
OFF->ON is
delayed by 87ns
ON->OFF is
delayed by 200ns
2SK2869(N-channel)
OFF->ON is
delayed by 120ns
ON->OFF is
delayed by 225ns
- 12 -
Program Explanation Manual “kit05.c”
1 4
D 10V
(NchIN) 0V
PchFET ON
Operation OFF
NchFET ON
Operation OFF
The part where this time is delayed is made from integrating circuit. Since there are lots of special books about
integrating circuit, please refer to those.
- 13 -
Program Explanation Manual “kit05.c”
E
A
D
F
A "1"(5V)
"0"
50us 50us
B "1"(5V)
"0"
Integrating
Circuit
C "1"(5V)
=AandB "0"
D "1"(5V)
=AorB "0"
10V
E
(PchIN) 0V
Voltage
10V
Conversion
F
(NchIN) 0V
PchFET ON
動作 OFF
FET
NchFET ON
動作 OFF
出力
Motor 0V 10V 0V
電圧
Free Free
Both are not turned ON.
- 14 -
Program Explanation Manual “kit05.c”
1.When signal from port is “0" then brake, when “1" it is normal rotation.Can change from brake to normal
rotation (A point).
2.The waveform which is delayed by 50us by integrating circuit is output from B point.
3.C point outputs waveform of A and B.
4.D point outputs waveform of A or B.
5.E point outputs, the signal for which the voltage is converted with a digital transistor. 0V-5V signal of C point is
converted into 10V-0V signal.
6.F point similarly converts 0V-5V signal of D point into 10V-0V signal.
7.When signal of A is converted from “0" -> “1", the gate of FET2 becomes 10V->0V and FET2 is turned OFF.
However, due to delay time it gets delayed and becomes OFF. At this point, the motor enters a free state because
FET1 and FET2 are OFF.
8.After changing the signal of A, the gate of FET1 becomes 0V->10V this time becomes OFF after 50us. 10V is
added to the motor and does normal rotation.
1.When signal from A is changed from “1"-> “0", the gate of FET1 is 10V->0V and FET1 is OFF. However, due
to delay time it gets delayed and switches OFF. At this point, the motor enters a free state because FET1 and
FET2 are OFF.
2.The signal of A is changed and 50us later, the gate of FET2 is 0V->10V and the status of FET2 becomes to
ON.
Thus, when operation is selected, a short circuit can be prevented by making the status of both FET and
turning OFF, free.
*Voltage of 10V added to the gate is an example. Actually it is same as power supply volatge (VBAT)
- 15 -
Program Explanation Manual “kit05.c”
The actual circuit is added the circuit for normal rotation/ reverse change, besides integrating circuit and FET
circuit.The following circuit is for left motor. PB1 is terminal which adds PWM, and PB2 changes normal
rotation/ reverse rotation.
FET for left motor
Integrating circuit
- 16 -
Program Explanation Manual “kit05.c”
Ú About Free
To avoid short circuit of PchFET and NchFET, Free is made from integrating circuit. Therefore, it is not
possible carry out Free in the program. Stopping the motor drive board Vol.3 is entirely with brake.
To change Free time, the value of C and R of integrating circuit is changed.
The servo isadded the pulse of timecycle 16[ms], and the angle of the servo is decided by the ON range of the
pulse. As for the relation between the rotating angle of the servo and the pulse range of turning ON, the relation is
as shown in the figure below. However there may be differences depending on the maker and the type of servo.
0
00度
0 0
Left 90
左90度 右Right
90度 90
16m s 16m s 1 6m s
* Cycle is16[ms]
* The center is ON pulse of 1.5ms and change of servo angle of +-900 is every +-0.8ms.
The PWM signal is generated in a reset synchronous PWM mode of the H8 microcomputer, and the servo is
controlled.
Servo out
Up: When power supply is
directly connected
Down: When 3 terminals are used
1.The PWM signal is output from bit 5 of port B. The ON width changes when the program changes the value of
ITU4_BRB.
2.Though the port and 1 pin of servo can be directly connected but, tentatively, OR circuit which remains as a
- 17 -
Program Explanation Manual “kit05.c”
buffer is incorporated. For instance, by mistake when power supply is connected to 1 pin or the noise mixes and
the terminal breaks, and if it is a direct connection, the port of the microcomputer will break and is fatal. If it is
74HC32, it is 1 for 30 ¥ but CPU is very expensive and since it is 14 pins but CPU is 100 pins, it can be easily
exchanged.
3.2 pin is power supply for the servo. When power supply for the motor is less than 4 batteries, the upper part of
JP1 is bypassed and connects directly with the power supply. In case of more voltage, the ratings of the servo
are exceeded; the voltage is adjusted to constant 6V with 3 terminal regulators which can throw 3A current
LM350. JP1 is short to the down side.
Actually, the resistance of 1k ohm is connected by reducing the battery usage and the current limit of the port.
Current = (Power supply voltage - voltage added to LED)/ resistance
= (5-2.8)/1000=2.2 [mA]
ON! OFF
No current
flow!!
0V 5V
If “0" is output to PB7, the cathode side of If “1" is output to PB7, the cathode side of
LED becomes 0V, the current flows, and LED LED becomes 5V, the potential difference at
glows. both ends of LED becomes 0V, no current
flows and LED does not glow.
- 18 -
Program Explanation Manual “kit05.c”
OFF ON
"1" "0"
The switch is pulled up by 10k ohm If the switch is not pushed, “1" is When the switch is pushed, “0" is
and is connected with bit 0 of port input to PB0 through the pull-up input to PB0 through GND.
B. resistor.
- 19 -
Program Explanation Manual “kit05.c”
- 20 -
Program Explanation Manual “kit05.c”
83 : speed( 0, 0 );
84 : pattern = 0;
85 : cnt1 = 0;
86 :
87 : while( 1 ) {
88 : switch( pattern ) {
89 :
90 : /*****************************************************************
91 : About pattern
92 : 0: Switch input wait
93 : 1: Wait for 1 second after the switch is pressed.
94 : 11: Usual trace
95 : 12: Check for the end of long turn to the right
96 : 13: Check for the end of long turn to the left
97 : 21: Processing when first crossline is detected
98 : 22: Skip second crossline
99 : 23: Trace 1 after crossline
100 : 24: Trace 2 after crossline, crank detection
101 : 31: Left crank Clear process Waits till it stabilizes
102 : 32: Left crank clear process Check for end of turn
103 : 41: Right crank clear process Waits till it stabilizes
104 : 42: Right crank clear process Check for end of turn
105 : *****************************************************************/
106 :
107 : case 0:
108 : /* Switch input waiting */
109 : if( pushsw_get() ) {
110 : pattern = 1;
111 : cnt1 = 0;
112 : break;
113 : }
114 : if( cnt1 < 100 ) { /* LED blinking process */
115 : led_out( 0x1 );
116 : } else if( cnt1 < 200 ) {
117 : led_out( 0x2 );
118 : } else {
119 : cnt1 = 0;
120 : }
121 : break;
122 :
123 : case 1:
124 : /* 1 second waiting after the switch is pushed */
125 : if( cnt1 < 500 ) {
126 : /* 1.0 seconds starting ago LED1:"OFF" , LED0:"ON" */
127 : led_out( 0x1 );
128 : } else if( cnt1 < 1000 ) {
129 : /* 0.5 seconds starting ago LED1:"ON" , LED0:"OFF" */
130 : led_out( 0x2 );
131 : } else {
132 : /* Start!! */
133 : led_out( 0x0 );
134 : pattern = 11;
135 : cnt1 = 0;
136 : }
137 : break;
138 :
139 : case 11:
140 : /* Usual trace */
141 : if( check_crossline() ) { /* Crossline Check */
142 : pattern = 21;
143 : break;
144 : }
145 : switch( sensor_inp(MASK3_3) ) {
146 : case 0x00:
147 : /* Center -> Straight */
148 : handle( 0 );
149 : speed( 100 ,100 );
150 : break;
151 :
152 : case 0x04:
153 : /* Slightly left inclined -> Slight turn to the right */
154 : handle( 5 );
155 : speed( 100 ,100 );
156 : break;
157 :
158 : case 0x06:
159 : /* Little left inclined -> Small turn to the right */
160 : handle( 10 );
161 : speed( 80 ,69 );
162 : break;
163 :
164 : case 0x07:
165 : /* Left inclined from the middle -> Middle turn to the right */
166 : handle( 15 );
167 : speed( 50 ,40 );
168 : break;
169 :
170 : case 0x03:
171 : /* Large inclined to the left -> Large turn to the right */
172 : handle( 25 );
173 : speed( 30 ,21 );
- 21 -
Program Explanation Manual “kit05.c”
- 22 -
Program Explanation Manual “kit05.c”
- 23 -
Program Explanation Manual “kit05.c”
356 :
357 : default:
358 : /* When the pattern is not applied to any case, return to waiting state */
359 : pattern = 0;
360 : break;
361 : }
362 : }
363 : }
364 :
365 : /************************************************************************/
366 : /* H8/3048F-ONE Built in Peripheral Function Initialization */
367 : /************************************************************************/
368 : void init( void )
369 : {
370 : /* I/O port Setting */
371 : P1DDR = 0xff;
372 : P2DDR = 0xff;
373 : P3DDR = 0xff;
374 : P4DDR = 0xff;
375 : P5DDR = 0xff;
376 : P6DDR = 0xf0; /* DIP SW on CPU board */
377 : P8DDR = 0xff;
378 : P9DDR = 0xf7; /* Communication Port */
379 : PADDR = 0xff;
380 : PBDR = 0xc0;
381 : PBDDR = 0xfe; /* Motor Drive Board Vol.3 */
382 : /* As P7 of the sensor board is an exclusive input, there are no input output settings. */
383 :
384 : /* ITU0 Interrupt at every 1ms */
385 : ITU0_TCR = 0x23;
386 : ITU0_GRA = TIMER_CYCLE;
387 : ITU0_IER = 0x01;
388 :
389 : /* ITU3, 4 reset-synchronized PWM mode for right-left motor and servo */
390 : ITU3_TCR = 0x23;
391 : ITU_FCR = 0x3e;
392 : ITU3_GRA = PWM_CYCLE; /* Setting of cycle */
393 : ITU3_GRB = ITU3_BRB = 0; /* PWM Setting of left motor*/
394 : ITU4_GRA = ITU4_BRA = 0; /* PWM Setting of right motor*/
395 : ITU4_GRB = ITU4_BRB = SERVO_CENTER; /* PWM Setting of servo */
396 : ITU_TOER = 0x38;
397 :
398 : /* Count start of ITU */
399 : ITU_STR = 0x09;
400 : }
401 :
402 : /************************************************************************/
403 : /* ITU0 Interrupt process */
404 : /************************************************************************/
405 : #pragma interrupt( interrupt_timer0 )
406 : void interrupt_timer0( void )
407 : {
408 : ITU0_TSR &= 0xfe; /* Flag clear */
409 : cnt0++;
410 : cnt1++;
411 : }
412 :
413 : /************************************************************************/
414 : /* Timer main unit */
415 : /* Argument Timer value 1=1ms */
416 : /************************************************************************/
417 : void timer( unsigned long timer_set )
418 : {
419 : cnt0 = 0;
420 : while( cnt0 < timer_set );
421 : }
422 :
423 : /************************************************************************/
424 : /* Sensor state detection */
425 : /* Argument Mask value */
426 : /* Return value Sensor value */
427 : /************************************************************************/
428 : unsigned char sensor_inp( unsigned char mask )
429 : {
430 : unsigned char sensor;
431 :
432 : sensor = P7DR;
433 :
434 : /* Since bit0 is for left and bit7 is for right in the new sensor board which is reversed */
435 : /* to the previous sensor board, the bit has been replaced to maintain compatibility. */
436 : sensor = bit_change( sensor ); /* Bit replacement */
437 : sensor &= mask;
438 :
439 : return sensor;
440 : }
441 :
442 : /************************************************************************/
443 : /* Crossline detection processing */
444 : /* Return value 0: no crossline 1: crossline exists */
445 : /************************************************************************/
446 : int check_crossline( void )
- 24 -
Program Explanation Manual “kit05.c”
447 : {
448 : unsigned char b;
449 : int ret;
450 :
451 : ret = 0;
452 : b = sensor_inp(MASK2_2);
453 : if( b==0x66 || b==0x64 || b==0x26 || b==0x62 || b==0x46 ) {
454 : ret = 1;
455 : }
456 : return ret;
457 : }
458 :
459 : /************************************************************************/
460 : /* Reading of DIP switch value */
461 : /* Return value Switch value 0 - 15 */
462 : /************************************************************************/
463 : unsigned char dipsw_get( void )
464 : {
465 : unsigned char sw;
466 :
467 : sw = ~P6DR; /* Reading of DIP switch */
468 : sw &= 0x0f;
469 :
470 : return sw;
471 : }
472 :
473 : /************************************************************************/
474 : /* Push switch value reading */
475 : /* Return value Switch value ON: "1" and OFF: "0" */
476 : /************************************************************************/
477 : unsigned char pushsw_get( void )
478 : {
479 : unsigned char sw;
480 :
481 : sw = ~PBDR; /* Reading of port having a push switch */
482 : sw &= 0x01;
483 :
484 : return sw;
485 : }
486 :
487 : /************************************************************************/
488 : /* LED control */
489 : /* Argument Switch value (LED1,LED0)=(bit1,bit0) "0":OFF , "1":ON */
490 : /* Example 0x3->(LED1,LED0)=(ON,ON) : 0x2->(LED1,LED0)=(ON,OFF) */
491 : /************************************************************************/
492 : void led_out( unsigned char led )
493 : {
494 : unsigned char data;
495 :
496 : led = ~led;
497 : led <<= 6;
498 : data = PBDR & 0x3f;
499 : PBDR = data | led;
500 : }
501 :
502 : /************************************************************************/
503 : /* Speed Control */
504 : /* Argument Left motor: -100 - 100 , Right motor: -100 - 100 */
505 : /* 0:Stop,100:normal rotation 100%,-100:Reverse 100% */
506 : /************************************************************************/
507 : void speed( int accele_l, int accele_r )
508 : {
509 : unsigned char sw_data;
510 : unsigned long speed_max;
511 :
512 : sw_data = dipsw_get() + 5; /* DIP switch read */
513 : speed_max = (unsigned long)(PWM_CYCLE-1) * sw_data / 20;
514 :
515 : /* Left motor */
516 : if( accele_l >= 0 ) {
517 : PBDR &= 0xfb;
518 : ITU3_BRB = speed_max * accele_l / 100;
519 : } else {
520 : PBDR |= 0x04;
521 : accele_l = -accele_l;
522 : ITU3_BRB = speed_max * accele_l / 100;
523 : }
524 :
525 : /* Right motor */
526 : if( accele_r >= 0 ) {
527 : PBDR &= 0xf7;
528 : ITU4_BRA = speed_max * accele_r / 100;
529 : } else {
530 : PBDR |= 0x08;
531 : accele_r = -accele_r;
532 : ITU4_BRA = speed_max * accele_r / 100;
533 : }
534 : }
535 :
536 : /************************************************************************/
537 : /* Servo steering operation */
- 25 -
Program Explanation Manual “kit05.c”
3.2. Start
1 :/****************************************************************************/
2 :/* Micom car Rally Trace Program 2005 Version */
3: /*2005.04 Micom car Rally Executive Committee */
4 :/****************************************************************************/
Initial section is comment field. Wavy line [/*] is the beginning of the comment and [*/]is the end of the comment.
Since the text between the start of the comment sign and end is ignored, it is convenient to write the note for a
program.
14 : /*======================================*/
15 : /* Include */
16 : /*======================================*/
17 : #include <machine.h>
18 : #include "h8_3048.h"
“#include” is the include command. Include command is for importing the external file. Imported file is enclosed
within [< >] or [“ ”] and described in that. Here, “machine.h” and “h8_3048.h” are imported. Difference between
[< >] and [ ““ ] is as follows.
17 : #include <machine.h>
First, “machine.h” file is read. This file is a built-in function, which offers specialized function in CPU, which
cannot be described by C language.
- 26 -
Program Explanation Manual “kit05.c”
1 : /**************************************************************************************/
2 :/*Definition of I/O register of built-in peripheral function for H8/3048F-ONE Ver1.02 */
3 : /* 2005.04 Micom car Rally Executive Committee */
4 : /**************************************************************************************/
5 :
6 : #define P1DDR (*(unsigned char*)0xfffc0)
7 : #define P1DR (*(unsigned char*)0xfffc2)
8 : #define P2DDR (*(unsigned char*)0xfffc1)
9 : #define P2DR (*(unsigned char*)0xfffc3)
10 : #define P3DDR (*(unsigned char*)0xfffc4)
11 : #define P3DR (*(unsigned char*)0xfffc6)
12 : #define P4DDR (*(unsigned char*)0xfffc5)
13 : #define P4DR (*(unsigned char*)0xfffc7)
14 : #define P5DDR (*(unsigned char*)0xfffc8)
15 : #define P5DR (*(unsigned char*)0xfffca)
16 : #define P6DDR (*(unsigned char*)0xfffc9)
17 : #define P6DR (*(unsigned char*)0xfffcb)
18 : #define P7DR (*(unsigned char*)0xfffce)
19 : #define P8DDR (*(unsigned char*)0xfffcd)
20 : #define P8DR (*(unsigned char*)0xfffcf)
21 : #define P9DDR (*(unsigned char*)0xfffd0)
22 : #define P9DR (*(unsigned char*)0xfffd2)
23 : #define PADDR (*(unsigned char*)0xfffd1)
24 : #define PADR (*(unsigned char*)0xfffd3)
25 : #define PBDDR (*(unsigned char*)0xfffd4)
26 : #define PBDR (*(unsigned char*)0xfffd6)
27 : #define P2PCR (*(unsigned char*)0xfffd8)
28 : #define P4PCR (*(unsigned char*)0xfffda)
29 : #define P5PCR (*(unsigned char*)0xfffdb)
30 :
31 : #define ITU_STR (*(unsigned char*)0xfff60)
32 : #define ITU_SNC (*(unsigned char*)0xfff61)
33 : #define ITU_MDR (*(unsigned char*)0xfff62)
34 : #define ITU_FCR (*(unsigned char*)0xfff63)
35 : #define ITU_TOER (*(unsigned char*)0xfff90)
36 : #define ITU_TOCR (*(unsigned char*)0xfff91)
37 :
38 : #define ITU0_CNT (*(unsigned int *)0xfff68)
39 : #define ITU0_TCR (*(unsigned char*)0xfff64)
40 : #define ITU0_GRA (*(unsigned int *)0xfff6a)
41 : #define ITU0_GRB (*(unsigned int *)0xfff6c)
42 : #define ITU0_IER (*(unsigned char*)0xfff66)
43 : #define ITU0_TSR (*(unsigned char*)0xfff67)
44 : #define ITU0_TIOR (*(unsigned char*)0xfff65)
45 :
46 : #define ITU1_CNT (*(unsigned int *)0xfff72)
47 : #define ITU1_TCR (*(unsigned char*)0xfff6e)
48 : #define ITU1_GRA (*(unsigned int *)0xfff74)
49 : #define ITU1_GRB (*(unsigned int *)0xfff76)
50 : #define ITU1_IER (*(unsigned char*)0xfff70)
51 : #define ITU1_TSR (*(unsigned char*)0xfff71)
52 : #define ITU1_TIOR (*(unsigned char*)0xfff6f)
53 :
54 : #define ITU2_CNT (*(unsigned int *)0xfff7c)
55 : #define ITU2_TCR (*(unsigned char*)0xfff78)
56 : #define ITU2_GRA (*(unsigned int *)0xfff7e)
57 : #define ITU2_GRB (*(unsigned int *)0xfff80)
58 : #define ITU2_IER (*(unsigned char*)0xfff7a)
59 : #define ITU2_TSR (*(unsigned char*)0xfff7b)
60 : #define ITU2_TIOR (*(unsigned char*)0xfff79)
61 :
62 : #define ITU3_CNT (*(unsigned int *)0xfff86)
63 : #define ITU3_TCR (*(unsigned char*)0xfff82)
64 : #define ITU3_GRA (*(unsigned int *)0xfff88)
65 : #define ITU3_GRB (*(unsigned int *)0xfff8a)
66 : #define ITU3_BRA (*(unsigned int *)0xfff8c)
67 : #define ITU3_BRB (*(unsigned int *)0xfff8e)
68 : #define ITU3_IER (*(unsigned char*)0xfff84)
69 : #define ITU3_TSR (*(unsigned char*)0xfff85)
70 : #define ITU3_TIOR (*(unsigned char*)0xfff83)
71 :
- 27 -
Program Explanation Manual “kit05.c”
Hereafter, abbreviation
“#define” is a definition function and defines the replacement of a certain character string with other character
strings.
For example,
Meaning of the above is that whenever “PADDR” character string occurs in the program it is replaced with
“(*(unsigned char*)0xfffd1)” character string. During the program, the compiler executes the program by
converting
PADDR = 0xff;
to
I/O register, which controls built-in peripheral functions including these I/O ports, is allocated in the address
identically of ROM or RAM. This is the part indicated by 0xfff1c-0xfffff block numbers which are the I/O
registers in the following diagram.
For instance, “1010 0101” signal is output from the output pin of port A if 0xa5(“1010 0101” written in binary
number) is written in 0xfffd3 block number, when 0xfffd3 block number is defined with PADR and set for the
output.
Since it becomes difficult to understand if all block numbers are directly specified by numerical values, it is
defined that “PADR is the value of 0xfffd3 block number”.
Note:0xfffd3 block number means address 0xfffd3.
- 28 -
Program Explanation Manual “kit05.c”
5V 0V 5V 0V 0V 5V 0V 5V
PADR is 8-bit width 0xfffd3 block number without code
#define PADR (unsigned char*)0xfffd3
(unsigned char).
PADR is value of 8-bit width 0xfffd3 block number without
#define PADR *(unsigned char*)0xfffd3
code.
#define PADR (*(unsigned char*)0xfffd3) It is the same, but is entirely enclosed by parentheses.
PADR++;
it gets converted to
This means add 1 to 0xfffd3 block number value (increment the value 0xfffd3 block number by 1).
However, if it not entirely enclosed by parentheses, it becomes
*(unsigned char*)0xfffd3++;
And it means add 1 to 0xfffd3 block number (increment 0xfffd3 block number by 1). As 0xfffd3 block number is a
- 29 -
Program Explanation Manual “kit05.c”
All the unused I/O registers other than the I/O register used for micom car control are covered in detail in
h8_3048.h. For details look up the meaning of register in “H8/3048 series and H8/3048F-ZTATTM
(H8/3048F,H8/3048F-ONE) hardware manual”.
20 : /*======================================*/
21 : /* Symbol definitions */
22 : /*======================================*/
23 :
24 : /* Constant settings */
25 : #define TIMER_CYCLE 3071 /* Timer cycle 1ms */
26 : /* When it is to be used by φ / 8 */
27 : /* φ / 8 = 325.5[ns] */
28 : /* Therefore, TIMER_CYCLE = */
29 : /* = 1[ms] / 325.5[ns] */
30 : /* = 3072 */
31 : #define PWM_CYCLE 49151 /* PWM cycle 16ms */
32 : /* Therefore, PWM_CYCLE */
33 : /* = 16[ms] / 325.5[ns] */
34 : /* = 49152 */
35 : #define SERVO_CENTER 5000 /* Center value of Servo */
36 : #define HANDLE_STEP 26 /* 1 degree part value */
37 :
38 : /* Mask value setting x: With Mask (Invalid) o:Without mask (Valid) */
39 : #define MASK2_2 0x66 /* */
40 : #define MASK2_0 0x60 /* */
41 : #define MASK0_2 0x06 /* */
42 : #define MASK3_3 0xe7 /* */
43 : #define MASK0_3 0x07 /* */
44 : #define MASK3_0 0xe0 /* */
45 : #define MASK4_0 0xf0 /* */
46 : #define MASK0_4 0x0f /* */
47 : #define MASK1_1 0x81 /* */
- 30 -
Program Explanation Manual “kit05.c”
Timer cycle is a value to set 1[ms] time in ITU0. ITU marks (ticks) the time with the
operation clock of CPU.
As RY3048F-ONE board crystal is 24.576[MHz], 1 clock cycle becomes 1÷(24.576 106) =
40.69[ns].
TIMER_CYCLE In addition, clock is divided, and is equipped with the function to lower the frequency and
this time it is used by dividing it in 8. Therefore, the value to be counted to set the time to
1[ms] is (1 10-3) ÷ (40.69 10-9) ÷ 8 = 3,072.
Value to be set becomes 3,071, because it must be less by 1 count than the calculated value.
Described later.
PWM cycle is added to Right motor, Left motor and servo. The PWM cycle is of 16[ms]. And
becomes
PWM_CYCLE
(16 10-3) ÷ (40.69 10-9) ÷ 8 = 49,152
Value to be set becomes 49,151. Described later.
Servo Center is a value when the servo faces straight. It is straight when
the ON pulse is just about 1.5[ms].( Refer to on page17) And becomes
(1.5 10-3) ÷ (40.69 10-9) ÷ 8 = 4,608
However, the value of servo center is different in all micom cars due to
SERVO_CENTER the impact of error in the servo itself or the engagement with jagged shaft
which is inserted in the servo horn, etc. To illustrate, it is like human
fingerprints;each is unique. Therefore, here, the value is limited
temrorarily to 5,000. This value is adjusted or changed to face straight SServo horn
when going straight.
Steering step of servo is the increasing or decreasing value when the servo moves by 1
degree. As it is a pulse of 2.3ms when the servo turns at 900 to the right, it is
(2.3 10-3) ÷ (40.69 10-9) ÷ 8 = 7,065
As it is a pulse of 2.3ms when the servo turns at 900 to the left, it is
(0.7 10-3) ÷ (40.69 10-9) ÷ 8 = 2,150
HANDLE_STEP (Right 900) − (left 900) = 7,065-2,150 = 4,915 is a value which moves by 180 degrees. If it is
divided by 180, the counter value per 1 degree can be found out.
4,915 ÷ 180 = 27
When value is accurately calculated 27 is the value of the servo 1 degree. However, it was 26
in the previous kit04.c program and has been kept as 26 taking into consideration the
compatibility with the previous program.
It is a value, which masks the status of the sensor. It means that in case of “Mask _0”,
number of left sensors and 0 number of right sensors are enabled and the others are masked.
MASK2_2
As “Mask2_2” is defined as “0x66”, bit6, 5, 2, 1 are maintained as they are in “0110 0110”
binary numbers and the others are forcibly set to “0”.
As “Mask2_0” is defined as “0x60”, bit6, 5, are maintained as they are in “0110 0000” binary
MASK2_0
numbers and the others are forcibly set to “0”.
As “Mask0_2” is defined as “0x06”, bit2, 1 are maintained as they are in “0000 0110” binary
MASK0_2
numbers and the others are forcibly set to “0”.
As “Mask3_3” is defined as “0xe7”, bit7, 6, 5, 2, 1, 0 are maintained as they are in “1110
MASK3_3
0111” binary numbers and the others are forcibly set to “0”.
As “Mask0_3” is defined as “0x07”, bit2, 1, 0, are maintained as they are in “0000 1110”
MASK0_3
binary numbers and the others are forcibly set to “0”.
As “Mask3_0” is defined as “0xe0”, bit7, 6, 5, are maintained as they are in “1110 0000”
MASK3_0
binary numbers and the others are forcibly set to “0”.
As “Mask4_0” is defined as “0xf0”, bit7, 6, 5, 4 are maintained as they are in “1111 0000”
MASK4_0
binary numbers and the others are forcibly set to “0”.
As “Mask0_4” is defined as “0x0f”, bit3, 2, 1, 0 are maintained as they are in “0000 1111”
MASK0_4
binary numbers and the others are forcibly set to “0”.
As “Mask1_1” is defined as “0x81”, bit7, 0 are maintained as they are in “1000 0001” binary
MASK1_1
numbers and the others are forcibly set to “0”.
Mask is described later.
- 31 -
Program Explanation Manual “kit05.c”
49 : /*======================================*/
50 : /* Prototype declaration */
51 : /*======================================*/
52 : void init( void );
53 : void timer( unsigned long timer_set );
54 : int check_crossline( void );
55 : unsigned char sensor_inp( unsigned char mask );
56 : unsigned char dipsw_get( void );
57 : unsigned char pushsw_get( void );
58 : void led_out( unsigned char led );
59 : void speed( int accele_l, int accele_r );
60 : void handle( int angle );
61 : char unsigned bit_change( char unsigned in );
Prototype declaration is the declaration that checks the number and type of arguments of the user defined
function before its use. Function prototype is as the function definition which is added “;” at the end of the
statement. Function prototype declares following information.
Function “speed”
Return value void
First argument of int type
Second argument of int type
As explained above, prototype declaration is used for checking number and type of function arguments. Thus, the
dummy argument name is not necessary. The following definition is also allowed.
But the dummy argument name helps to decode the program while reading. It is a good practice to write it.
Moreover, just remember that "copy the function declaration line as it is and add a semicolon at the end" should
be done instead of writing the dummy argument names explicitly so that errors will be reduced.
Naturally, function 'speed' should have same arguments and return value as that of the prototype declaration.
The following sample is the function definition of the speed function.
void speed( int accele_l, int accele_r )
{
Program;
}
In this way, all the user-defined functions are declared in the prototype declaration.
- 32 -
Program Explanation Manual “kit05.c”
Though it is an error if the function is called without prototype declaration, the compiler executes strange
operation without noticing the error, as it does not understand whether function argument and return value are
correct. For that, function name, arguments and return type are declared in advance so that compiler understands
that the function exists. (Figure below)
Global variables are declared outside the function and can be referred from any function. General variables
declared inside the function are called as local variables and only that function can refer to it. An example is
illustrated below.
timer = 0;
i = 10;
printf(“%d¥n”,timer ); <- 0 is displayed
a();
printf(“%d¥n”,timer ); <-Value 20 set in the function a
is displayed as timer is a global variable
printf(“%d¥n”,i ); <-Value 10 set in this function is displayed
as ‘i’is also declared in function ‘a’ but
is not changed as it is a local variable
}
void a( void )
{
int i;
i = 20;
timer = i;
}
- 33 -
Program Explanation Manual “kit05.c”
cnt1 unsigned long Used by programmer to set the timing in the program.
If the program is explained sequentially, ‘main’ function comes first but here it is explained last.
The functions built-in H8/3048F-ONE microcomputer are initialized here.’init’ is the abbreviation for ‘initialize’
and means initialization.
365 : /************************************************************************/
366 : /* H8/3048F-ONE Built in Peripheral Function Initialization */
367 : /************************************************************************/
368 : void init( void )
369 : {
370 : /* I/O port Setting */
371 : P1DDR = 0xff;
372 : P2DDR = 0xff;
373 : P3DDR = 0xff;
374 : P4DDR = 0xff;
375 : P5DDR = 0xff;
376 : P6DDR = 0xf0; /* DIP SW on CPU Board */
377 : P8DDR = 0xff;
378 : P9DDR = 0xf7; /* Communication Port */
379 : PADDR = 0xff;
380 : PBDR = 0xc0;
381 : PBDDR = 0xfe; /* Motor Drive Board Vol.3 */
382 : /* As P7 of the sensor board is an exclusive input, there are no input output settings. */
I/O port is the abbreviation for Input/Output Port and it means the ‘port where input and output is carried out’. In
this context it is ‘a place where input and output operations are carried out collectively’ .I/O port input output
settings are set at the start of the program.
There are 11 I/O ports from 1 ~ B and basically they are 8 bit ports but there are some ports with less than 8 bits.
The ports from 1-B are composed of DDR and DR registers respectively and input-output direction settings, and
input and output of data is performed one by one. But the port 7 is an exclusive input port and there is no P7DDR.
Port 7 is necessarily an input port.
- 34 -
Program Explanation Manual “kit05.c”
2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34
P84 P82 P80 P65 NMI P60 P52 P50 P26 P24 P22 P20 P16 P14 P12 P10 GND Ex, P84 indicate bit 4 of
1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 the port 8
V cc P83 P81 P66 P64 *RES P53 P51 P27 P25 P23 P21 P17 P15 P13 P11 P37
1 Vcc 2 P36
3 P35 4 P34
5 P33 6 P32
7 P31 8 P30
9 P47 10 P46
11 P45 12 P44
13 P43 14 P42
15 P41 16 P40
17 P94 18 P92
19 P90 20 GND
1 Vcc 2 PB7
3 PB6 4 PB5
5 PB4 6 PB3
7 PB2 8 PB1
9 PB0 10 GND
9 7 5 3 1 9 7 5 3 1
P70 P72 P74 P76 Vcc PA0 PA2 PA4 PA6 Vcc
10 8 6 4 2 10 8 6 4 2
GND P71 P73 P75 P77 GND PA1 PA3 PA5 PA7
- 35 -
Program Explanation Manual “kit05.c”
Input-Output Setting
Explaining port B as an example, PB in the PBDDR means port B. There are P1DDR ~ PBDDR. The part in
changes from 1 to B. However, there is no P7DDR.
DDR is the abbreviation for ‘Data Direction Register’ and it decides the input-output direction. Input –output
setting is done using 1 bit.
Corresponding Bit”0”: Input Pin (Default Value)
Corresponding Bit “1”: Output Pin
Bit: 7 6 5 4 3 2 1 0
Input-Output Input-Output Input-Output Input-Output Input-Output Input-Output Input-Output Input-Output
PBDDR: Setting of Setting of Setting of Setting of Setting of Setting of Setting of Setting of
port bit 7 port bit 6 port bit 5 port bit 4 port bit 3 port bit 2 port bit 1 port bit 0
Motor drive board is connected to port B. Confirm the connective conditions for each bit.
Pin Signal, DDR
Details “0” “1” Input-output
No. Direction Value
1 − + 5V
2 Board <-PB7 LED1 ON OFF Output 1
3 Board<-PB6 LED0 ON OFF Output 1
4 Board<-PB5 Servo Signal PWM Signal Output 1
5 Board<-PB4 Right Motor PWM Stop PWM Motion Output 1
Right Motor Rotational Normal Reverse
6 Board<-PB3 Output 1
Direction Rotation Rotation
Left Motor Rotational Normal Reverse
7 Board<-PB2 Output 1
Direction Rotation Rotation
8 Board<-PB1 Left Motor PWM Stop PWM Motion Output 1
9 Board->PB0 Push Button Pushed Not Pushed Input 0
10 − GND
Bit 0 is input setting and others are output setting. As input is set to ‘0’ and output is set
1 7
to ’1’ thus
1 6
PBDDR = 1111 1110 = 0xfe.
1 5
1 4
P
B
D
1 3
D
R
1 2
1 1
0 0
1 7
1 6
1 5
Earlier it was explained that address was assigned to the I/O register and block number is
top address of the I/Oregister.
0
1 4
x
f
f
As PBDDR has block number 0xfffd4, 0xfffd4 directly relates to the part that decides the
1 3
f
input-output of port B and input-output direction is decided by the value written in the
d
4
1 2
block number.
1 1
0 0
- 36 -
Program Explanation Manual “kit05.c”
Port B is explained as an example. PB of the PBDR means port B. There are P1DR ~ PBDR. The part in
changes from 1 to B.
DR is the abbreviation for ‘Data Register’ and is the register that outputs the data to the pin or inputs the data from
the pin. In case of the pin which is set for input port (DDR=0), voltage level at that pin is obtained by reading the
data from DR.
Corresponding Bit”0”: Voltage input at the pin is”0”(Low Level).
Corresponding Bit “1”: Voltage input at the pin is”1”(High Level).
In case of the pin which is set for output port (DDR=1), voltage level at that pin is output by writing the data into
DR.
Corresponding Bit “0”: Voltage output from the pin is”0”(Low Level).
Corresponding Bit “1”: Voltage output from the pin is”1”(High Level).
Bit: 7 6 5 4 3 2 1 0
Output data Output data Output data Output data Output data Output data Output data Output data
setting to setting to setting to setting to setting to setting to setting to setting to
PBDR: bit 7 /Input bit 6 /Input bit 5 /Input bit 4 /Input bit 3 /Input bit 2 /Input bit 1 /Input bit 0 /Input
data read data read data read data read data read data read data read data read
from bit 7 from bit 6 from bit 5 from bit 4 from bit 3 from bit 2 from bit 1 from bit 0
External
5.0V
Input voltage range
“1”
External recognized as“1”
Voltage 2.0V
0.8V Input voltage range
“0”
0V recognized as“0”
In case output setting, a regulated voltage is output from the objective pin if data is written to the port address which
microcomputer needs to output. Voltage 3.5 V or more is output from the pin for the bit is "1" (high level) and
voltage 0.4V or less is output from the pin for the bit is "0" (Low level).
External
“1” 5.0V Output Voltage
3.5V “1”
Micro-
computer
0.4V Output Voltage
“0” 0V “0”
- 37 -
Program Explanation Manual “kit05.c”
Incidentally, TTL (74LS Series IC’s) and CMOS (74HC Series IC's) voltage levels are as shown in the figure
below. It is necessary to note that both are not the microcomputer I/O port voltage levels.
0.8 V
“0” 0.4V “0” “0” 0.1V “0”
0V 0V
Outpu 0V Input Outpu 0V Input
TTL Levels CMOS Levels
Permissible
Item
Current
Ports 1, 2, 5, and B 10mA
Permissible output low level current (Per pin)
Other output pins 2.0mA
Total of 28pins in ports 1, 2, 5 and B 80mA
Permissible output low level current (total) Total of all output pins , including the
120mA
above
Permissible output high level current (Per pin) All output pins 2.0mA
Permissible output high level current (total) Total of all output pins 40mA
Conditoions: Vcc=3.0 ~ 3.6V, AVcc=3.0 ~ 3.6V, VREF=3.0 ~ AVcc, Vss=AVss=0V or
Vcc=5.0±10%, AVcc=5.0±10%, VREF=4.5 ~ AVcc, Vss=AVss=0V
Connect the current-limiting resistor with the output pin to drive the Darlington transistor and LED directly. When
the Low level signal is output to port B, the current of 10mA/Pin flows out.When 10 mA current flows out of all
the eight pins, the current of 80mA is consumed only by port B. It is not possible to flow the current in the ports
1,2, and 5 as ' Permissible Output low level current (total) out of ports 1, 2, 5, and B is 80 mA'.
Permissible output low level current out of each pin corresponding to ports 1, 2, and 5 is 10 mA but no current can
flow in case of high level, as permissible high level current is only 2.0 mA. Take precautions while designing a
circuit.
- 38 -
Program Explanation Manual “kit05.c”
Pin Signal,
Details “0” “1” DR Value
Number Direction
1 − + 5V
2 Board <-PB7 LED1 ON OFF 1
3 Board<-PB6 LED0 ON OFF 1
4 Board<-PB5 Servo signal PWM Signal 0
5 Board<-PB4 Right Motor PWM Stop PWM Motion 0
Right Motor Rotational Normal Reverse
6 Board<-PB3 0
Direction Rotation Rotation
Left Motor Rotational Normal Reverse
7 Board<-PB2 0
Direction Rotation Rotation
8 Board<-PB1 Left Motor PWM Stop PWM Motion 0
9 Board->PB0 Push Button Switch Pushed Not Pushed Both are acceptable.
10 − GND
To turn off LED, “1” is output first. To stop the motor, “0” is output and the temporary
1 7 5V
“0” is put in the servo as both are acceptable. Since PB0 is for input, even if write
1 6 5V
anything, the value does not change. However, “0” is written as there may be a doubt that
0 5 0V
something happens if “1” is written. PBDR = 1100 0000 = 0xc0.
P 0 4 0V
B
D
R 0 3 0V
0 2 0V
0 1 In the program 0xc0 is set in PBDR first and then 0xfe is set in PBDDR. Why should we
0V
0 0 set the data before input-output settings? This relates to the register values immediately
after reset. According to the hardware manual, the initial value of PBDDR is 0x00 , so all
pins of port B become to input port. Initial value of the PBDR is 0x00. Thus, if the port is set for output in PBDR
first, 0x00 value of the PBDR is output. LED becomes ON for a moment as it is switched ON by "0". There may
not be a problem as LED is turned OFF immediately after next PBDR write but there may be some wrong
operations because of that momentary lighting effect if some other device is connected. Thus PBDR settings
should be set first and the LED should be turned OFF and then the PBDDR settings should be set to avoid such
minute mistakes
- 39 -
Program Explanation Manual “kit05.c”
When the bit set to output is read, present output value is read. For example, Input-output pin settings are as
shown in the following chart when switch conditions of the motor drive board is to be read.
Output bit reads the present output value.
1 7 1
0 6 0
1 5 1
P 1 4 1
B
D
R 0 3 0
0 2 0
1 1 1
1 0 1
This time if PBDR is read, ‘logical-OR’ed value of present output value and input value is read as shown in the
following chart.
Bit 7 6 5 4 3 2 1 0
Value being output 1 0 1 1 0 0 1
Input Value 1
Read value of PBDR 1 0 1 1 0 0 1 1
Other Ports
Setup
Port
value
P1DDR 0xff No connection
P2DDR 0xff No connection
P3DDR 0xff No connection
P4DDR 0xff No connection
P5DDR 0xff No connection
Bit 3 ~ 0 are DIPswitch inputs on the CPU board and others are not
P6DDR 0xf0
connected.
Sensor board is connected.
P7
There is no P7DDR as port 7 is an exclusive input port.
P8DDR 0xff No connection
Bit 3 is communication data output and bit 1 is communication data input,
P9DDR 0xf7
others are not connected.
PADDR 0xff No connection
PBDDR 0xfe Motor Drive Board
Why should a bit that is not connected, should make as an output port? In worst case, the internal circuit parts of
the H8 microcomputer get damaged because of the external noise if pin is set to input when nothing is connected.
The input pins with which nothing is connected are either pulled up/down or output setting is done without
connecting anything to the pins.
- 40 -
Program Explanation Manual “kit05.c”
Process 2
Processing Time 1us
When compared with the human being it is like operating a PC from the place which cannot be seen and voice will
not reach it from the cash counter while observing the shop. Therefore, it is necessary to check whether customer
has arrived or not every now and then. It is not efficient without applying to personal computer operation.
Then, the chime was prepared with the sticker "Dear customer, please push the chime”. Now it can be understood
- 41 -
Program Explanation Manual “kit05.c”
that customer has come and it is not necessary to go and check whether the person has come or not.
To check every now and then
It is called “Polling” in computer language. As regular observation is a must, there is a time loss if there are too
many parts to be observed.
To check when chime rings
It is called “Interrupt” in computer language. It is efficient as it checks only when the chime rings. But it is
necessary to confirm whether chime has rung or not. It is similar to the interrupt setting. Responding to the chime
ring and going up to the watch stand is similar to the interrupt program.
In this way it is possible to generate multiple interrupts. When an interrupt is generated, program jumps to the
interrupt routine (function) set in advance. Here, the interrupt is generated after every 1 ms using ITU. There are
five ITU channels from 0 ~ 4. ITU0is used here.
“ITU” is the abbreviation for “Integrated Timer Unit”. ”Integrated” means accumulated.
Accumulated means ”large number of things gathered together”. Here, it is a timer with a large number of
functions. In one word, it is a high efficiency timer.
ITU0 ~ 4 are the five built-in channels in the H8/3048F-ONE. They are used in various applications depending
on the settings.
Interval Timer … Sets 1ms timer
PWM Output … Controls the motor Speed
3 phase PWM Output … Controls the 3 phase Motor
Input Capture input … Measurement of waveform pulse width
- 42 -
Program Explanation Manual “kit05.c”
The functions used in the micom car are interval timer and PWM output. Accurate time measurement is done
using interval timer, and servo and motor control are performed using PWM output.
Program
ITU0 Register
It acts like a second hand of the clock. The counter value is incremented by one after a fixed interval. This value
is always monitored; eg.generates an interrupt when it reaches say 1000.
- 43 -
Program Explanation Manual “kit05.c”
Bit: 7 6 5 4 3 2 1 0
ITU0_TCR: − CCLR1 CCLR0 CKEG1 CKEG0 TPSC2 TPSC1 TPSC0
Setup value: 0 0 1 0 0 0 1 1
Hexadecimal :
2 3
This is the setting for “Timing to set 0 to ITU0_CNT ”. Compare-match means setting it in such a way that if
ITU0_CNT matches (ITU0_GRA + 1), ITU0_CNT is cleared. One might wonder why it should be incremented by
1, but it has been set in “Regulations of ITU". At the time of “ITU0_CNT=(ITU0_GRA + 1)", matching is judged
to be occured. Therefore, if one wants to do something when ITU0_CNT becomes 1000(Interrupt or the pulse is
generated), one must put 999 into ITU0_GRA. Interrupt or the pulse is generated by always comparing whether
ITU0_CNT is ( 999 + 1 ) or not.
Bit2 ~ 0: Timer Prescalar 2 ~ 0
Selects the counter clock of CNT.
TPSC2 TPSC1 TPSC0 Explanation
0 0 0 Internal Clock: Count at φ
0 0 1 Internal Clock: Count at φ / 2
0 1 0 Internal Clock: Count at φ / 4
0 1 1 Internal Clock: Count at φ / 8
1 0 0 External Clock A: Count at TCLKA(PA0) pin
1 0 1 External Clock B: Count at TCLKB(PA1) pin
1 1 0 External Clock C: Count at TCLKC(PA2) pin
1 1 1 External Clock D: Count at TCLKD(PA3) pin
- 44 -
Program Explanation Manual “kit05.c”
It should ideally be set to “000” because it is 1ms, but taking into consideration the compatibility with kit04.c,
“011” is set in the TPSC this time. The time at which ITU0_CNT advances by 1 is 325.52ns.
Bit: 7 6 5 4 3 2 1 0
ITU0_IER: − − − − − OVIE IMIEB IMIEA
Setup value: 0 0 0 0 0 0 0 1
Hexadecimal:
0 1
- 45 -
Program Explanation Manual “kit05.c”
Enables or disables the interrupt requested by the OVF frag in TSR when OVF is set to 1.
OVIE Explanation
0 OVI interrupt requested by OVF is disabled ( Initial value)
1 OVI interrupt requested by OVF is enabled
This time we does not use this OVF interrupt, then there is no relation to this interrupt.
In case of no relation, the original value ( = Default value = Initial value ) is retained.
Bit: 7 6 5 4 3 2 1 0
ITU0_TSR: − − − − − OVF IMFB IMFA
- 46 -
Program Explanation Manual “kit05.c”
This is “IMFA” which is Bit0 of ITU0_IER mentioned earlier. “Input capture/compare Match Flag A” is
abbreviated and called as IMFA. Still it is not understood what it exactly is. In short, Bit0 of ITU0_TSR becomes
“1” at ITU0_CNT=(ITU0_GRA + 1). "
Bit0 of ITU0_TSR becomes “1” and if Bit0 of ITU0_IER is “1”, interrupt is generated. The interrupt generation is
not triggered by”ITU0_CNT=(ITU0_GRA + 1)" but is triggered when Bit0 of ITU0_TSR becomes “1” after
“ITU0_CNT=(ITU0_GRA + 1)”.
ITU0_IER 00000001
Interrupt is
generated when both
bits are “1”.
ITU0_TSR 00000001
Becomes “1”
whenITU0_CNT=(ITU0_GRA+1)
Setup value: 0 0 0 0 1 0 0 1
Value to be
ORed in
0 9
program:
- 47 -
Program Explanation Manual “kit05.c”
0
ITU3_GRA sets time required for alarm. According to the previous
setting, CNT increases one by one with 325.52[ns]. As time
required for alarm is set by 1[ms] , so 3072 is set in the GRA but
according to the standard operating procedure of ITU,
"ITU0_CNT=(ITU0_GRA + 1)" is the actual required timing for
GRA+1
CNT value alarm.
(3072)
(1 10-3) / (325.52 10-9)=3072
1ms till Therefore, 3071 of 1 small value is set in the ITU0_GRA.
becoming 3072
The ordinary clock goes through a rotation, but on the way through
0
When a rotation, ITU can forcefully adjust the second hand to 0. Since it
becoming 3072, is set as "CNT is cleared in compare match/ input capture of GRA
it is cleared to “ by ITU0_TCR, if it becomes ITU0_CNT=(ITU0_GRA + 1) then
0. CNT becomes 0. It requires 1[ms] to become 3072 , and then it is
cleared to 0 at once and ITU0_CNT=(ITU0_GRA + 1) becomes in
GRA+1
CNT value each 1[ms].
(3072)
ITU0_TSR bit0="1"
Bell
- 48 -
Program Explanation Manual “kit05.c”
ITU0_TSR bit0="1"
ITU0_IER bit0="1" In order to ring the alarm bell the Bit 0 of ITU0_IER is set to
Bell "1", and an interrupt is generated. When the bell rings,the
microcomputer shifts to the interrupt process.
Battery is put in the alarm Setting completed! But, actually, there is no battery in the clock.
(Clock is stared) The clock in which battery is put is moved. This is the setting 0x01
ITU STR = 0x01 into the timer start register ITU_STR. However, as ITU3 is used
too, 0x09 is actually set.
kit05start.src setting
When interrupt is generated, “The execution of the program jumps to the interrupt program (function) which is set
in advance”, and that is described already on page 41. what means that?
This time, execution is moved to interrupt_timer0 function which is a private function. Using “interrupt” as the
name of a private function, is ok. In H8/3048F-ONE, the address of 0x0000-0x00ff block number is called as
vector address area. An address in which the interrupt program is stored, is written in the previously decided
address of vector address. When the interrupt is generated, the executio of the program jamps to that address.
The following table lists it. For example, interrupt (IMIEA0 interrupt) generated when the CNT of ITU is in
agrrement with (GRA + 1), reads the value written in address 0x0060 and jump to that address.
The summarized table for interrupt types and vector address is displayed below.
Generating Vector
Interrupt source Vector address IPR Priority
origin no.
Reset External pin 0 H'0000 ~ H'0003 −−−
- 49 -
Program Explanation Manual “kit05.c”
- 50 -
Program Explanation Manual “kit05.c”
“. DATA.L” command is the command of writing data of Long unit (4 bytes). For example,
0x0060 0x00
0x0061 0x00
0x0062 0x05
0x0063 0xa0
- 51 -
Program Explanation Manual “kit05.c”
Reset is also interrupt. Reset is vector number 0. The flow of program execution jumps to RESET_START after
reset.
When calling C language program file from the assembly program file.
According to the rule, the function name must start with the “_”(underscore), when calling the function of C
program file (kit05.c) from the assembly program file (kit05start.src). It is stated as “_interrupt_timer0” in the
assembly program and, “interrupt_timer0” in C language program.
Declaration of .IMPORT
The compiler looks for converting the declared “_interrupt_timer0" into an address.
But the error message “it does not exist” is displayed , because this function is in the “Kit05.c” as “ 405 : #pragma
interrupt ( interrupt_timer0 ) and 406 : void interrupt_timer0( void ) “.
Then, the name “_ interrupt_timer0” exists in separate file by using the “. IMPORT” command and “Search again
later” is instructed to the compiler.
6: .IMPORT _interrupt_timer0
The vector number is different from the contents, which generates interrupt.
Jump destination function is described in the corresponding vector number.
However, “_ (underscore)” is added at the beginning of the function name.
Whether this name is exists in the external file by the “.IMPORT” command is conveyed.
- 52 -
Program Explanation Manual “kit05.c”
ITU0_TSR = 0x00;
How do you think about the above statement for the bit clear ? Regrettably, this is not allowed.
Let’s refer to the ITU0_TSR (IMFA) bit 0 description again.
Setting contents of ITU0_TSR (Timer status register)
Bit : 7 6 5 4 3 2 1 0
ITU0_TSR: − − − − − OVF IMFB IMFA
“After reading IMFA flag” is the key point. If the value is written as it is like "ITU0_TSR = 0x00;",
it is not “Read”. Therefore, even if 0x00 is written, bit 0 does not become "0". Then, AND operation is done.
Bit 7 6 5 4 3 2 1 0
ITU0_TSR ? ? ? ? ? ? ? 1
Value by
which AND 1 1 1 1 1 1 1 0
operated
Result 0
Note: means “No change”.
“ ITU0_TSR &= 0xfe; ” means “ ITU0_TSR = ITU0_TSR & 0xfe; “. There is ITU0_TSR in the right hand
assignment expression in the assignment statement. ITU0_TSR in the assignment expression means that the
value of ITU0_TSR is read in the CPU register once, and the new value of the expression is made by logical AND
operation, and the new value is written into ITU0_TSR by “ ITU0_TSR = ”. So,”write after read” has been
carried out. Moreover, there is a merit of not changing the values other than bit 0 by AND operation .
What will happen if ITU0_TSR bit 0 is not set to “1”? Interrupt is generated, when -
Bit 0 of ITU0_IER is “1” and bit 0 of ITU0_TSR is “1”.
When any interrurt is enabled, this check is done always after execution cycle of every command translated
machine language level.
- 53 -
Program Explanation Manual “kit05.c”
Now, notice about "Return and Recheck". If bit 0 of ITU0_TSR is not cleared, it is judged that the interrupt is
generated then, and the flow of processing backs again to the interrupt program at once, in spite of very short time
for less than 1 ms. This means that only interrupt program keeps on executing without executing the main program
and it becomes infinite loop. It is necessary to clear corresponding status flag always in the interrupt program.
The process example is displayed below when bit0 of ITU0_IER ="1" and bit0 of ITU0_TSR = ”1” is
detected.
mov.b #h'00,r1
cmp.b r1,r2
Same process
sub.b #h'56,r3
…
- 54 -
Program Explanation Manual “kit05.c”
Actually it is necessary to declare, "pragma interrupt" in the function, to which the processing flow jumps by
interrupt. The function name is written in the parenthesis as "# pragma interrupt (interrupt function name)".
In C language, when the function is called, the processing flow goes to the function and returns automatically to
the place where the function has been called, at the completion of the function.
C language is translated to the assembly language by C language compiler as following diagram. In assembly
language, RTS(ReTurn from Subroutine) command is the command that the processing flow returns to the place
where the function is called.
Conversion to assembler
In C language interrupt program is also a function but actually the assembler command that the processing flow
is returned from interrupt program is not a RTC command, it is a RTE(ReTurn from Exeption) command. This is a
command which returns to the place where interrupt program is called, after rewriting the value of CCR and PC
which are stored automatically when interrupt is generated.
※CCR: Condition Cord Register PC:Program Counter
Conversion to assembler
RTE <-Returned
} from interrupt
In C language, the function ends by “}”, whether it is an interrupt function or not. But in the assembly language,
the return command changes depending on that the function is an interrupt function or not. This specification is a
“pragma declaration”.
In the case of jumping by the interrupt, “#pragma” is declared in the function , then it is OK.
It is not possible to call the function that declares “pragma interrupt”, from the usual functions like main function
etc.
Here, interrupt setting is complete. Let’s use the interrupt.
- 55 -
Program Explanation Manual “kit05.c”
389 : /* ITU3, 4 reset-synchronized PWM mode for right-left motor and servo */
390 : ITU3_TCR = 0x23;
391 : ITU_FCR = 0x3e;
392 : ITU3_GRA = PWM_CYCLE; /* Setting of cycle */
393 : ITU3_GRB = ITU3_BRB = 0; /* PWM Setting of left motor */
394 : ITU4_GRA = ITU4_BRA = 0; /* PWM Setting of right motor */
395 : ITU4_GRB = ITU4_BRB = SERVO_CENTER; /* PWM Setting of servo */
396 : ITU_TOER = 0x38;
397 :
398 : /* Count start of ITU*/
399 : ITU_STR = 0x09;
Here, PMW for controlling left motor, right motor and servo is set. PMW cycle is adjusted to 16ms fited into the
servo cycle. It is OK if PMW cycle of the motor is approximately 1[ms] (a motor moves most smoothly) but as the
cycle cannot be made only in common, it matches with servo.
There are five channels of ITU. One PWM wave of per one ITU can be output usually.
In H8/3048F-ONE there is a setting called reset-synchronized PMW mode. This mode is the mode that output 3
toggled PMW waveforms by combining and using ITU3 and ITU4. Further, the wave that reverses the 3 toggled
PWM waveformes are output at the same time. PWM output is possible from total 6 pins. The defect
(shortcoming) is that it has to be made the same for all 3 cycles.
B0
ITU3
B0
PWM mode
B1
ITU3 and
ITU4 B2
ITU4
B2
PWM mode
Reset B4
synchronized
B3
※ B0 means bit #0 of B5
port B
single PWM mode Reset synchronized PWM
- 56 -
Program Explanation Manual “kit05.c”
This time cycle is of 16[ms]. To adjust the cycle to 16ms TPSC is ="011".
- 57 -
Program Explanation Manual “kit05.c”
In this register, the setting for channels 3 and 4 are carried out. One is mode selection and the other is setting of
buffer operation.
Bit: 7 6 5 4 3 2 1 0
ITU_FCR: − − CMD1 CMD0 BFB4 BFA4 BFB3 BFA3
Set value: 0 0 1 1 1 1 1 0
Hexadecimal:
3 e
We can select normal mode, complementary PWM mode, and reset-synchronized PWM mode using ITU3and 4.
This time, as reset-synchronized PWM mode is used it is adjusted to "11". Other bits are described later.
Bit: 7 6 5 4 3 2 1 0
ITU_TOER: − − EXB4 EXA3 EB3 EB4 EA4 EA3
Set value: 0 0 1 1 1 0 0 0
Hexadecimal
3 8
- 58 -
Program Explanation Manual “kit05.c”
Contents of the formal hardware manual are written as it is, but there are lots of difficult expressions. In summary,
If in the manual hence those expressions are not understood well. If reset-synchronized PWM mode is used, PWM
waveform is automatically output from PB5~0. At this time, PWM output can be OFF by setting this register. If
PWM waveform is not necessary, it is preferable to be used as a normal I/O port.
It is rewritten in an easily comprehensible manner.
TOER 7 6 5 4 3 2 1 0
PB5 is a PB4 is a PB1 is a PB3 is a PB2 is a PB0 is a
normal normal normal normal normal normal
When "0" − −
input-output input-output input-output input-output input-output input-output
port port. port. port. port. port.
PB5 is a PWM PB4 is a PWM PB1 is a PWM PB3 is a PWM PB2 is a PWM PB0 is a PWM
When "1" − −
output output output output output output
Setting at
0 0 1 1 1 0 0 0
this time
PB5 is used as PWM for Servo, PB4 is used as PWM for Right motor and PB1 is used as PWM for Left motor.
This time, only the reversing PWM signal is used. Except this, others are used as a normal input-output port.
- 59 -
Program Explanation Manual “kit05.c”
ITU4_CNT It is unused.
Setting of PWM waveform , which is output, from TIOCA3 and TIOCB3 pins.
ITU3_GRB TIOCA3 is a PB0 pin. Waveform of duty ratio set by ITU3_GRB is output from PB0 pin.
TIOCB3 is a PB1 pin and reversing waveform of PB0 pin is output.
Setting of PWM waveform , which is output, from TIOCA4 and TIOCXA4 pins.
ITU4_GRA TIOCA4 is a PB2 pin. Waveform of duty ratio set by ITU4_GRA is output from PB2 pin.
TIOCXA4 is a PB4 pin and reversing waveform of PB2 pin is output.
Setting of PWM waveform , which is output, from TIOCB4 and TIOCX B4 pins.
ITU4_GRB TIOCB4 is a PB3 pin. Waveform of duty ratio set by ITU4_GRB is output from PB3 pin.
TIOCX B4 is a PB5 pin and reversing waveform of the PB3 pin is output.
Output state is explained by the illustration.
0
GRB3 ITU_TOER Current output signal
+1
PB0
GRA3
"0" PB0
+1
CNT3
PB1
PB1
PB2
GRA3
"0" PB2
+1
CNT3
PB4
GRA4 PB4
+1
0
PB3
GRA3
"0" PB3
+1
CNT3
PB5
PB5
Synchro
-nized GRB4+1
1. In reset-synchronized PWM mode, three pairs of complementary PWM waveform are produced with
ITU3_CNT in common.
2. PWM output pins are decided each pins assignment already and pins which affect ITU3_GRB become PB0 and
PB1, pins which affect ITU4_GRA become PB2 and PB4, and pins that affect ITU4_GRB become PB3 and
PB5 respectively. PB0, PB2 and PB3 are PWM waveforms which start from logical level “0”, and PB1, PB4
and PB5 are output reverse/complementary waveform of each pin output.
3. ITU_TOER can select using pin for a PWM output or for an input-output port. This time PB1, PB4 and PB5 are
used. PB0, PB2 and PB3 actually do not output in PWM waveform but those are explained assuming that it is
to be output.
- 60 -
Program Explanation Manual “kit05.c”
0
GRB3 ITU_TOER Current output signal
+1
PB0
GRA3
"1" PB0
+1
CNT3
PB1
PB1
PB2
GRA3
"0" PB2
+1
CNT3
PB4
GRA4 PB4
+1
0
PB3
GRA3
"0" PB3
+1
CNT3
PB5
PB5
GRB4+1
4. Logical level of output waveform of PB0 and PB1reverses when becomes “TU3_CNT=(ITU3_GRB + 1)”. Till
now PB1 was “1” but this time it reverses and becomes “0”. ON width of PB1 becomes period of 1 count of
ITU3_CNT (ITU3_GRB + 1).
0
GRB3 ITU_TOER Current output signal
+1
PB0
GRA3
"1" PB0
+1
CNT3
PB1
PB1
PB2
GRA3
"1" PB2
+1
CNT3
PB4
GRA4 PB4
+1
0
PB3
GRA3
"0" PB3
+1
CNT3
PB5
PB5
GRB4+1
5. Output waveform of PB2 and PB4 reverses when becomes "ITU3_CNT=(ITU4_GRA + 1)". Till now PB4 was
"1" but this time it reverses and becomes "0". ON width of PB4 becomes period of 1 count of ITU3_CNT
(ITU4_GRA + 1).
- 61 -
Program Explanation Manual “kit05.c”
0
GRB3 ITU_TOER Current output signal
+1
PB0
GRA3
"1" PB0
+1
CNT3
PB1
PB1
PB2
GRA3
"1" PB2
+1
CNT3
PB4
GRA4 PB4
+1
0
PB3
GRA3
"1" PB3
+1
CNT3
PB5
PB5
GRB4+1
6. Output waveform of PB3 and PB5 reverses when becomes "ITU3_CNT=(ITU4_GRB + 1)". Till now PB5 was
"1" but this time it reverses and becomes "0". ON width of PB5 becomes
period of 1 count of ITU3_CNT (ITU4_GRB + 1).
GRA3
"0" PB0
+1
CNT3
PB1
PB1
PB2
GRA3
"0" PB2
+1
CNT3
PB4
GRA4 PB4
+1
0
PB3
GRA3
"0" PB3
+1
CNT3
PB5
PB5
GRB4+1
- 62 -
Program Explanation Manual “kit05.c”
When ITU3_CNT=(ITU3_GRA+1)
ITU3_CNT becomes 0.
0
GRB3 ITU_TOER Current output signal
+1
PB0
GRA3
"0" PB0
+1
CNT3
PB1
PB1
PB2
PB3
GRA3
"0" PB3
+1
CNT3
PB5
PB5
GRB4+1
Beside, there are some shortfalls when reset-synchronized PWM mode is used. It is explained.
1 Cycle
To change the duty ratio, ITU3_GRB, ITU4_GRA and ITU4_GRB are rewritten. If rewriting of each general
register and compare match of ITU3_CNT with each general register (ITU3_CNT= each general register+1), are
overlapped, the rewriting of each general register is given priority and so waveform is not reversed because the
compare match is ignored.
- 63 -
Program Explanation Manual “kit05.c”
Value of buffer register automatically transfers to general register after waveform is reversed when buffer
register is to be set for the use. Waveform reverses, moment at the time of which value becomes
ITU3_CNT=(ITU3_GRB + 1). Competition with compare match does not occur because value is written in buffer
register from first to last in the main program.
BRB3
Setting like “Automatic transfer” is a function of ITU_FCR which is explained just before.
- 64 -
Program Explanation Manual “kit05.c”
Since ITU4_GRB is used as duty setting, setting above is assumed to be buffer operation.
Since ITU4_GRA is used as duty setting, setting above is assumed to be buffer operation.
Since ITU3_GRB is used as duty setting, setting above is assumed to be buffer operation.
- 65 -
Program Explanation Manual “kit05.c”
If once ITU3_GRA is set, there is nothing to change because it is used for a period setting register and the period
is constant. Since there is no competition, ITU3_GRA operates normally.
The period is set. Since PWM_CYCLE is set in 49151 by define sentence, this value is assigned.
The PWM output, which is set by ITU3_GRB, is output from PB0 and its reversing signal is output from PB1.
The PB0 is turned off and the left motor drive circuit is connected with PB1. The value “0” is written because at
the first, the motor is stopped. At the same time buffer register is cleared. This is a one time limit to write the value
in ITU3_GRB.
PWM output signal and its reversing signal are output from PB2 and PB4 that are set by ITU4_GRA. PB2 is OFF
and the right motor drive circuit is connected with PB4. Value “0” is written as at the beginning, the right motor is
kept stopped. Buffer register is also cleared at the same time. This is a one time limit to write the value in
ITU4_GRA.
PWM output signal and its reversing signal are output from PB3 and PB5 that are set by ITU4_GRB. PB3 is OFF
and the Servo is connected with PB5. At the beginning, center value is written, as it is preferable to point the
steering in straight direction. Buffer register is also written at the same time. This is a one time limit to write the
value in ITU4_GRB.
- 66 -
Program Explanation Manual “kit05.c”
0% cannot be output
The value “0” is set in ITU3_GRB which duty ratio is decided, because it is to be 0%. ITU3_GRA is assumed to
be 999.
1Cycle 1 Cycle
Output waveform
Perfect 0% is not possible like this. Always during 1 count of ITU3_CNT becomes ON. Since at this time it is
period of 16 [ms], it can be entirely ignored as using motor control, becaused it is (325.52 10-9) / (16 10-3) =
0.00002 = 0.002%. It is no problem that we say it 0%.
Since it is to be 100% duty ratio, ITU3_GRA’s value which is corresponding with the period of this PWM
waveform, is set in ITU3_GRB. ITU3_GRA is assumed to be 999.
1Cycle 1 Cycle
Output waveform
Reverse by (ITU3_CNT=(GRB+1)=(999+1)=1000
and ITU3_CNT=(GRA+1)=(999+1)=1000).
Reversing is done only once because it agrees at the
same time.
- 67 -
Program Explanation Manual “kit05.c”
When the values of ITU3_GRA (cycle) and ITU3_GRB (duty ratio) are the same like this, the corresponding
timing with ITU3_CNT becomes the same and reversing is carried out only once. It becomes waveform, which is
not the PWM of cycle 16 [ms] and waveform of the result becomes, 1 cycle 0%, next 1 cycle 100%.
1 cycle 1 cycle
Output waveform
Thus, 100% completion cannot be output. Always one count of ITU3_CNT becomes OFF.
The right motor, left motor and servo are controlled with any consideration for these.
- 68 -
Program Explanation Manual “kit05.c”
When this function is called, waiting is done in this line. As a usage method, numerical value is input in the
argument of the timer function in milliseconds.
413 : /************************************************************************/
414 : /* Timer main unit */
415 : /* Argument Timer value 1=1ms */
416 : /************************************************************************/
417 : void timer( unsigned long timer_set )
418 : {
419 : cnt0 = 0;
420 : while( cnt0 < timer_set );
421 : }
For instance, if it is assumed that the argument is 1000, timer_set becomes 1000. It becomes
as cnt0 becomes 0 on 419th line. In such cases, continuation conditional expression in brackets is always satisfied,
and there seems to be no further process. Recall the place where cnt0 is operated. cnt0 does +1 by generating the
interrupt of each 1ms in the middle of executing interrupt_timer0 function. Hence after 1ms it becomes
420 : while( 1000 < 1000 ); <-The continuation conditional expression does not come into effect!!
and the expression in this brackets is judged as false (not consisted) and goes to the next line. As a result, flow of
program execution waits for 1000ms at 420th line. And the role of the timer is done according to the name of the
function.
For instance, if waiting of 2 seconds is preferred, it becomes
timer ( 2000 );
- 69 -
Program Explanation Manual “kit05.c”
This function reads “White”, “Black” information from sensor board. Argument is a value by which the sensor is
masked.
423 : /************************************************************************/
424 : /* Sensor state detection */
425 : /* Argument Mask value */
426 : /* Return value Sensor value */
427 : /************************************************************************/
428 : unsigned char sensor_inp( unsigned char mask )
429 : {
430 : unsigned char sensor;
431 :
432 : sensor = P7DR;
433 :
434 : /* Since bit0 is for left and bit7 is for right in the new sensor board which is reversed */
435 : /* to the previous sensor board, the bit has been replaced to maintain compatibility. */
436 : sensor = bit_change( sensor ); /* Bit replacement */
437 : sensor &= mask;
438 :
439 : return sensor;
440 : }
State of sensor
00011111
P7DR 11111000
Reading
sensor 11111000
If the sensor state is read, it is "00011111", but which is being actually read is the reversing of left and right
i.e."11111000". Sensor bit position and reading bit position is in reverse, i.e. right of sensor bit position is left of
reading bit position.
436 : sensor = bit_change( sensor );
Still, if the state is "00011111", it is clear that it is easy to consider also in program as "0001111". Right and left
can be replaced in program for this purpose. It is bit_change function, which does this replacing operation.
"sensor" in the beginning is value after conversion and "sensor" in the bracket is value before conversion.
- 70 -
Program Explanation Manual “kit05.c”
State of sensor
00011111
P7DR 11111000
Reading
sensor 11111000
Sensor is replaced by
bit_change function.
sensor 00011111
"sensor" is covered with the mask. Checked sensor state must be minimized by compulsorily making the bit other
than the examined bit to "0".
The unit of 1 port is 8 bits therefore it cannot be checked only by 1 bit (It is possible if the method called as bit
field is used and here it is not used). It becomes a check of group 8 bits.
For instance, when checking that bit 7 at the left end of sensor is “1” or not, if it is done as
It is considered OK. However, we can’t understand whether the value of bit 6~0 will become “1” or 0”.
For instance, if bit 7 is “1” and bit 0 is also “1”, then it becomes
Sensor value = 10000001(Binary number)=0 x 81(Hexadecimal number)
It cannot be judged whether bit 7 is "1" or “0”, only by checking if it is 0 x 80 in program. In such cases, operation
called "Mask" is done, as it is not possible to check properly. When they say mask, it is the one associated with
mask that is used at the time of having cold. The mask for the cold is used to prevent the bacteria from spreading,
however the mask mentioned here resembles in only the physical appearance of the mask. If mask is put on mouth
cannot be seen. It is hidden. The mask mentioned here has only the meaning “Cover”.
In the previous example, only bit 7 is required to know because other bits (from bit0 to 6) are covered by having
mask and covered up, in other words it is made to ignore.
- 71 -
Program Explanation Manual “kit05.c”
Then, how to ignore it? In actual control, it is only made compulsorily “0”.
In the program, the logical multiplication (product) of the logical operation, that is, logical AND is done.
Logical AND is an operation in which, “1” is output when both A and B are “1” (each numerical value of “0” or
”1”). A is considered as sensor value.
A(Sensor value) B A and B
0 0 0
0 1 0
1 0 0
1 1 1
Even if A (sensor value) may be in any value , when B is "0", the result is sure to become "0".
Next, note when B is “1”.
A(Sensor value) B A and B
0 1 0
1 1 1
Thus, mask must compulsorily make the unnecessary bit "0" by logical AND.
For instance, when sensor state is "black black black white white white white white", sensor value is "00011111".
It is assumed that only bit 2 and bit 1 are necessary to check and other are not necessary.
bit 7 6 5 4 3 2 1 0
Unnecessary Unnecessary Unnecessary Unnecessary Unnecessary Necessary Necessary Unnecessary
Mask value of unnecessary bit is made "0" and logical AND is done to adjust the unnecessary part to "0".
Therefore, mask value only has to rewrite unnecessary part on "0" and necessary part on "1" of the above table.
bit 7 6 5 4 3 2 1 0
Mask
0 0 0 0 0 1 1 0
value
If "00000110" is converted in Hexadecimal number, it becomes "0 x 06". The table below is the calculation
method and the result.
State of sensor
00011111
Sensor value 00011111
Mask value 00000110 )AND
- 72 -
Program Explanation Manual “kit05.c”
For instance, it becomes as follows when it is required to check whether bit 2 ="1", bit 1 = "0" or not.
Only bit 2 and bit 1 can be examined with ease because it is known that bits other than bit 2 and bit 1 become "0"
compulsorily by mask.
Mask pattern
It is explained that the mask value is put in the argument of the sensor_inp function. Actually, the mask value is
limited in case of creating program of the micom car. It is defined in advance.
"MASK _ " means that the number of “1” on the left side are bits, and the number of “1” on the right side are
bits and the remaining are made compulsorily “0”.
It can be rewritten as
because the mask pattern that checks previous bit2 and bit1 is as per the above table “MASK0_2”.
- 73 -
Program Explanation Manual “kit05.c”
The bit is changed by "bit_change function" and "bit_change function" is used in the sensor_inp function, so
"bit_change function" is also explained along with this. Argument “in” is the 8_bit value before changing the bit.
The return value is a value after changing the bit.
546 : /************************************************************************/
547 : /* Bit change */
548 : /* Argument Value to be changed */
549 : /* Return value Changed value */
550 : /************************************************************************/
551 : char unsigned bit_change( char unsigned in )
552 : {
553 : unsigned char ret;
554 : int i;
555 :
556 : for( i = 0; i < 8; i++ ) {
557 : ret >>= 1; /* Right shift of return value */
558 : ret |= in & 0x80; /* Ret bit7 = in bit7 */
559 : in <<= 1; /* Left shift of argument */
560 : }
561 : return ret;
562 : } Range repeated with for
554 : int i;
Variable "i" for working
560 : }
Close bracket of loop in “for statement”. Rows 557~559 are repeated.
- 74 -
Program Explanation Manual “kit05.c”
For instance, when 0xf8 is changed right for left and the function is called as below,
c = bit_change( 0xf8 );
0x1f is substituted for variable c. Calculation process becomes an image like the figure below.
i in ret Explanation
11111000 10000000 Bit7 of “in” and bit7 of “ret” are operated in logical
OR.
01000000 “ret” shifts to the right, the prior “1” moves to bit6 and
1 → “0” is inserted in bit7.
11110000 11000000 Bit7 of “in” and bit7 of “ret” are operated in logical
OR.
11100000 “in” shifts one bit to the left, “0” is entered in bit0.
←
…
00011111 “ret” shifts to the right, prior “0” moves to the bit6,
7 → “0” is inserted in bit7.
00000000 00011111 Bit7 of “in” and bit7 of “ret” are operated in logical
OR. No change since bit7 of “in” is “0” and also bit7
of “ret” is “0”.
00000000
← “in” shifts one bit to the left, “0” is entered in bit0.
The bit change is completed, and “0x1f" of the return value is substituted in variable c.
- 75 -
Program Explanation Manual “kit05.c”
There are 2 crosslines before 50cm ~ 100cm of crank. These are called crosslines. A special function to detect this
crossline was created. The return value is, "1" if there is crossline and "0" if no crossline.
442 : /************************************************************************/
443 : /* Crossline detection processing */
444 : /* return value 0: no crossline 1: crossline exists */
445 : /************************************************************************/
446 : int check_crossline( void )
447 : {
448 : unsigned char b;
449 : int ret;
450 :
451 : ret = 0;
452 : b = sensor_inp(MASK2_2);
453 : if( b==0x66 || b==0x64 || b==0x26 || b==0x62 || b==0x46 ) {
454 : ret = 1;
455 : }
456 : return ret;
457 : }
451 : ret = 0;
Variable “ret” in which the return value is saved has been initialized. If it is judged as crossline, “1” is entered in
this variable and if as no crossline, “0” is entered in this variable. Since at present it is unknown, it is temporarily
judged as no crossline and “0” is entered.
452 : b = sensor_inp(MASK2_2);
The sensor is read, and saved in variable b. Since the mask value of the sensor is "MASK2_2=0x66", 4 sensors,
such as left middle 2 and right middle 2 are read as shown below.
- 76 -
Program Explanation Manual “kit05.c”
0x 6 6
0 1 1 0 0 1 1 0
0x 6 4 0x 62
0 1 1 0 0 1 0 0 0 1 1 0 0 0 1 0
0 x2 6 0x 46
0 0 1 0 0 1 1 0 0 1 0 0 0 1 1 0
When sensor board enters to clossline from the direct front and sensor input-pattern become to 0x66, all 4 sensors
become "1" and this is judged unquestionably a crossline. When sensor-pattern is 0x64 or 0x26, the board enters
obliquely from left or right, and it is judged as crossline since more than 3 have become "1". When sensor-pattern
is 0x62, it seems 0x64 or 0x66 in the figure. The sensor can adjust the sensitivity by the volume. It is not a
problem if it is adjusted such that all sensors light up at the same time under the same condition but, when the
sensitivity of the second sensor from the right (shown with the arrow in figure 0x62) is weak due to insufficient
adjustment; the state of the sensor is judged to be 0x62 and not 0x64. However, 0x62 is also included as the
sensor-pattern of detected clossline because there is no problem as shown in figure. 0x46 is also similar.
459 : /************************************************************************/
460 : /* Reading of DIP switch value */
461 : /* Return value Switch value 0 ~15 */
462 : /************************************************************************/
463 : unsigned char dipsw_get( void )
464 : {
465 : unsigned char sw;
466 :
467 : sw = ~P6DR; /* Reading of DIP switch */
468 : sw &= 0x0f;
469 :
470 : return sw;
471 : }
- 77 -
Program Explanation Manual “kit05.c”
For instance, it is assumed the state of DIP switch to be OFF, OFF, ON, and ON.
c = dipsw_get();
The function is called like above statement. In this case, it becomes an image like the figure below.
0x03 is entered in variable c.
Read
P6DR ????1100
P63
P62
P61
P60
OFF sw ????0011
Mask
ON
sw 00000011
State of switch
Return value
sw 00000011
It is a function which reads the state of the push switch of the motor drive board. The push switch circuit is as
follows.
To CPU board
The push switch circuit is connected with bit 0 of port B. In the circuit, when the push switch is ON, bit 0 is input
"0" and when OFF, bit 0 is input "1". But this function must be such that return value becomes “1” when switch is
ON and "0" when switch is OFF.
- 78 -
Program Explanation Manual “kit05.c”
473 : /************************************************************************/
474 : /* Push switch value reading */
475 : /* Return value Switch value ON: “1” and OFF: “0” */
476 : /************************************************************************/
477 : unsigned char pushsw_get( void )
478 : {
479 : unsigned char sw;
480 :
481 : sw = ~PBDR; /* Reading of port having a push switch */
482 : sw &= 0x01;
483 :
484 : return sw;
485 : }
PBDR
7 ?
6 ?
5 ? PBDR ? ? ? ? ? ? ? 0
Inversion
4 ?
sw ? ? ? ? ? ? ? 1
3 ?
Mask
Return
2 ? 0 0 0 0 0 0 0 1
Value
ON
1 ?
0 0
Push ? something unknown
switch
- 79 -
Program Explanation Manual “kit05.c”
Three LEDs are attached to the motor drive board. Out of those, two LEDs can be switched ON/OFF by the
microcomputer.
LED1 LED0
To CPU board
Glows when power
supply is given
It is connected with bit7 and bit6 of port B. LED connected with bit7 is "LED1" in the program and LED
connected with bit6 is "LED0" in the program.
In this function, the argument and method of lighting LED is as shown in the following table.
In short, when the argument is made a binary number, the first digit is made for control of LED0 and second digit
for LED1. It is switched off when signal is "0"and switched on when signal is "1".
487 : /************************************************************************/
488 : /* LED control */
489 : /* Argument Switch value (LED1, LED0) = (bit1 : bit0) :"0": OFF, "1": ON */
490 : /* Example 0x3->(LED1, LED0)=(ON, ON) : 0x2->(LED1, LED0)=(ON, OFF) */
491 : /************************************************************************/
492 : void led_out( unsigned char led )
493 : {
494 : unsigned char data;
495 :
496 : led = ~led;
497 : led <<= 6;
498 : data = PBDR & 0x3f;
499 : PBDR = data | led;
500 : }
- 80 -
Program Explanation Manual “kit05.c”
For example,
led_out ( 0x02 );
function is assumed to be called. In this case, it becomes an image like the figure below. LED1 is ON, LED0 is
OFF.
led data
0 0 0 0 0 0 1 0 Value of port B LED1 LED0
PBDR
Inversion by “~” Read
0 7
1 1 1 1 1 1 0 1 ? ? ? ? ? ? ? ?
ON! OFF
1 6
Mask of 0x3f
6 bit shift
0 1 0 0 0 0 0 0 0 0 ? ? ? ? ? ? ? 5
? 4
Logical OR
? 3
? 2
0 1 ? ? ? ? ? ?
? 1
? 0
?is no change
- 81 -
Program Explanation Manual “kit05.c”
It is a function which controls the left motor and right motor. The argument can be set from 100 to -100 and
normal rotation 100% corresponds to argument value “100”, reverse rotation 100% corresponds to argument
value “-100”, and braking state corresponds to argument value “0”.
The connection of the motor drive board is confirmed again.
Signal,
Pin no. Details “0” “1” Details
direction
1 - +5V
2 board<-PB7 LED1 ON OFF
3 board<-PB6 LED0 ON OFF
Duty ratio setting by
4 board<-PB5 Servo signal PWM signal
ITU4_BRB
Duty ratio setting by
5 board<-PB4 Right motor PWM Stop Operate
ITU4_BRA
Direction of right Normal Reverse
6 board<-PB3
motor rotation rotation rotation
Direction of left Normal Reverse
7 board<-PB2
motor rotation rotation rotation
Duty ratio setting by
8 board<-PB1 Left motor PWM Stop Operate
ITU3_BRB
9 board->PB0 Push switch Pushed Not pushed
10 - GND
As shown in the figure, PB4 is for right motor PWM, PB1 is for left motor PWM, PB3 is for rotation direction
control of right motor, and PB2 is for rotation direction control of left motor. Moreover, since reset-synchronized
PWM mode is used, the value of ITU4_BRA is changed to change the duty ratio of PB4 and the value of
ITU3_BRB is changed to change the duty ratio of PB1.
Buffer is ITU3_BRB
0
GRB3 ITU_TOER
+1
PB0
+1
CNT3
PB1
PB1 To left motor
PB2
+1
CNT3
PB4
GRA4 PB4 To right
+1 motor
0
Buffer is ITU4_BRA
PB3
interlock GRB4+1
- 82 -
Program Explanation Manual “kit05.c”
502 : /************************************************************************/
503 : /* Speed Control */
504 : /* Argument Left motor: -100 ~ 100 , Right motor: -100 ~ 100 */
505 : /* 0:Stop,100:normal rotation 100%,-100:Reverse 100% */
506 : /************************************************************************/
507 : void speed( int accele_l, int accele_r )
508 : {
509 : unsigned char sw_data;
510 : unsigned long speed_max;
511 :
512 : sw_data = dipsw_get() + 5; /* DIP switch read */
513 : speed_max = (unsigned long)(PWM_CYCLE-1) * sw_data / 20;
514 :
515 : /* Left motor */
516 : if( accele_l >= 0 ) {
517 : PBDR &= 0xfb;
518 : ITU3_BRB = speed_max * accele_l / 100;
519 : } else {
520 : PBDR |= 0x04;
521 : accele_l = -accele_l;
522 : ITU3_BRB = speed_max * accele_l / 100;
523 : }
524 :
525 : /* Right motor */
526 : if( accele_r >= 0 ) {
527 : PBDR &= 0xf7;
528 : ITU4_BRA = speed_max * accele_r / 100;
529 : } else {
530 : PBDR |= 0x08;
531 : accele_r = -accele_r;
532 : ITU4_BRA = speed_max * accele_r / 100;
533 : }
534 : }
1 2 3
sw_data(5 ~ 20)
speed_max = (unsigned long) Value when 100%
20
1 Since 2 is PWM_CYCLE-1, it becomes 49151-1=49150. Since the numerator of 3 is 20 or less and 5 or more,
it becomes 49150 20=983000. Since the (unsigned int) type range is exceeded, correct calculation is not
possible as it becomes over flow when it becomes more than 65536. Therefore, it is temporarily converted into
the unsigned long type. The calculation result does not exceed 65536 and also must not exceed during the
calculation.
2 100% is set as 1 small value than ITU3_GRA as explained in reset-synchronized PWM mode setting. Since
PWM_CYCLE is a value set in ITU3_GRA, the value PWM_CYCLE - 1 becomes the 100% value.
3 The ratio of the maximum speed is changed by the DIP switch. The ratio is as follows.
- 83 -
Program Explanation Manual “kit05.c”
It is left motor control. First of all, it is checked whether accele_l, which is the argument of left motor PWM of the
speed function, is 0 or more. If it is more than 0, bit 2 for the left motor rotation direction control is made "0"
because it is normal rotation.
Bit 7 6 5 4 3 2 1 0
PBDR before
? ? ? ? ? ? ? 1
change
AND value 1 1 1 1 1 0 1 1 ->0 xfb
PBDR after
0
change
= no change
Next, the duty ratio is set. Though setting is carried out by ITU3_GRB, in appearance, buffer register changes
the setting instead of general register in the program. The buffer of ITU3_GRB becomes ITU3_BRB.
It becomes,
ITU3_BRB =(Value substituted for buffer register corresponding to ratio of DIP switch)
(% of speed function) ÷100
= speed_max accele_l ÷100
The point is, the ratio set by the speed function is not output to the motor but "DIP switch ratio ratio set by
speed function" is output to the motor.
- 84 -
Program Explanation Manual “kit05.c”
Next is explained about “ else statement”. When the judgment of the 516th line does not be applied, this part is
executed. Since the judgment is “Is accele_l 1 or more?”, when else statement is executed, “accele_l” is less
than 0, that is to say, “accele_l” is minus.
Bit 2 for the left motor rotation direction control is made “1” because left motor rotation is reversed. Logical
OR operation is used to make only bit2 as “1”.
Bit 7 6 5 4 3 2 1 0
PBDR before
? ? ? ? ? ? ? 1
change
OR value 0 0 0 0 0 1 0 0 -> 0x04
PBDR after
1
change
= no change
Next, the duty ratio is set. The sign has been changed into the plus on the 521th line before calculation because
accele_l is minus. Next, the duty ratio is set in ITU3_BRB same as before.
After left motor, about right motor control is explained. First of all, it is checked whether accele_r, which is the
argument of right motor PWM of the speed function, is 0 or more. If it is more than 0, bit 3 for the right motor
rotation direction control is made "0", because right motor rotates normally.
Bit 7 6 5 4 3 2 1 0
PBDR before
? ? ? ? ? ? ? 1
change
AND value 1 1 1 1 0 1 1 1 -> 0xf7
PBDR after
0
value
= no change
Next, the duty ratio is set. Though setting is carried out by ITU4_GRA, in appearance, buffer register changes the
setting instead of general register in the program. The buffer of ITU4_GRA becomes ITU4_BRA.
It becomes,
ITU4_BRA =(Value substituted for buffer register corresponding to ratio of DIP switch)
(% of speed function) ÷100
= speed_max accele_r ÷100
The point is, the ratio set by the speed function is not output to the motor but "DIP switch ratio ratio set by
speed function" is output to the motor.
- 85 -
Program Explanation Manual “kit05.c”
Next is explained about “ else statement”. When the judgment of 526th line does not be applied, this part is
executed. Since the judgment is “Is accele_r 1 or more?”, when else statement is executed, “accele_r” is less
than 0, that is to say, “accele_r” is minus.
Bit 3 for the right motor rotation direction control is made “1” because right motor rotation is reversed. Logical
OR operation is used to make only bit 3 as “1”.
Bit 7 6 5 4 3 2 1 0
PBDR before
? ? ? ? ? ? ? 1
change
OR value 0 0 0 0 1 0 0 0 -> 0x08
PBDR after
1
change
= no change
Next, the duty ratio is set. The sign has been changed into the plus in 531th line before calculation because accele_r
is minus. Next, the duty ratio is set in ITU4_BRA same as before.
For example, assume that the following program was executed.
0 0 1 1 When the DIP switch is as shown in the figure, since the value read from the
switch is 3,
P63
P62
P61
P60
Because one cycle is 16 ms, the time interval of operation becomes as the following.
Left motor->4.48[ms] normal rotation, 11.52[ms] brake
Left motor->6.40[ms] normal rotation, 9.60[ms] brake
In motor drive board Vol.3, when the motor stops, the operation is only brake. There is no free (open) state.
- 86 -
Program Explanation Manual “kit05.c”
This is a function which controls the angle of the servo. Though the argument is in range of -90 to 90 degree of the
servo rotating angle, since servo does not actually rotate to that extent, practical range is thought to be -45 to 45
degree.
536 : /************************************************************************/
537 : /* Servo steering operation */
538 : /* Argument Servo operation angle: -90 ~ 90 */
539 : /* -90: 90o to the left turn ,0: straight ,90: 90o to the right turn */
540 : /************************************************************************/
541 : void handle( int angle )
542 : {
543 : ITU4_BRB = SERVO_CENTER - angle * HANDLE_STEP;
544 : }
Signal,
Pin no. Details “0” “1” Details
direction
1 - +5V
2 board<-PB7 LED1 ON OFF
3 board<-PB6 LED0 ON OFF
Duty ratio is set with
4 board<-PB5 Servo signal PWM signal
ITU4_BRB
Duty ratio is set with
5 board<-PB4 Right motor PWM Stop Operation
ITU4_BRA
Right motor rotation Normal Reverse
6 board<-PB3
direction rotation rotation
Left motor rotation Normal Reverse
7 board<-PB2
direction rotation rotation
Duty ratio is set with
8 board<-PB1 Left motor PWM Stop Operation
ITU3_BRB.
9 board->PB0 Push switch Pushed Not pushed
10 - GND
As shown in the table, PB5 is for servo control. Since reset-synchronized PWM mode is used, the value of
ITU4_BRB is changed to change the duty ratio of PB5.
SERVO_CENTER is center value of the servo. The only angle value which is set in variable “angle”, is increased
or decreased from center value. However, one unit of ITU4_BRB is not one degree. In HANDLE_STEP, there is a
value corresponding to 1o. Therefore, variable “angle” is multiplied by HANDLE_STEP.
- 87 -
Program Explanation Manual “kit05.c”
It is the Main function. It is called from the start-up routine and for the first time, the program of C language is
executed from here.
69 : /************************************************************************/
70 : /* Main Program */
71 : /************************************************************************/
72 : void main( void )
73 : {
74 : int i;
75 : int pattern;
76 :
77 : /* Initialization of microcomputer function */
78 : init(); /* Initialization */
79 : set_ccr( 0x00 ); /* Whole interrupt enable */
80 :
81 : /* State initialization of micom car*/
82 : handle( 0 );
83 : speed( 0, 0 );
84 : pattern = 0;
85 : cnt1 = 0;
78 : init(); /* Initialization */
The “init” function is executed, and the I/O register of the built-in peripheral function of H8/3048F-ONE is
initialized.
Bit: 7 6 5 4 3 2 1 0
CCR: I UI H U N Z V C
Set value: 0 - - - - - - -
Hexadecimal
number:
0 0
CCR cannot be directly accessed in C program unlike the variable, because it is a register in CPU. Therefore, the
function which operates the value is prepared. This function is “set_ccr”. This function is defined in the machine.h
file. Therefore, this C program includes the machine.h file for this purpose. If the contents of machine.h are shown,
the description is,
The argument of an unsigned char type is substituted. Though it is good that only bit7 is made "0", since there is
no influence here even if "0" is written in the rest, 0x00 is substituted..
- 88 -
Program Explanation Manual “kit05.c”
I
CCR 0 0 0 0 0 0 0 0
ITU0
ITU0_IER 0 0 0 0 0 0 0 1
"1" Interrupt is
generated!!
ITU0_TSR 0 0 0 0 0 0 0 1
ITU1
Communication
A/D
etc...
Kit05.c is a method of executing the program by branching to the pattern number. The pattern number is decided
beforehand according to the number set in the pattern variable.
For example, pattern 0 is “switch input wait processing”, and pattern 1 is “wait for 1 second processing” after
switch is pushed---etc. If this method is used, since the program is divided into each pattern, it becomes easy to
understand. The pattern method can be said, "Making the program into blocks".
Even when adding a new function, it becomes easy to remodel to add the program by allocating a new number.
Hereafter, outline, actual operation, remodeling example of pattern method are shown.
- 89 -
Program Explanation Manual “kit05.c”
3.2.2. First part of pattern method (while statement and switch statement)
87 : while( 1 ) {
88 : switch( pattern ) {
107 : case 0:
Process at pattern 0
121 : break;
122 :
123 : case 1:
Process at pattern 1
135 : break;
Pair Pair
Each pattern process
357 : default:
358 : /* When it is not any pattern, return to standby state. */
359 : pattern = 0;
360 : break;
361 : }
362 : }
"While (expression)" is a control statement executing next command beyond put-together (bundled) command in
{ } if the value of the expression is " false ", and inner command in { } if the value of the expression is "true".
- 90 -
Program Explanation Manual “kit05.c”
The microcomputer becomes uncontrollable by going to the area where program is not written when it ends the
program without doing end process appropriately. As for the microcomputer, it does not end by repeating the thing
that to do not do anything (infinite loop), and stops the moving operation in low power consumption mode which
is called sleep mode and it is usual to wait for the timing which returns by any trigger.
The pattern decided by kit05.c and its content are summarized here.
Thus the pattern number and process contents are decided and program is created.
As per the remarks column, number 0 level is a process before program run and number 10 level is a process of
usual program run and it becomes easy to understand when brief process contents are decided at each number 10
level.
In kit04.c, pattern 23 is "Trace and crank detection after crossline" and pattern 24 is not there. In kit kit05.c,
process is done by dividing in pattern 23 and 24.
- 91 -
Program Explanation Manual “kit05.c”
The flow of the pattern is summarized in the flow chart below. It is easy to grasp problem if we created and
analyze the program with considering the flow of pattern always.
Program start
Pattern 0
switch input waiting
Pattern 1
1 second waiting
Pattern 12 Pattern 13
Crossline Check of large right Check of large left
bending end Large bend end. bending end Large bend end
detection
Crossline detection Crossline detection
Pattern 21
Process at the time of first
crossline detection
Pattern 22
2nd crrossline is
skipped
Pattern 23
The first of trace after
crossline
Pattern 24
Crank detection and the
second of trace after
crossline
Pattern 32 Pattern 42
Check of left crank Check of right crank
bending end bending end
- 92 -
Program Explanation Manual “kit05.c”
Here, it is a state to wait for input of switch. If switch is pushed, the flow of the program shifts to pattern 1, else
LED0 and LED1 are made to glow alternately because we cannot understand whether CPU is stopped or CPU is a
state of really waiting. First of all switch detection part is shown below.
case 0:
/* Switch input waiting */
if( pushsw_get() ) {
pattern = 1;
cnt1 = 0;
break;
}
If the switch is pushed, the value of “pushsw_get” function becomes “1”, and the value is judged “True”. And
statements in brackets are executed. Then, “pattern” becomes 1.
The program, which blinks LED, is added after this. Blinking is adjusted to repeated process of 0.1 second LED0
lights and for next 0.1 second LED1 lights.
Ordinary variable which is called local variable, for instance pattern variable, if set once, does not change value
until changed for the next time. In kit05.c, only the cnt0 variable and the cnt1 variable are exceptions, and they are
called global variable. Cnt0 and cnt1 are done +1 in the interrupt_timer0 function. The interrupt_timer0 function is
executed at each 1ms. Therefore, time can be measured by using this variable.
If the switch detection and LED blinking program are combined, it becomes the program as follows.
107 : case 0:
108 : /* Switch input waiting */
109 : if( pushsw_get() ) {
110 : pattern = 1;
111 : cnt1 = 0;
112 : break;
113 : }
114 : if( cnt1 < 100 ) { /* LED blinking process */
115 : led_out( 0x1 );
116 : } else if( cnt1 < 200 ) {
117 : led_out( 0x2 );
118 : } else {
119 : cnt1 = 0;
120 : }
121 : break;
Break statement of 121st line is the statement for ending the case 0.
- 93 -
Program Explanation Manual “kit05.c”
In case timer function is used without using cnt1, what will be the case?
Statements which are shown with arrow and include two “timer()” functions, correspond to the statements from
114th line to 121st line in “kid05.c”.
if( pushsw_get() ) {
pattern = 1;
cnt1 = 0;
break;
}
timer( 100 );
led_out( 0x1 );
timer( 100 );
led_out( 0x2 );
break;
It became simple. This method may be preferable. However, timer function does not do anything except waiting.
Therefore, if the switch is pushed for a split second during execution of “timer( )” function, the switch is not
pushed already when “pushsw_get( )” function that checks the switch is called. Here is a possibility of the missing
detection of the pushing the switch. Since it is 0.2 seconds in this program, there is no missing as far as the
pushing of 0.2 or more seconds is operated. But, if the timer of second order is used ( e.g. timer(2000); ), the
missing error must be happened because the time of not checking the switch becomes too much.
Simply, it is routine to wait for 1 second after the switch is pushed. It is made to wait a little because there is a
possibility that when the micom car runs out rapidly after pushing the switch it may collide with the hand which
pushed the switch. Since waiting idle is boring (gets on nerves), LED0 lights for 0.5 seconds, and LED1 lights
for 0.5 seconds and then the micom car starts.
121 : case 1:
122 : /* 1 second waiting after the switch is pushed */
123 : if( cnt1 < 500 ) {
124 : /* 1.0 seconds starting ago LED1: "OFF",LED0: "ON" */
125 : led_out( 0x1 );
126 : } else if( cnt1 < 1000 ) {
127 : /* 0.5 seconds starting ago LED1: "ON",LED0: "OFF" */
128 : led_out( 0x2 );
129 : } else {
130 : /* Start!! */
131 : led_out( 0x0 );
132 : pattern = 11;
133 : cnt1 = 0;
134 : }
135 : break;
- 94 -
Program Explanation Manual “kit05.c”
- 95 -
Program Explanation Manual “kit05.c”
Moreover, there is a crossline in the course of the micom car. Since there is check_crossline function which
detects the crossing line, it is used.
Left Right
Value when Hexadecimal Steering
State of course and sensor motor motor
sensor is read number angle PWM PWM
● Sensor Reading
The state of the sensor is read. Since 3 right and 3 left sensors are read, MASK3_3 is used.
●Direct Advance
The sensor is in the state of “0x00". This state is a state which advances straight as shown in the figure below.
Micom car advances by servo angle 0°, left motor 100%, right motor 100%.
0 0 0 0 0 0 0 0
- 96 -
Program Explanation Manual “kit05.c”
The sensor is in the state of “0x04". This state is a state in which the micom car is slightly coming towards left as
shown in the figure below. The servo advances by 5° to the right, left motor 100%, right motor 100% and the
micom car comes near the center.
0 0 0 0 0 1 0 0
The sensor is in the state of “0x06". This state is a state in which the micom car is coming a little towards the left
as shown in the figure below. The servo advances by 10° to the right, left motor 80%, right motor 69% and the
micom car comes near to the center while decelerating.
0
0 0 0 1 1
0 0
- 97 -
Program Explanation Manual “kit05.c”
The sensor is in the state of “0x07". This state is a state in which the micom car is coming towards left from the
middle veering as shown in the figure below. The servo advances by 15° to the right, left motor 50%, right motor
40% and the micom car comes near to the center while decelerating.
0 0 1 1 1
0 0 0
0 1 1
0 0 0
0 0
- 98 -
Program Explanation Manual “kit05.c”
The sensor state is “0x20”. In this state the micom car is slightly coming towards right as shown in the figure
below. The servo advances by 5° to the left, left motor 100%, right motor 100% and the micom car comes near to
the center.
0 0 1 0 0 0 0 0
The sensor state is “0x60". In this state the micom car is coming a little towards the right as shown in the figure
below. The servo advances by 10° to the left, left motor 69%, right motor 80% and the micom car comes near the
center while decelerating.
0 1 1
0 0 0
0 0
- 99 -
Program Explanation Manual “kit05.c”
The sensor state is “0xe0”. In this state the micom car is coming a little to the right as shown in the figure below.
The servo advances by 15° to the left, left motor 40%, right motor 50% and the micom car comes near the center
while decelerating.
1 1
1 0
0 0
0 0
1 1
0 0
0 0
0 0
- 100 -
Program Explanation Manual “kit05.c”
●Crossline Check
When the return value of check_crossline function is “0”, there is no crossline, when the value is “1”, the first
crossline has been detected. When the crossline is detected the pattern is adjusted to 21 and the switch-case
statement is ended by the break statement. Since the crossline check is important, the check is placed first in
pattern 11, pattern 12, and pattern 13.
●Other
202 : default:
203 : break;
When it is other than the patterns up to now, it jumps to this default part. Nothing is done.
- 101 -
Program Explanation Manual “kit05.c”
Sensor state 0x03 is sensor detection state when the micom car is coming greatly to the left. Therefore, when the
micom car is expanded by the curve any further, there is possibility of the car becomes like the figure below.
1 1 0 1
0 0 0 0 0
0 0 0
0 0 1 0
Steering comes
off the axle!
Even though there is a large incline towards the left, in the program there is a wrong judgment of "large inclined
to the right". Since the servo turns in the opposite direction when wrong judgment is done, the wheel jumps from
the course.
Here, when large turn is done to the right, the steering keeps turning largely to the right until the micom car is
returned back to a certain state of the sensor. Judging place of this “certain state of the sensor” is pattern 12.
- 102 -
Program Explanation Manual “kit05.c”
In pattern 12, let’s consider how the state is evolved to return to the normal run pattern 11.
0 0
0 0 0
1 1 1 1 0
0 0 0
0 0
0
0
1 0
0 0 0 0 0
0 0 0 0 0
0 1 1
1 0
0 0 1
0 0 0
When the program is set such that it returns to the pattern 11 and sensor state becomes 0x06, the misunderstanding
like the previous one can be avoided.
Though we consider that the program is complete, remember that crossline check was carried out in pattern 11.
Is it not necessary in pattern 12?
- 103 -
Program Explanation Manual “kit05.c”
0 0 0 0 0 0 1 1
1
1
0
0 0
0
0
0
1 1 1 0
0 1 1 1
If the micom car plunges into the crossline
in the state of 0x03 and if there is no crossline check,
the state is judged as the processing of other than 0x06.
And it passes through without notice and the wheel jumps
from the course.
Thus the crossline is occasionally detected even during processing in pattern 12. Therefore, the program for
crossline detection part is put in pattern 12.
- 104 -
Program Explanation Manual “kit05.c”
1 0
1 1 0 0
0 0 0 0
0 0 0 1
0 0
State 0xc0 at the time of large turn Inclined more to the right than 0xc0.
Though still turning to the left.
Steering comes
off the axle!
When the steering is turned to Since it is actually inclining to the right, when the servo
the left according to the program... is turned to the right, it goes off the course and
the wheel jumps from the course.
Even though there is a large incline towards the right, in the program there is a wrong judgment of "large
inclined to the left". Since the servo turns in the opposite direction when wrong judgment is done, the wheel jumps
from the course.
Therefore, when large turn is done to the left, steering keeps turning largely to the left until the micom car is
returned back to a certain state of the sensor. Judging place of this “certain state of the sensor” is pattern 13.
case 0xc0:
/* Large incline to the right-> Large turn to the left */
handle( -25 );
speed( 21 ,30 );
pattern = 13; <- Move to pattern 13
break; :This statement is added only in this case ox0c.
- 105 -
Program Explanation Manual “kit05.c”
In pattern 13, let’s consider how the state is evolvedi to return to normal run pattern 11.
0
0 0
1 1 0
0 0 0 0
0 0 1
0 0 1
0 0
1
0 0
0 0
0 0 0
0 0
0
1 1
0
Still turning
Continue turning even though about to fall
0
1 1
0 0
0 0
0
When set such that it returns to the pattern 11 when sensor state becomes 0x06, the misunderstanding like the
previous one can be avoided.
Though we consider that the program is complete, remember that crossline check was carried out in pattern 11.
Is it not necessary in pattern 13?
- 106 -
Program Explanation Manual “kit05.c”
1 1 0 0 0 0 0 0
1
1 0
0
0 0
0
0
1 1 1 1
1 1 1 0 0
Thus the crossline is occasionally detected even during processing in pattern 13. There, the program for crossline
detection part is put in pattern 13.
- 107 -
Program Explanation Manual “kit05.c”
Program start
Pattern 0
switch input waiting
Pattern 1
1 second waiting
Pattern 12 Pattern 13
Crossline Check of large right Check of large left
bending end Large bend end. bending end Large bend end
detection
Crossline detection Crossline detection
Pattern 21
Process at the time of first
crossline detection
Pattern 22
2nd crrossline is
skipped
Pattern 23
The first of trace after
crossline
Pattern 24
Crank detection and the
second of trace after
crossline
Pattern 32 Pattern 42
Check of left crank Check of right crank
bending end bending end
The part enclosed in the square is the processing until the right angle is detected after the crossline is detected.
Checks if there is crossline in pattern 11, 12, 13. Move to pattern 21 as soon as crossline is detected.
- 108 -
Program Explanation Manual “kit05.c”
When does the flow of the program move to pattern 21 in what type of state ? If you recall the part that moved
from pattern 11 to pattern 21, it was a program like below.
When the sensor board has detected the crossline, the flow becomes to pattern 21 as a figure below.
5 0 ~1 0 0 c m
Position of
slow down start
After the crossline, about 50~100cm ahead, the crank (Right angle), which is the worst difficulties in the course,
is shown. First of all, what is necessary to be done? Since the car is running along the course untill now, the car is
keeping on a considerable speed. It is impossible to turn in right angle at that speed directly. Then, first of all, the
brakes are applied. After crossline, the steering is adjusted to 0 degrees because it is known that the straight line
course is there.
The breaks are applied till "position of slow down start" and after that it is considered to proceed by going slow.
After the first crossline is found, till proceeding the slow going part, there is a state as shown in following figure.
- 109 -
Program Explanation Manual “kit05.c”
No.4
No.3
No.2
No.1
No.1 shows first crossline, No.2 shows black, No.3 shows second crossline, and No.4 shows the slow down
starting part in black.
Program that distinguishes whether the course has changed as white->black->white->black till No.4, is necessary
and that releases the braking in No.4 part, is necessary, too. It seems to be complex somehow.
The concept has been changed a little. Crossline is detected and the car proceeds up to No.4 position. Is it about
10cm? If it is about 10cm then little temperization is done with timer function and the car proceeds with inertia
and it seems to finish without a difficult sensor judging. The time ... as the experiment is not done on this time, it
is indescribable. For the time being, detailed time is assumed to be finely adjusted by running as for 0.1 second. It
is made in such a way that after crossline detection LED is lighted and it can be known from outside that it has
entered in pattern 21.
If summarized,
・LED0,1 are lighted
・Steering is adjusted to 0 degree.
・Break is applied by adjusting left and right motor PWM to 0%.
・0.1 second waiting
・Moves to the following pattern after some duration
case 21:
led_out( 0x3 );
handle( 0 );
speed( 0 ,0 );
if( cnt1 > 100 ) {
pattern = 22; /* To pattern 22 after 0.1 seconds*/
}
break;
Visual inspection is performed on completion for any defects. Why! There is a doubtful part in above program.
When cnt1 becomes more than 100 (When passing by 100 milliseconds), it is made to move to pattern 22.
Therefore, when pattern 21 is carried out , cnt1 should be 0. For instance, if cnt1 is 1000 when program has moved
to pattern 21, cnt1 is assumed to be more than 100 and pattern 21 is hardly executed (at about 0.1 seconds). There
is no guarantee of cnt1 being 0. Then, one more pattern has to be increased. Pattern is divided in two parts, one is
pattern 21 that takes charge of applying braking operation and clearing of “cnt1”, and another is pattern 22 that
takes charge of whether 0.1 second has passed or not.
- 110 -
Program Explanation Manual “kit05.c”
Performed by pattern 21
・LED0,1 are turned on
・Steering is adjusted to 0 degree
・Brake is applied by adjusting left and right motor PWM to 0%.
・The pattern is moved to next
・cnt1 is cleared
The program shown above is reviewed on completion for any defects. Brake is applied at pattern 21, cnt1
concerned with standard time interval, is cleared and then moved to pattern 22. Whether 0.1 seconds passed is
checked in pattern 22. If it passed, then execution of the program moves to pattern 23.
Here the program from detecting the crossline to slow down starting is completed.
In pattern 21, 22, after the crossline is detected, brake is applied for 0.1 second and 2 crosslines are passed. The
process after that is done in pattern 23.
As the crossline has passed, next is crank (right angle) detection. When crank is found, the car slowly proceeds
since the steering has to turn immediately. Normal trace is necessary, as straight line should be traced in between
crossline and the right angle. This time it is as per the following figure.
- 111 -
Program Explanation Manual “kit05.c”
-> 0x07
- 112 -
Program Explanation Manual “kit05.c”
It is difficult to create a program. There are two kinds of states in “0xe0”. There were two kinds of “0x07”, too.
“0xe0” state is shown in following figure.
○○○××●●●
○○○××●●●
Part processed by
pattern 24
5 0 ~1 0 0 c m
Part processed by
pattern 23
Position of
slow down start
- 113 -
Program Explanation Manual “kit05.c”
Timing for moving to pattern 24 from pattern 23 is judged by time. Up to what extent is it good? It cannot be
described in theory. It is ineffective when it is short, and the car reaches the crank part when it is too long. This
time it is adjusted to 0.3 seconds and afterwards it will be adjusted by actual running.
Pattern 24 is a process till right angle detection. The process is shifted to pattern 31 after controlling the steering
and motor when the left crank is detected. The process is shifted to pattern 41 after controlling the steering and
motor when the right crank is detected.
Though the showing has become lengthy, pattern 23, 24 will become as follows if programming is done.
- 114 -
Program Explanation Manual “kit05.c”
When sensor becomes “0xe0” in pattern 24, the steering turns with large angle by judgment that it is the left crank.
And we consider the micom car shall be able to get over the crank. But, there may be the following problem that
until when, the steering continues the large turning to left.
It is as shown in following figure.
●●●×× ○○ ●
●
●
●
●
×
●●
×
●
●
××
●
○
●○
○○○× ×●●●
- 115 -
Program Explanation Manual “kit05.c”
In case of “0xe0”, it is turned to left with a large angle but as it is in speed, it takes an expanded turn. It is
returned to pattern 11 by ending the turning when sensor comes near to the center line and becomes “0x60”.
This is made into a program.
case 31:
if( sensor_inp(MASK3_3) == 0x60 ) {
pattern = 11;
}
break;
Program is completed and the micom car is made to run. If this is done, the moment the sensor state has become
“0xe0”, the steering is turned to the left. When it was continued to turn like this, immediately it turned straight and
the wheel jumps from the course. Connector of motor and servo is unplugged and it is processed slowly by hand
as the operation is too quick and cannot be understood properly. If the sensor state is observed carefully, it
becomes like the following figure.
1 2
●○ ○× × ● ●●
○ ○○× ×●● ●
"0xe0" is detected, When it turns, in the part where the color changes
and turn till it becomes "0x60" completely from white to black, sensor state
becomes "0x60" and it ends large turning immediately.
And the execution moves to pattern 11.
And shifts to pattern 11.
●● ●×× ●●●
3 4
● ●●×× ●● ●
"0x00" is detected and it goes straight 100%. The wheels jump from the course like this
and it is called "the course out".
As shown in figure 2, by the transition of white and black (it is actually white, gray and black but, gray appears
as white), it is understood that the state of the sensor is "0x06". The sensor on the extreme left changes to "0"
because the sensor is not adjusted properly. Though it might be better to increase the sensitivity of the extreme left
sensor, there is a possibility of the wheel jumping from the racing course.Can anything be done in the program?
After some thought, it was noticed that some time was required from the detection of "0xe0" until the final
sensor state of "0x06". After detecting the crossline, here too, it waits for a small progression using the timer as if
the sensor has not detected anything for 0.2 seconds. Check the sensor. Draw and make an image.
- 116 -
Program Explanation Manual “kit05.c”
1 ●●
● 2
×
●×
●●
○○○× ×●●●
"0xe0" is detected, and waited for 0.2 seconds After 0.2 seconds, sensor is confirmed.
after turning with a large angle. "Turning is continued till 0x60".
●
×× ○ ○
3 4
●
●●●
●
●
×
×
○
○
●
The micom car is at the position where a white and black turning point was exceeded beyond after 0.2 seconds, as
shown in Figure 2. Later, it continues to turn securely till it becomes “0x60”. If this idea is adopted, it seems to be
perfect. Program is done.
The program checks whether the cnt1 is more than 200 or not on 325th line. If it is more than 200, in other words,
if 0.2 seconds are passed, shifts to pattern 32. Incidentally, cnt1 clear is done on the 289th before the execution
moves to pattern 31.
- 117 -
Program Explanation Manual “kit05.c”
When the sensor becomes “0x07" in pattern 24, it is considered as right crank and the crank is cleared by a large
turn to the right.
The next problem that arises is: "Turn to the right up to what extent?"
It is considered to be as shown in the figure below.
●○○×× ●●●
●
●
●
●●
×
×
●
●×
●
●
○○ ×
●●●× ×○○ ○
●
When sensor state becomes "0x06",
turning is completed and returned to pattern 11.
Though the car turns to the right in case of “0x07”, it takes a large expanding turn due to the high speed. When the
sensor comes near the center-line and becomes "0x06", the turns are complete and the execution returns to pattern
11.
This is described in the program.
case 41:
if( sensor_inp(MASK3_3) == 0x06 ) {
pattern = 11;
}
break;
Program is completed and the micom car is made to run. If this is done, the moment the sensor state has become
“0x07”, the steering is turned to the right. When it was continued to turn like this, immediately it turned straight
and the wheel jumps from the course. Connector of motor and servo is unplugged and the car is processed slowly
by hand as the actual operation is too quick and cannot be understood properly. If the sensor state is observed
carefully, it becomes like the following figure.
- 118 -
Program Explanation Manual “kit05.c”
1 2
●●●××○○●
● ●●× ×○○ ○
● ●●× ×●● ●
3 4
●●● ××● ●●
"0x00" is detected, 100% direct advancement. The wheels jump from the course like this
and it is called "the course out".
As shown in figure 2, by the transition of white and black (actually white, gray and black but, gray appears as
white), the state of the sensor is “0x06”. The sensor on the extreme right changes to “0” before it is adjusted
properly. Though it might be better to increase the sensitivity of the extreme right sensor, there is a possibility of
the wheel coming off the axle hence can anything be done in the program?
It was found that some time was required from the detection of "0x07" until the final sensor state of "0x06". After
detecting the crossline, here too it waits for a small progression using the timer as if the sensor has not detected
anything for 0.2 seconds. Can the sensor be checked for that?
- 119 -
Program Explanation Manual “kit05.c”
1 2 ●●
●×
×●
●●
●● ●××○○○
3 4
×× ●
●●
●●
●×
○○ ×
●
States of "0x60" Still turning is continued. Detection of "0x06". End of turn.
The execution goes to normal run of pattern 11.
After 0.2 seconds, as shown in Fig 2, the micom car is at the position where a white and black turning point was
exceeded beyond. Later, it continues to turn securely until it becomes “0x06”, if this idea is acceptable, it seem to
be perfect. Program is created.
The program checks that cnt1 is 200 or more in 342nd line. If it is above 200, that is, if 0.2 seconds have passed,
the execution moves to pattern 42. Clear of cnt1 is carried out in 297th line before moving to pattern 41.
- 120 -
Program Explanation Manual “kit05.c”
357 : default:
358 : /* When the pattern is not applied to any case, return to waiting state */
359 : pattern = 0;
360 : break;
Default system is executed, when the pattern is none of the above. The pattern is made to 0 and is set to standby.
Execution of default statement means that some inconsistent pattern was made in the program while changing the
pattern. That part should be searched and corrected.
- 121 -
Program Explanation Manual “kit05.c”
When the steering is turned, the rotation of the tire is different on the inner and outer sides. The calculation
method is shown below.
W=0.175m W
θ=30°=π/6
T=0.14m r1
r2
r3
According to the figure, the triangular relation of the base r2, height W, and angleθ is as follows.
Tanθ = W/r2
Therefore, if the rotation of the outer wheel is 100, the rotation of the inner wheel is,
r1/r3x100 = 0.233/0.373x100 = 62
When steering is turned by 30° to the left, the rotation of left tire becomes 62 as against 100 of right tire.
- 122 -
Program Explanation Manual “kit05.c”
Setting as follows in the program can do the rotation without the loss of inner and outer tires.
handle ( -30 );
speed( 62, 100 );
It is convenient to create a table of angles from 0 to 45 and next is the rotation rate of the left and right tires in
Excel.
In order to turn slightly to the right, the steering is turned 30° to the right, left tire 80%. The PWM value of the
right tire on inner side is not known. As from table, it is understood that at 10° the left tire on inner side is 87%.
However, this is a value when the outer tire is 100%. Since here it is 80%,
Right tire = PWM of left tire / ratio 100 = 80 / 87 100 = 69
Therefore, the PWM value of the right tire is set to 69. In kit05.c, the rotation difference between inner and outer
is thus calculated.
- 123 -
Program Explanation Manual “kit05.c”
When the value of W and T are in the length of one’s own micom car, the rotation rate of the right and left tires is
understood.
- 124 -
Program Explanation Manual “kit05.c”
The “angle calculation.xls” file is an example. The following file opens when this is opened.
If
of the cell are set, the angle of the steering and the speed value are input in part automatically.
This is convenient. Actually, this Excel sheet did the right and left rotation difference calculation of kit05.c.
However, please match the wheelbase and the tread carefully.
- 125 -
Program Explanation Manual “kit05.c”
- 126 -
Program Explanation Manual “kit05.c”
This command specifies the type of CPU. “300HA” specifies H8/300H advanced mode. H8/3048F-ONE uses this
mode. Moreover, “: 20” specifies the bit width of the address space in 20-bit width (address h'00000-h' fffff ).
Since CPU board used with the kit is a single chip mode, which does not use external memory, it is assumed as
20-bit width, though a 24-bit width also is specified.
An external reference is defined. External reference means “Not in this file, but there is a label (function) in
another file, so refer to the external file”. External files are the files which are to be united at the time of linking.
The assembler knows that “the label defined with .IMPORT is in another file” and reserves only the name and area.
This reserved address name is allocated when the address of the label is decided by the operation of the link. When
the label defined at the time of link operation is not found, it becomes a link error. The link is described later.
There is “_” (underscore) at the beginning of the label, the reason is that there is regulation of putting “_” at the
beginning, when calling label (function) name of C language file (kit05.c) from assembler file (kit05start.src).
- 127 -
Program Explanation Manual “kit05.c”
“.SECTION" is a delimiter of the program, and the name “V” is used here. Section V is allocated to the address
that has been described in the sub file. The label which jumps when interrupts which include “reset” occur, is
specified in section V.
“.DATA.L” is a command to allocate data. “L” indicates “long”, “long” means 4 bytes. Since data on 9th line is
“RESET_START”, the value of the address with “RESET_START" is written. If it is h'00100,
“h'00,h'00,h'01,h'00” is written.
In H8/3048F-ONE, the procedure to generate interrupt carries out the following processing,
1. Checks various interrupt flags when the currently executing command ends.
2. If there is an interrupt, moves (shunts) the PC, CCR register to interrupt processing routine.
3. According to the kind of the interrupt generated, the address data of destination to jump is read from the decided
address
4. The interrupt program is executed by jumping to the specified location.
That “decided address” means address h'00000 ~ h'000f. This is a special address and is called a vector address.
- 128 -
Program Explanation Manual “kit05.c”
When the power supply of CPU is turned on, it becomes a ‘power supply turned on’ interrupt. Though there are no
procedures(like 1, 2), the jump destination address data written in the h'00000 address is read and program is
executed by jumping to the specified location. For example, the case when jump destination is address h'00100 is
shown below.
At the time of reset, the data "h'000100" at the address h'00000 is read and
executed by jumping to address h'000100.
The table which summarizes the type of interrupt and vector address is shown below.
Vector Priorit
Interrupt factor Origin Vector Address IPR
No. y level
External
Reset 0 H'0000 - H'0003 −−−
terminal
NMI 7 H'001C - H'001F −−− high
IRQ0 12 H'0030 - H'0033 IPRA7 ↑
IRQ1 13 H'0034 - H'0037 IPRA6
External
IRQ2 14 H'0038 - H'003B
terminal IPRA5
IRQ3 15 H'003C - H'003F
IRQ4 16 H'0040 - H'0043
IRQ5 17 H'0044 - H'0047
IPRA4
18 H'0048 - H'004B
Reserve −−−−−
19 H'004C - H'004F
WOVI (Interval timer) Watch dog timer 20 H'0050 - H'0053
Refresh
CMI (Compare match) 21 H'0054 - H'0057
controller IPRA3
22 H'0058 - H'005B
Reserve −−−−−
23 H'005C - H'005F
IMIA0 (Compare match/input capture A0) 24 H'0060 - H'0063
ITU
IMIB0 (Compare match/input capture B0) 25 H'0064 - H'0067
Channel 0 IPRA2
OVI0 (Overflow 0) 26 H'0068 - H'006B
Reserve ───── 27 H'006C - H'006F
IMIA1 (Compare match/input capture A1) 28 H'0070 - H'0073
ITU
IMIB1 (Compare match/input capture B1) 29 H'0074 - H'0077
Channel 1 IPRA1
OVI1 (Overflow 1) 30 H'0078 - H'007B
Reserve ───── 31 H'007C - H'007F
IMIA2 (Compare match/input capture A2) 32 H'0080 - H'0083
ITU
IMIB2 (Compare match/input capture B2) 33 H'0084 - H'0087
Channel 2 IPRA0
Reserve 34 H'0088 - H'008B
Reserve ───── 35 H'008C - H'008F
- 129 -
Program Explanation Manual “kit05.c”
36 H'0090 - H'0093
ITU
Channel 3 IPRB7
IMIB3 (Compare match/input capture B3) 37 H'0094 - H'0097
OVI3 (Overflow 3) 38 H'0098 - H'009B
Reserve ───── 39 H'009C - H'009F
IMIA4 (Compare match/input capture A4) 40 H'00A0 - H'00A3
ITU
IMIB4 (Compare match/input capture B4) 41 H'00A4 - H'00A7
Channel 4 IPRB6
OVI4 (Overflow 4) 42 H'00A8 - H'00AB
Reserve ───── 43 H'00AC - H'00AF
DEDN0A 44 H'00B0 - H'00B3
DEDN0B DMAC 45 H'00B4 - H'00B7
IPRB5
DEDN1A Group 0 46 H'00B8 - H'00BB
DEDN1B 47 H'00BC - H'00BF
48 H'00C0 - H'00C3
49 H'00C4 - H'00C7
Reserve ───── ──
50 H'00C8 - H'00CB
51 H'00CC - H'00CF
ERI0 (Reception error 0) 52 H'00D0 - H'00D3
RXI0 (Reception completion0) SCI 53 H'00D4 - H'00D7
IPRB3
TXI0 (Transmission data empty 0) Channel 0 54 H'00D8 - H'00DB
TEI0 (Transmission end 0) 55 H'00DC - H'00DF
ERI1 (Reception error 1) 56 H'00E0 - H'00E3
RXI1 (Reception completion1) SCI 57 H'00E4 - H'00E7
IPRB2
TXI1 (Transmission data empty 1) Channel 1 58 H'00E8 - H'00EB ↓
TEI1 (Transmission end 1) 59 H'00EC - H'00EF
ADI (A/D End) A/D 60 H'00F0 - H'00F3 IPRB1 low
As shown in the table the numbers from 0 to 60 are allocated and kit05start.src defines the addresses of all the
numbers. “RESERVE” name is given to the vector that is not a jumping destination and only the location is
secured. Later when using the interrupt, it is possible to change it easily by changing the name "RESERVE" of
corresponding vector address to jump destination address.” RESERVE" is allocated in third line of the program
list (kit05start.src), with h 'FFFFFFFF.
- 130 -
Program Explanation Manual “kit05.c”
This is the section named “P”. Here actually are program described while the section ”V” describes address of
jumping destination at interruption. Process in section P is stuck area setting and command to jump into “_main”.
“_main” is a main function of file c, and C language program is executed from the main function.
“BRA OWARI” at the end is process when main function of C language finishes and returns. It is usual that the
main function does not terminates, though, the process jumps into itself to let CPU do nothing in case the main
function terminates. Without this description, process goes to address without program or address with unknown
program, resulting that CPU continues meaningless operation out of control.
4.6. END
78 : .END
“src” file declares always the end of assembly program with “.END”.
Even If some program is written after this command, it is ignored.
- 131 -
Program Explanation Manual “kit05.c”
1: input kit05start,kit05
2: lib c: ¥h8n_win¥3048¥c¥c38hae.lib
3: output kit05
4: print kit05
5: start V(000000)
6: start P,C(000100)
7: start B(0fef10)
8: exit
1: input kit05start,kit05
The files that are linked with the "input" command are described. Each “obj” file is described by delimiting with
comma and without extension. Here, “kit05start” and “kit05” are specified.
2: lib c: ¥h8n_win¥3048¥c¥c38hae.lib
The read library is described by “lib” command. The library is a file, which is used when the C language program
is converted into the assembler. The folder where the library is preserved is usually, “c: ¥h8n_win¥3048¥c" and
the library name is “c38hae.lib". On combining, it becomes "c: ¥h8n_win¥3048¥c¥c38hae.lib".
3: output kit05
The "output" command describes the file name when the mot file is created. As it is “kit05”, “kitt05.mot” file is
created.
- 132 -
Program Explanation Manual “kit05.c”
4: print kit05
The "print" command describes the file name when the map file is created. The “kit05.map" file is created since it
is assumed kit05.
5: start V(000000)
6: start P,C(000100)
7: start B(0fef10)
The beginning of the address where the section is to be allocated is described by the "start" command and the
command is specified as "Section name (hexadecimal number address)". The section names that are automatically
assigned by the compiler are as follows.
Section where “const type” data is stored. Allocated in the ROM area. When the variable is
C declared “const”, section C is allocated. Though it is not used in kit05.c, it has been defined
taking into consideration that it is used for adding programs.
Section where the uninitialized data is stored. It is allocated in the RAM area. Section B is
B used when the global variable is allocated. Since cnt0 and cnt1 are allocated as global
variables at this time, it is used.
The addresses for allocation of these sections are decided. Moreover, because section V is originally defined in the
start-up routine, this allocated address is declared.
When it is compiled or compiled and written in development environment, the following error is generated.
- 133 -
Program Explanation Manual “kit05.c”
: input kit05start,kit05
: lib c: ¥h8n_win¥3048¥c¥c38hae.lib
: output kit05
: print kit05
: start V(000000)
: start P,C(000100)
: start B(0fef10)
: exit
** 121 CANNOT FIND SECTION(C)
This is an error, which says, "There is no section C". As it is explained previously, section C is a section where the
“const type” data is stored. As “const” is not declared in kit05.c, section C is not established, and the error
message is given. Though it is a message, which informs that there is no section C, it can be ignored because there
is no trouble with the execution of the program.
If you consider that there is still a problem, extract the part “,C” from “start P,C(000100)”, so, the command is
such that 6th line of "kit05.sub" as below and the error is not outputted.
6: start P(000100)
However, when the const type is declared after acquisition, section C is allocated after section B.
The section to which address is not allocated is allocated after the last section.
The last section is section B. Section B is allocated in the RAM area. If the position of section C is not specified in
the sub file, it is allocated after the section B, that is, it is allocated in the RAM area. The error that there is no
allocation address of section C, is not outputted. Since section C should originally be allocated in ROM area,its
MOT file does not operate normally.
Therefore, it has been set such that the error is outputted initially and it is better than that the error is not outputted
at the time of usage and ‘no operation if there is no error’.
8: exit
- 134 -
Program Explanation Manual “kit05.c”
It is C source program file written in C language. It is the main part, which controls
kit05.c
the micom car.
It is an assembly source program file which programs the vector address of start-up
kit05start.src routine and interrupt jump destination. File name is "Name of C language file
excluding extension + start.src"
It is a subcommand file where information when files are linked is described. File
kit05.sub
name is "Name of C language file excluding extension + .sub"
The following 6 files are created by assembling, compiling, linking and converting this file.
It is a file called list file for assembly program. When “kit05start.src” file is
kit05start.lis assembled, which type of machine language it has been converted to, can be known
by seeing this file.
It is a file, which is called S type format. This file is output when “abs” file is
kit05.mot converted. The writing software reads this file, and writes the program in the CPU
board via RS-232 of computer.
Though the aim is to create "kit05.mot" file which stores the data to be finally written in the microcomputer from
the files "kit05.c" and "kit05start.src", the MOT file cannot be created if it does not follow the procedure of
assemble -> compile -> link -> convert.
- 135 -
Program Explanation Manual “kit05.c”
kit05start.lis
List for assembly program
kit05.map
kit05start.src kit05start.obj Linkage list
Assembly source assemble Relocatable object Link
program program kit05.abs
Absolute load module compile
kit05.c kit05.obj
C source compile Relocatable object
program program
kit05.mot
kit05.sub
S type format
Subcommand link
… File from source information
Write with the writing
… File to be created software
Operation Contents
Assemble The assembly resource program is converted into the object program.
Two or more object files are incorporated by referring to information of the subcommand,
Link
and made in to one absolute load module.
Absolute load module is converted to S type format file, and finally made into a file type
Convert
which can be written in the microcomputer.
Finally, the “kit05.mot” file is written in the CPU board with the writing software via RS-232C of the
computer.
- 136 -
Program Explanation Manual “kit05.c”
7. Bibliography
Please see the micom car rally official homepage for detailed information on the micom car rally.
http://www.mcr.gr.jp/
Please see the homepage of Renesas Technology Company Ltd. for detailed information on the H8
microcomputer.
http://japan.renesas.com/
- 137 -