Thông báo

Collapse
No announcement yet.

Có ai giải thích cụ thể đoạn code này cho anh em với!

Collapse
X
 
  • Lọc
  • Giờ
  • Show
Clear All
new posts

  • Có ai giải thích cụ thể đoạn code này cho anh em với!

    Mình mới bước vàop lập trình bà con có ai biết giải thích giúp đoạn code này với! Đây là dùng chíp H8/3048F-ONE

    /************************************************** **************************/
    /* 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 */
    /* = 1[ms] / 325.5[ns] */
    /* = 3072 */
    #define PWM_CYCLE 49151 /* PWM cycle 16ms */
    /* Therefore, PWM_CYCLE */
    /* = 16[ms] / 325.5[ns] */
    /* = 49152 */
    #define SERVO_CENTER 5000 /* Center value of Servo */
    #define HANDLE_STEP 26 /* 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;
    break;
    }
    switch( sensor_inp(MASK3_3) ) {
    case 0x00:
    /* Center -> Straight */
    handle( 0 );
    speed( 100 ,100 );
    break;

    case 0x04:
    /* Slightly left inclined -> Slight turn to the right */
    handle( 5 );
    speed( 100 ,100 );
    break;

    case 0x06:
    /* Little left inclined -> Small turn to the right */
    handle( 10 );
    speed( 80 ,69 );
    break;

    case 0x07:
    /* Left inclined from the middle -> Middle turn to the right */
    handle( 15 );
    speed( 50 ,40 );
    break;

    case 0x03:
    /* Large inclined to the left -> Large turn to the right */
    handle( 25 );
    speed( 30 ,21 );
    pattern = 12;
    break;

    case 0x20:
    /* Slightly inclined to the right -> Slight turn to the left */
    handle( -5 );
    speed( 100 ,100 );
    break;

    case 0x60:
    /* A little inclined to the right -> Small turn to the left */
    handle( -10 );
    speed( 69 ,80 );
    break;

    case 0xe0:
    /* Right inclined from the middle veering -> Middle turn to the left */
    handle( -15 );
    speed( 40 ,50 );
    break;

    case 0xc0:
    /* Large inclined to the right -> Large turn to the left */
    handle( -25 );
    speed( 21 ,30 );
    pattern = 13;
    break;

    default:
    break;
    }
    break;

    case 12:
    /* Check of large turning to the right completion */
    if( check_crossline() ) { /* Crossline check even during turning */
    pattern = 21;
    break;
    }
    if( sensor_inp(MASK3_3) == 0x06 ) {
    pattern = 11;
    }
    break;

    case 13:
    /* Check of large turning completion to the left */
    if( check_crossline() ) { /* Crossline check even during large turn */
    pattern = 21;
    break;
    }
    if( sensor_inp(MASK3_3) == 0x60 ) {
    pattern = 11;
    }
    break;

    case 21:
    /* Process when first crossline is detected */
    led_out( 0x3 );
    handle( 0 );
    speed( 0 ,0 );
    pattern = 22;
    cnt1 = 0;
    break;

    case 22:
    /* Second is skipped. */
    if( cnt1 > 100 ) {
    cnt1 = 0;
    pattern = 23;
    }
    break;

    case 23:
    /* 1 of trace after crossline */
    if( cnt1 > 300 ) {
    cnt1 = 0;
    pattern = 24;
    break;
    }
    switch( sensor_inp(MASK3_3) ) {
    case 0x00:
    /* Center -> Straight */
    handle( 0 );
    speed( 40 ,40 );
    break;
    case 0x04:
    case 0x06:
    case 0x07:
    case 0x03:
    /* Tending to the left -> Turn to the right */
    handle( 8 );
    speed( 40 ,36 );
    break;
    case 0x20:
    case 0x60:
    case 0xe0:
    case 0xc0:
    /* Tending to the right -> Turn to the left */
    handle( -8 );
    speed( 36 ,40 );
    break;
    default:
    break;
    }
    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( -38 );
    speed( 10 ,50 );
    pattern = 31;
    cnt1 = 0;
    break;
    case 0x07:
    /* Judgment of right crank -> The process for getting over right crank */
    led_out( 0x2 );
    handle( 38 );
    speed( 50 ,10 );
    pattern = 41;
    cnt1 = 0;
    break;
    case 0x00:
    /* Center -> Straight */
    handle( 0 );
    speed( 40 ,40 );
    break;
    case 0x04:
    case 0x06:
    case 0x03:
    /* Tending to the left -> Turn to the right */
    handle( 8 );
    speed( 40 ,36 );
    break;
    case 0x20:
    case 0x60:
    case 0xc0:
    /* Tending to the right -> Turn to the left */
    handle( -8 );
    speed( 36 ,40 );
    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:
    /* Left crank clear process Check of end of turn */
    if( sensor_inp(MASK3_3) == 0x60 ) {
    led_out( 0x0 );
    pattern = 11;
    cnt1 = 0;
    }
    break;

    case 41:
    /* Right crank clear processing Waits a little until stabilizing */
    if( cnt1 > 200 ) {
    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 */
    P8DDR = 0xff;
    P9DDR = 0xf7; /* Communication Port */
    PADDR = 0xff;
    PBDR = 0xc0;
    PBDDR = 0xfe; /* Motor Drive Board Vol.3 */
    /* 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; /* Flag clear */
    cnt0++;
    cnt1++;
    }

    /************************************************** **********************/
    /* 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;

    /* Since bit0 is for left and bit7 is for right in the new sensor board which is reversed */
    /* to the previous sensor board, the bit has been replaced to maintain compatibility. */
    sensor = bit_change( sensor ); /* Bit replacement */
    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 Value to be changed */
    /* RReturn value Changed value */
    /************************************************** **********************/
    char unsigned bit_change( char unsigned in )
    {
    unsigned char ret;
    int i;

    for( i=0; i<8; i++ ) {
    ret >>= 1; /* Right shift of return value */
    ret |= in & 0x80; /* Ret bit7 = in bit7 */
    in <<= 1; /* Left shift of argument */
    }
    return ret;
    }

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

Về tác giả

Collapse

gaby_boy Tìm hiểu thêm về gaby_boy

Bài viết mới nhất

Collapse

Đang tải...
X