You are on page 1of 23

/****************************************************************************/

/* Micom Car Rally Trace Program 2005 Version

*/

/* 2005.04 Micom Car Rally Executive Committee

*/

/****************************************************************************/
/*
This kit05.c program connects to motor drive board (Vol.3).
The following contents have been changed with respect to kit04.c.
- The port connected to CPU board has been changed from J2 (Port A) to J3
(Port B).
- Motor mode function has been removed (scrapped) (always brake)
- Motor is able to perform normal rotation, reverse rotation and brake control.
(Reverse rotation was not possible previously)
- 2 step process after crossline detection (Pattern 23, 24)
*/

/*======================================*/
/* Include

*/

/*======================================*/
#include

<machine.h>

#include

"h8_3048.h"

/*======================================*/
/* Symbol definition

*/

/*======================================*/

/* Set Constants */
#define

TIMER_CYCLE

3071

/* Timer cycle 1ms

*/

/* When it is to be used by f/8 */


/* f / 8 = 325.5[ns]

*/

/* Therefore, TIMER_CYCLE

#define

/*

= 1[ms] / 325.5[ns] */

/*

= 3072

PWM_CYCLE

*/

*/

49151 /* PWM cycle 16ms

/* Therefore, PWM_CYCLE
/*

= 16[ms] / 325.5[ns] */

/*

= 49152

#define

SERVO_CENTER

#define

HANDLE_STEP

5000
26

*/

*/

*/

/* Center value of Servo


/* 1 degree part value

*/
*/

/* Mask value setting x: With Mask (Invalid) o:Without mask (Valid)


#define

MASK2_2

0x66

/* xooxxoox

*/

#define

MASK2_0

0x60

/* xooxxxxx

*/

#define

MASK0_2

0x06

/* xxxxxoox

*/

#define

MASK3_3

0xe7

/* oooxxooo

*/

#define

MASK0_3

0x07

/* xxxxxooo

*/

#define

MASK3_0

0xe0

/* oooxxxxx

*/

#define

MASK4_0

0xf0

/* ooooxxxx

*/

#define

MASK0_4

0x0f

/* xxxxoooo

*/

#define

MASK1_1

0x81

/* oxxxxxxo

*/

/*======================================*/
/* Prototype declaration

*/

/*======================================*/

*/

void init(void );
void timer( unsigned long timer_set );
int check_crossline( void );
unsigned char sensor_inp( unsigned char mask );
unsigned char dipsw_get( void );
unsigned char pushsw_get( void );
void led_out( unsigned char led );
void speed( int accele_l, int accele_r );
void handle( int angle );
char unsigned bit_change( char unsigned in );

/*======================================*/
/* Global Variable Declaration

*/

/*======================================*/
unsigned long cnt0;

/* used in 'timer' function */

unsigned long cnt1;

/* used in main

*/

/************************************************************************/
/* Main program

*/

/************************************************************************/
void main( void )
{
int

i;

int

pattern;

/* Microcomputer function initialization */

init();

/* Initialization

set_ccr( 0x00 );

*/

/* Whole interrupt enable */

/* State initialization of micom car */


handle( 0 );
speed( 0, 0 );
pattern = 0;
cnt1 = 0;

while( 1 ) {
switch( pattern ) {

/*****************************************************************
About pattern
0: Switch input wait
1: Wait for 1 second after the switch is pressed.
11: Usual trace
12: Check for the end of long turn to the right
13: Check for the end of long turn to the left
21: Processing when first crossline is detected
22: Skip second crossline
23: Trace 1 after crossline
24: Trace 2 after crossline, crank detection
31: Left crank Clear process Waits till it stabilizes
32: Left crank clear process Check for end of turn
41: Right crank clear process Waits till it stabilizes

42: Right crank clear process Check for end of turn


*****************************************************************/

case 0:
/* Switch input waiting */
if( pushsw_get() ) {
pattern = 1;
cnt1 = 0;
break;
}
if( cnt1 < 100 ) {

/* LED blinking process */

led_out( 0x1 );
} else if( cnt1 < 200 ) {
led_out( 0x2 );
} else {
cnt1 = 0;
}
break;

case 1:
/* 1 second waiting after the switch is pushed */
if( cnt1 < 500 ) {
/* 1.0 seconds starting ago LED1:"OFF" , LED0:"ON" */
led_out( 0x1 );
} else if( cnt1 < 1000 ) {
/* 0.5 seconds starting ago LED1:"ON" , LED0:"OFF" */

led_out( 0x2 );
} else {
/* Start!! */
led_out( 0x0 );
pattern = 11;
cnt1 = 0;
}
break;

case 11:
/* Usual trace */
if( check_crossline() ) {

/* Crossline Check */

pattern = 21;
cnt1=0;
break;
}
switch( sensor_inp(MASK3_3) ) {
case 0x00:
/* Center -> straight */
handle( 0 );
speed( 90 ,90 );
break;

case 0x04:
/* Slight amount left of center -> slight turn to right */
handle( -10 );

speed( 80 ,75 );
break;

case 0x06:
/* Small amount left of center -> small turn to right */
handle( -20 );
speed( 80,70 );
break;

case 0x07://Truong hop re sang lan duong ben trai


pattern = 12;
break;

case 0x03:
/* Large amount left of center -> large turn to right */
handle( -40 );
speed( 80,65 );

break;

case 0x20:
/* Slight amount right of center -> slight turn to left */
handle( 10 );
speed( 75,80 );
break;

case 0x60:
/* Small amount right of center -> small turn to left */
handle( 20 );
speed( 70,80 );
break;

case 0xe0://Truong hop re sang lan duong ben trai


pattern = 13;
break;

case 0xc0:
/* Large amount right of center -> large turn to left */
handle( 40 );
speed( 80 ,65 );

break;

default:
break;
}
break;

case 12:
pattern=11;
break;

case 13:
if( sensor_inp( 0xff ) == 0x00 )//khi di het line tat ca cac den
deu tat
{
//cho xe queo trai
handle( 45 );
speed( 30,35 );
pattern = 23;
}else{
switch( sensor_inp(MASK3_3) ) {
case 0x00:
/* Center -> Straight */
handle( 0 );
speed( 50,50 );
break;
case 0x04:
/* Slight amount left of center -> slight turn to right */
handle( -10 );
speed( 50 ,45 );
break;

case 0x06:
/* Small amount left of center -> small turn to right */
handle( -20 );
speed( 50 ,40 );
break;

case 0x03:
/* Large amount left of center -> large turn to right */
handle( -45 );
speed( 45,30 );
//pattern = 12;
break;

case 0x20:
/* Slight amount right of center -> slight turn to left */
handle( 10 );
speed( 45,50 );
break;

case 0x60:
/* Small amount right of center -> small turn to left */
handle( 20 );
speed( 40 ,50 );
break;

case 0xc0:
/* Large amount right of center -> large turn to left */
handle( 45 );
speed( 30 ,45 );
//pattern = 13;
break;

default:
break;
}
}
break;

case 21:
/* Process when first crossline is detected */
led_out( 0x3 );
handle(0);
speed(0,0);
if(cnt1>200)//bo qua crossline thu 2
{
pattern = 24;
cnt1 = 0;
}
break;
case 23:
if( sensor_inp( 0xc0 ) !=0 )
{
handle( -10 );
timer( 200 );
pattern = 11;
}
break;
case 24:

/* 2 of trace after crossline and crank detection */


switch( sensor_inp(MASK3_3) ) {
case 0xe0:
/* Judgment of left crank -> To the left crank clearing process */
led_out( 0x1 );
handle( 65 );
speed( 30 ,30 );
pattern = 31;
cnt1 = 0;
break;
case 0x07:
/* Judgment of right crank -> The process for getting over right
crank */
led_out( 0x2 );
handle( -65 );
speed( 30 ,30 );
pattern = 41;
cnt1 = 0;
break;
case 0x00:
/* Center -> Straight */
handle( 0 );
speed( 50,50 );
break;
case 0x04:
/* Slight amount left of center -> slight turn to right */
handle( -10 );

speed( 50 ,45 );
break;

case 0x06:
/* Small amount left of center -> small turn to right */
handle( -20 );
speed( 50 ,40 );
break;

case 0x03:
/* Large amount left of center -> large turn to right */
handle( -40 );
speed( 45,30 );
//pattern = 12;
break;

case 0x20:
/* Slight amount right of center -> slight turn to left */
handle( 10 );
speed( 45,50 );
break;

case 0x60:
/* Small amount right of center -> small turn to left */
handle( 20 );
speed( 40 ,50 );

break;

case 0xc0:
/* Large amount right of center -> large turn to left */
handle( 40 );
speed( 30 ,45 );
//pattern = 13;
break;

default:
break;

}
break;

case 31:
/* Left crank clear process Wait a little till it becomes stable. */
if( cnt1 > 200 ) {
pattern = 32;
cnt1 = 0;
}
break;

case 32:
//if( sensor_inp(MASK3_3) == 0x60 ) {
led_out( 0x0 );

speed(0,0);
timer(5000);

//}
break;

case 41:
/* Right crank clear processing Waits a little until stabilizing */
if( cnt1 > 500 ) {
pattern = 42;
cnt1 = 0;
}
break;

case 42:
/* Right crank clear processing Turning completion check */
//if( sensor_inp(MASK3_3) == 0x06 ) {
led_out( 0x0 );
pattern = 11;
cnt1 = 0;
//}
break;

default:
/* When the pattern is not applied to any case, return to waiting state */
pattern = 0;

break;
}
}
}

/************************************************************************/
/* H8/3048F-ONE Built in Peripheral Function Initialization

*/

/************************************************************************/
void init( void )
{
/* I/O port Setting */
P1DDR = 0xff;
P2DDR = 0xff;
P3DDR = 0xff;
P4DDR = 0xff;
P5DDR = 0xff;
P6DDR = 0xf0;

/* DIP SW on CPU board

*/

/* Communication Port

*/

/* Motor Drive Board Vol.3

*/

P8DDR = 0xff;
P9DDR = 0xf7;
PADDR = 0xff;
PBDR = 0xc0;
PBDDR = 0xfe;

/* As P7 of the sensor board is an exclusive input, there are no input output


settings. */

/* ITU0 Interrupt at every 1ms */


ITU0_TCR = 0x23;

ITU0_GRA = TIMER_CYCLE;
ITU0_IER = 0x01;

/* ITU3, 4 reset-synchronized PWM mode for right-left motor and servo */


ITU3_TCR = 0x23;
ITU_FCR = 0x3e;
ITU3_GRA = PWM_CYCLE;

/* Setting of cycle

ITU3_GRB = ITU3_BRB = 0;

/* PWM Setting of left motor*/

ITU4_GRA = ITU4_BRA = 0;

/* PWM Setting of right motor*/

ITU4_GRB = ITU4_BRB = SERVO_CENTER;

*/

/* PWM Setting of servo

ITU_TOER = 0x38;

/* Count start of ITU */


ITU_STR = 0x09;
}

/************************************************************************/
/* ITU0 Interrupt process

*/

/************************************************************************/
#pragma interrupt( interrupt_timer0 )
void interrupt_timer0( void )
{
ITU0_TSR &= 0xfe;
cnt0++;
cnt1++;
}

/* Flag clear

*/

*/

/************************************************************************/
/* Timer main unit

*/

/* Argument Timer value 1=1ms

*/

/************************************************************************/
void timer( unsigned long timer_set )
{
cnt0 = 0;
while( cnt0 < timer_set );
}

/************************************************************************/
/* Sensor state detection
/* AArgument

Mask value

/* RReturn value Sensor value

*/
*/
*/

/************************************************************************/
unsigned char sensor_inp( unsigned char mask )
{
unsigned char sensor;

sensor = ~P7DR;
sensor &= 0xef;
if( sensor & 0x08 ) sensor |= 0x10;

sensor &= mask;

return sensor;
}

/************************************************************************/
/* Crossline detection processing

*/

/* Return value 0: no crossline 1: crossline exists

*/

/************************************************************************/
int check_crossline( void )
{
unsigned char b;
int ret;

ret = 0;
b = sensor_inp(MASK2_2);
if( b==0x66 || b==0x64 || b==0x26 || b==0x62 || b==0x46 ) {
ret = 1;
}
return ret;
}

/************************************************************************/
/* Reading of DIP switch value
/* Return value Switch value 0 - 15

*/
*/

/************************************************************************/
unsigned char dipsw_get( void )
{

unsigned char sw;

sw = ~P6DR;

/* Reading of DIP switch */

sw &= 0x0f;

return sw;
}

/************************************************************************/
/* Push switch value reading

*/

/* Return value Switch value ON: "1" and OFF: "0"

*/

/************************************************************************/
unsigned char pushsw_get( void )
{
unsigned char sw;

sw = ~PBDR;

/* Reading of port having a push switch */

sw &= 0x01;

return sw;
}

/************************************************************************/
/* LED control

*/

/* Argument Switch value (LED1,LED0)=(bit1,bit0) "0":OFF , "1":ON

*/

/* Example 0x3->(LED1,LED0)=(ON,ON) : 0x2->(LED1,LED0)=(ON,OFF)

*/
/************************************************************************/
void led_out( unsigned char led )
{
unsigned char data;

led = ~led;
led <<= 6;
data = PBDR & 0x3f;
PBDR = data | led;
}

/************************************************************************/
/* Speed Control

*/

/* Argument Left motor: -100 - 100 , Right motor: -100 - 100


/*

0:Stop,100:normal rotation 100%,-100:Reverse 100%

*/
*/

/************************************************************************/
void speed( int accele_l, int accele_r )
{
unsigned char

sw_data;

unsigned long

speed_max;

sw_data = dipsw_get() + 5;

/* DIP switch read */

speed_max = (unsigned long)(PWM_CYCLE-1) * sw_data / 20;

/* Left motor */

if( accele_l >= 0 ) {


PBDR &= 0xfb;
ITU3_BRB = speed_max * accele_l / 100;
} else {
PBDR |= 0x04;
accele_l = -accele_l;
ITU3_BRB = speed_max * accele_l / 100;
}

/* Right motor */
if( accele_r >= 0 ) {
PBDR &= 0xf7;
ITU4_BRA = speed_max * accele_r / 100;
} else {
PBDR |= 0x08;
accele_r = -accele_r;
ITU4_BRA = speed_max * accele_r / 100;
}
}

/************************************************************************/
/* Servo steering operation
/* Argument Servo operation angle: -90 ~ 90
/*

*/
*/

-90:90 to the left turn , 0:straight ,90:90 to the right turn */

/************************************************************************/
void handle( int angle )

{
ITU4_BRB = SERVO_CENTER - angle * HANDLE_STEP;
}

/************************************************************************/
/* Bit change
/* Argument
/* RReturn value

*/
Value to be changed

*/

Changed value

*/

/************************************************************************/
char unsigned bit_change( char unsigned in )
{
unsigned char ret;
int i;

for( i=0; i<8; i++ ) {


ret >>= 1;
ret |= in & 0x80;
in <<= 1;

/* Right shift of return value */


/* Ret bit7 = in bit7
/* Left shift of argument

*/
*/

}
return ret;
}

/************************************************************************/
/* end of file

*/

/************************************************************************/

You might also like