目次

琴似工業高校マシン整備

 札幌国際情報高校でMCR全国大会が開かれるのは
 よく知られていることです。

 全国大会会場から車で10分ほどの場所に、創世期のMCRを
 支えた北海道札幌琴似工業高校があります。



 非常勤講師で通っていた大学での教え子に、北海道札幌琴似工業高校
 出身者がいました。「夏休みは暇だ。」というので、MCR委員会販売の
 標準キットがあれば、走らせてみるかと言葉をかけると、のってきた
 ので、改造することに。



 使われていたH8は、H8/3687(北斗電子)だったので
 H8/3048FOne(24.576MHz)に交換。

 Hブリッジを使った制御基板から、次の回路に変更しました。



 DCモータ2個、サーボモータ1個のためにフォトカプラと
 パワートランジスタでドライバを構成。スタートトリガー
 をプッシュボタンと抵抗でまとめることに。

 なるべく原型を崩したくなかったので、木片の上に
 H8、制御基板を載せてます。

 テスト用ファームウエアは、以下としました。

#include "3052.h"

typedef unsigned char  UBYTE ;
typedef unsigned short UWORD ;
typedef unsigned long  ULONG ;
typedef   signed char  SBYTE ;
typedef   signed short SWORD ;

#define NO  0
#define YES 1

/*----------------*/
/* user variables */
/*----------------*/
#define ITU0_AREG 24576
#define ITU1_AREG 245

ULONG timcnt ;

#define P4DDR P4.DDR
#define P4DR  P4.DR.BYTE
#define P6DDR P6.DDR
#define P6DR  P6.DR.BYTE
#define P8DDR P8.DDR
#define P8DR  P8.DR.BYTE
#define P7DR  P7.DR.BYTE
#define P9DDR P9.DDR
#define P9DR  P9.DR.BYTE
#define PADDR PA.DDR
#define PADR  PA.DR.BYTE
#define PBDDR PB.DDR
#define PBDR  PB.DR.BYTE

#define MASKFFFF 0xffff
#define MASKFF   0xff
#define MASKCF   0xcf
#define MASK0F   0x0f
#define MASK3F   0x3f
#define MASK07   0x07
#define OFF      0
#define ON       OFF+1

#define MASK80 0x80

#define SW_START  PB.DR.BIT.B4

void init_sci_1(TBaudRate x);
void rs1_putchar(UBYTE x);
void rs1_crlf(void);
void rs1_puts(UBYTE *x);
void show_help(void);
void show_value(UBYTE x);

UBYTE uflag ;
UBYTE sindex ;
UBYTE sbuf[32];
UBYTE cmd ;

UBYTE sflag ;
UBYTE start_sft ;

UBYTE asc_hex[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'} ;

UBYTE pcnt ;
UBYTE rduty ;
UBYTE lduty ;
UBYTE rdutyx ;
UBYTE ldutyx ;

UWORD scnt ;
UBYTE servoduty ;
UBYTE servodutyx ;

UBYTE xport ;

/*--------------------------------*/
/* Insert user functions protoype */
/*--------------------------------*/
void  user_initialize(void);
void  init_timer0();
void  init_timer1();

UBYTE get_hex(UBYTE x);
void  delay_ms(UWORD x);

/*------*/
/* main */
/*------*/
int main(void)
{
  UBYTE tmp  ;
  UWORD tmpx ;
  UBYTE i ;
  /* disable interrupt */
  DI ;
  /* initialize */
  user_initialize();
  /* enable interrupt */
  EI ;
  /* opening message */
  rs1_puts("Hello"); rs1_crlf();
  /* loop */
  while ( ON ) {
    /* command interpreter */
    if ( uflag == ON ) {
      /* clear flag */
      uflag = OFF ;
      /* new line */
      rs1_crlf();
      /* get command */
      cmd = *(sbuf+0) ;
      /* judge */
      if ( cmd == '?' ) { show_help() ; }
      /* DC motor test */
      if ( cmd == 'M' ) {
        /* get duty ratio */
        tmp = get_hex( *(sbuf+1) );
        tmp *= 10 ;
        tmp += get_hex( *(sbuf+2) );
        /* set duty ratio */
        i = *(sbuf+3) ;
        if ( i == 'R' ) { rduty = tmp ; }
        if ( i == 'L' ) { lduty = tmp ; }
        if ( i == 'B' ) { rduty = tmp ; lduty = tmp ;}
      }
      /* servo motor test */
      if ( cmd == 'S' ) {
        /* get duty ratio */
        tmp = get_hex( *(sbuf+1) );
        tmp *= 10 ;
        tmp += get_hex( *(sbuf+2) );
        /* store */
        if ( 100 <= tmp && tmp <= 200 ) {
          servoduty = tmp ;
        } else {
          servoduty = 150 ;
        }
      }
    }
    /* test start trigger */
    if ( sflag == ON ) {
      /* clear flag */
      sflag = OFF ;
      /* show */
      rs1_puts("go") ;
      rs1_crlf();
    }
  }
  return 0 ;
}

/*-----------------------*/
/* Insert user functions */
/*-----------------------*/
void user_initialize(void)
{
  int i ;
  /* PORT 6 */
  P6DR  = 0xf0 ;
  P6DDR = 0xf6 ; /* P60 , P63 inputs , others output */
  /* PORT 8 */
  P8DR  = 0x02 ;
  P8DDR = MASKFF ; /* all outputs */
  /* PORT B */
  PBDR  = 0x00 ;
  PBDDR = MASKCF ; /* PB5,PB4 inputs , others are outputs */
  /* PORT A */
  PADR  = 0      ;
  PADDR = MASKFF ; /* all outputs */
  /* PORT 4 */
  P4DR  = 0x00 ; /* disable all */
  P4DDR = 0xef ; /* P44 : inputs , others : outputs */
  /* initialize timers */
  init_timer0();
  init_timer1();
  /* clear flags */
  sflag = OFF ;
  uflag = OFF ;
  /* clear SCI buffer */
  *(sbuf+0) = 0 ; sindex = 0 ;
  /* initialize */
  timcnt = 0 ;
  pcnt       = 0 ;
  rduty      = 0 ;
  lduty      = 0 ;
  rdutyx     = 0 ;
  ldutyx     = 0 ;
  start_sft  = 0 ;
  scnt       = 0 ;
  servoduty  = 150 ;
  servodutyx = 150 ;
}

void init_timer0(void)
{
  /* stop timer */
  ITU.TSTR.BIT.STR0 = OFF ;
  /* TOER : Timer Output Enable Register
        7 **** -> 0
        6 **** -> 0
        5 EXB4 -> 0
        4 EXA4 -> 0
        3 EB3  -> 0
        2 EB4  -> 0
        1 EA4  -> 0
        0 EA3  -> 0
  */
  ITU.TOER.BYTE = 0 ;
  /* TIOR : Timer I/O Control Register
        7 **** -> 0
        6 IOB2 -> 0 GRB is not output compare match register
        5 IOB1 -> 0
        4 IOB0 -> 0
        3 **** -> 0
        2 IOA2 -> 0 GRA is not output compare match register
        1 IOA1 -> 0
        0 IOA0 -> 0
  */
  ITU0.TIOR.BYTE = 0 ;
  /* TCR : Timer Control Register
        7 ****  -> 0
        6 CCLR1 -> 0 clear TCNT if GRA = TCNT
        5 CCLR0 -> 1
        4 CKEG1 -> 0 rising edge
        3 CKEG0 -> 0
        2 TPSC2 -> 0 φ利用
        1 TPSC1 -> 0
        0 TPSC0 -> 0
  */
  ITU0.TCR.BYTE = 0x20 ;
  /* TIER : Timer Interrupt Enable Register
        7 ****  -> 0
        6 ***   -> 0
        5 ***   -> 0
        4 ***   -> 0
        3 ***   -> 0
        2 OVIE  -> 0
        1 IMIEB -> 0
        0 IMIEA -> 1 select compare match interrupt
  */
  ITU0.TIER.BIT.IMIEA = ON ;
  /* reference */
  ITU0.GRA = ITU0_AREG ;
  ITU0.GRB = MASKFFFF ;
  /* counter */
  ITU0.TCNT = 0 ;
  /* start timer */
  ITU.TSTR.BIT.STR0 = ON ;
}

void init_timer1(void)
{
  /* stop timer */
  ITU.TSTR.BIT.STR1 = OFF ;
  /* TOER : Timer Output Enable Register
        7 **** -> 0
        6 **** -> 0
        5 EXB4 -> 0
        4 EXA4 -> 0
        3 EB3  -> 0
        2 EB4  -> 0
        1 EA4  -> 0
        0 EA3  -> 0
  */
  ITU.TOER.BYTE = 0 ;
  /* TIOR : Timer I/O Control Register
        7 **** -> 0
        6 IOB2 -> 0 GRB is not output compare match register
        5 IOB1 -> 0
        4 IOB0 -> 0
        3 **** -> 0
        2 IOA2 -> 0 GRA is not output compare match register
        1 IOA1 -> 0
        0 IOA0 -> 0
  */
  ITU1.TIOR.BYTE = 0 ;
  /* TCR : Timer Control Register
        7 ****  -> 0
        6 CCLR1 -> 0 clear TCNT if GRA = TCNT
        5 CCLR0 -> 1
        4 CKEG1 -> 0 rising edge
        3 CKEG0 -> 0
        2 TPSC2 -> 0 φ利用
        1 TPSC1 -> 0
        0 TPSC0 -> 0
  */
  ITU1.TCR.BYTE = 0x20 ;
  /* TIER : Timer Interrupt Enable Register
        7 ****  -> 0
        6 ***   -> 0
        5 ***   -> 0
        4 ***   -> 0
        3 ***   -> 0
        2 OVIE  -> 0
        1 IMIEB -> 0
        0 IMIEA -> 1 select compare match interrupt
  */
  ITU1.TIER.BIT.IMIEA = ON ;
  /* reference */
  ITU1.GRA = ITU1_AREG ;
  ITU1.GRB = MASKFFFF ;
  /* counter */
  ITU1.TCNT = 0 ;
  /* start timer */
  ITU.TSTR.BIT.STR1 = ON ;
}

/*+++++++++++++++++++++++++++++++++++++*/
/* ITU0 interrupt with compare match A */
/*                        1ms interval */
/*+++++++++++++++++++++++++++++++++++++*/
void int_imia0(void)
{
  UBYTE dummy ;
  /* clear flag */
  dummy = ITU0.TSR.BIT.IMFA ;
  ITU0.TSR.BIT.IMFA = OFF ;
  /* increment */
  timcnt++ ;
  /* impress */
  xport &= 0xfc ;
  if ( pcnt < rdutyx ) { xport |= 0x01 ; }
  if ( pcnt < ldutyx ) { xport |= 0x02 ; }
  PBDR = xport ;
  /* increment */
  pcnt++ ;
  /* judge */
  if ( pcnt == 100 ) {
    pcnt = 0 ;
    rdutyx = rduty ;
    ldutyx = lduty ;
  }
  /* shift */
  start_sft <<= 1 ;
  start_sft &= 0x07 ;
  /* get start trigger switch */
  if ( SW_START == OFF ) { start_sft |= ON ; }
  /* judge */
  if ( sft == 0x01 ) { sflag = ON ; }
}

/*+++++++++++++++++++++++++++++++++++++*/
/* ITU1 interrupt with compare match A */
/*                      10us  interval */
/*+++++++++++++++++++++++++++++++++++++*/
void int_imia1(void)
{
  UBYTE dummy ;
  /* clear flag */
  dummy = ITU1.TSR.BIT.IMFA ;
  ITU1.TSR.BIT.IMFA = OFF ;
  /* increment */
  scnt++ ;
  /* impress */
  xport &= 0xfb ;
  if ( scnt < servodutyx ) { xport |= 0x04 ; }
  PBDR = xport ;
  /* judge */
  if ( scnt == 2000 ) {
    scnt = 0 ;
    servodutyx = servoduty ;
  }
}

/*+++++++++++++++++++++++++*/
/* SCI_1 receive interrupt */
/*+++++++++++++++++++++++++*/
void  init_sci_1(TBaudRate x)
{
  volatile UWORD i;
  /* SCR : Serial Control Register
    7 bit TIE  -> 0 Transmit Interrupt Enable(disable)
    6 bit RIE  -> 0 Receive  Interrupt Enable(disable)
    5 bit TE   -> 0 Transmit Enable(disable)
    4 bit RE   -> 0 Receive  Enable(disable)
    3 bit MPIE -> 0 Multi Processor Interrupt Enable(disable)
    2 bit TEIE -> 0 Transmit End Interrupt Enable(disable)
    1 bit CKE1 -> 0 Clock Source (Use Internal Baud Rate Generator)
    0 bit CKE0 -> 0 
  */
  SCI1.SCR.BYTE = 0 ;
  /* SMR : Serial Mode Register
    7 bit C/nA -> 0 Communication Mode(Asynchronous)
    6 bit CHR  -> 0 data Charactor (8 bits)
    5 bit PE   -> 0 Parity Enable(disable)
    4 bit O/nE -> 0 Parity Mode(even)
    3 bit STOP -> 0 Stop Bit(1 bit)
    2 bit MP   -> 0 Multi Processor(disable)
    1 bit CKS1 -> 0 Clock Source ( φ )
    0 bit CKS0 -> 0 
  */
  SCI1.SMR.BYTE = 0 ;
  /* data transfer speed */
  SCI1.BRR = x ;
  /* wait 1 frame */
  for (i = 0; i < 3000 ; i++) ;
  /* enable Transmmit and Receive with interrupt */
  SCI1.SCR.BYTE = 0x70 ;
}

/*+++++++++++++++++++++++++*/
/* SCI_1 receive interrupt */
/*+++++++++++++++++++++++++*/
void int_rxi1(void)
{
  volatile UBYTE ch,dummy ;
  /* clear flag */
  dummy = SCI1.SSR.BYTE ;
  SCI1.SSR.BIT.RDRF = OFF ;
  /* get a character */
  ch = SCI1.RDR ;
  /* store */
  *(sbuf+sindex) = ch ;
  sindex++ ;
  /* check */
  if ( ch == '\r' ) {
    *(sbuf+sindex) = 0 ;
    sindex = 0 ;
    UFLAG  = ON ;
  }
}

/*+++++++++++++++*/
/* SCI_1 putchar */
/*+++++++++++++++*/
void rs1_putchar(UBYTE x)
{
  /* wait data transfer */
  while ( SCI1.SSR.BIT.TDRE == OFF ) ;
  /* put */
  SCI1.TDR = x ;
  SCI1.SSR.BIT.TDRE = OFF ;
}

/*++++++++++++*/
/* SCI_1 puts */
/*++++++++++++*/
void rs1_puts(UBYTE *x)
{
  /* send 1 charactors */
  while ( *x ) {
    rs1_putchar(*x);
    x++ ;
  }
}

/*++++++++++++*/
/* SCI_1 crlf */
/*++++++++++++*/
void rs1_crlf(void)
{
  rs1_putchar('\r');
  rs1_putchar('\n');
}

/*++++++++++++++++++++*/
/* SCI_1 command help */
/*++++++++++++++++++++*/
void show_help(void)
{
  rs1_puts("? help")            ; rs1_crlf();
  rs1_puts("M test DC motor")   ; rs1_crlf();
  rs1_puts("S test servo motor"); rs1_crlf();
}

void show_value(UBYTE x)
{
  volatile UBYTE msg[2] ;
  volatile UBYTE i ;
  /* separate */
  *(msg+0) = (x >> 4) & MASK0F ;
  *(msg+1) = x & MASK0F ;
  /* conversion */
  *(msg+0) = asc_hex[ *(msg+0) ] ;
  *(msg+1) = asc_hex[ *(msg+1) ] ;
  /* output */
  rs1_putchar( *(msg+0) ) ;
  rs1_putchar( *(msg+1) ) ;
}

UBYTE get_hex(UBYTE x)
{
  UBYTE result ;
  /* default */
  result = 0 ;
  /* convert */
  if ( '0' <= x && x <= '9' ) { result = x - '0' ; }
  if ( 'A' <= x && x <= 'F' ) { result = x - 'A' + 10 ; }
  if ( 'a' <= x && x <= 'f' ) { result = x - 'a' + 10 ; }

  return result ;
}

void delay_ms(UWORD x)
{
  ULONG target ;
  /* calculate last value */
  target = timcnt + x ;
  /* wait */
  while ( timcnt < target ) ;
}


目次

inserted by FC2 system