目次

動作テスト(PIC)

 ハーフブリッジICのSN754410NEを
 基板に半田付けして、動作テスト
 してみます。



 コネクタは、以下のように接続。

 テストには、PIC16F873を利用。



 ポートAは、次のように使います。

 ポートBは、センサーからの入力にします。



 MSBが左、LSBが右になります。

 ポートA、Bの初期設定は、以下。

  PORTA = 0x03 ; /* left , right must be '1' */
  PORTB = 0x00 ;

  TRISA = 0xf0 ; /* upper : inputs , lower : outputs */
  TRISB = 0xf0 ; /* all bits : inputs */


 ポートAに関係する処理を定義していきます。

 スタートトリガー

  スタートトリガーは、テスト車両の後部にあります。



  このスイッチを利用して、ドライバICのEnable端子の
  論理値を決定します。

  スイッチの状態をタイマー割込みで、入力。
  シフトレジスタのLSBに格納後、変化を検出
  したなら、Enableに論理値を変更。

  タイマー割込みで、トリガーを与えられたなら
  次のコードが実行されるようにします。

  typedef unsigned char UBYTE

  UBYTE xflags ;
  UBYTE swsft  ;
  UBYTE mcnt   ;

  #define SFLAG xflas.F1

  #define XEN   PORTA.F2
  #define XSW   PORTA.F4

  if ( SFLAG == ON ) {
    /* clear flag */
    SFLAG = OFF ;
    /* shift */
    swsft = swsft + swsft ;
    /* mask */
    swsft = swswft & 3 ;
    /* get switch state */
    if ( XSW == OFF ) { swsft = swsft | ON ; }
    /* judge */
    if ( swsft == 1 ) {
      mcnt = mcnt + 1 ;
      mcnt = mcnt & ON ;
      /* update flag */
      XEN = mcnt ;
    }
  }

  MikroCを利用することを考えているので
  ビットごとの処理が単純になっています。

 モード設定

  モードは、移動とテストの2種で、トグルスイッチで
  指定します。電源投入したら、トグルスイッチの状態
  をリードして、モードを指定します。

  モードは、次のように決めました。

  0 移動
  1 テスト

  単純に、次のように定義。

  #define MFLAG xflas.F2

  #define TSW   PORTA.F5

  MFLAG = OFF ;
  if ( TSW == ON ) { MFLAG = ON ; }

 PWM波形生成

  PWM波形は、ポートAのビット1、0に出力すると
  して、タイマー割込みの中に、次のように組み入れ
  します。

  if ( INTCON.T0IF == ON ) {
    /* clear flag */
    INTCON.T0IF = OFF ;
    /* initialize */
    TMR0 = CNTBEGIN ;
    /* get now state */
    aport = PORTA :
    /* judge */
    if ( pcnt < llx ) { aport = aport & 0xfd ; }
    if ( pcnt < rrx ) { aport = aport & 0xfe ; }
    /* impress */
    PORTA = aport ;
    /* increment */
    pcnt = pcnt + 1 ;
    /* initialize */
    if ( pcnt == PCNTMX ) {
      pcnt = 0 ;
      llx  = left  ;
      rrx  = right ;
    }
  }

  タイマー割込みの周期は、1ms程度としておきます。

 LED点滅

  コンピュータが、動作しているのかを示すために
  LEDを点滅させます。人間にとって、わかりやすく
  するためだけに使います。

  1秒ごとに、LEDに対して0か1を設定していきます。

  タイマー割込みの中に、組み込んでしまいます。

  #define LOUT PORTA.F3

  typedef unsigned short UWORD ;

  UWORD lcnt  ;
  UBYTE lcntx ;

  if ( INTCON.T0IF == ON ) {
    /* clear flag */
    INTCON.T0IF = OFF ;
    /* initialize */
    TMR0 = CNTBEGIN ;
    /* get now state */
    aport = PORTA :
    /* judge */
    if ( pcnt < llx ) { aport = aport & 0xfd ; }
    if ( pcnt < rrx ) { aport = aport & 0xfe ; }
    /* impress */
    PORTA = aport ;
    /* increment */
    pcnt = pcnt + 1 ;
    /* initialize */
    if ( pcnt == PCNTMX ) {
      pcnt = 0 ;
      llx  = left  ;
      rrx  = right ;
    }
    /* LED handling */
    lcnt = lcnt + 1
    if ( lcnt == 1000 ) {
      lcnt  = 0 ;
      lcntx = lcntx + 1 ;
      LOUT  = lcntx & 1 ;
    }
  }

 PIC16F873、ドライバIC基板、モータその他を
 接続すると、次のようになります。



 ハードウエアの動作テストまで含めたプログラムは以下。

/*
  file name mcrx.c

  abstract  control MCR machine
  CPU       PIC16F876
  CLOCK     20MHz

  PORTA
    5 mode
    4 start trigger
    3 LED
    2 enable
    1 left
    0 right

  PORTB (sensor)

  white => '0'
  black => '1'

*/
#define OFF 0
#define ON  OFF+1

#define CNTBEGIN 6
#define PCNTMAX  100
#define SCNTMAX  50

#define MSW  PORTA.F5
#define XSW  PORTA.F4
#define XLED PORTA.F3
#define XEN  PORTA.F2

typedef unsigned char UBYTE ;

volatile UBYTE xflag ;

/* set flag bit */
#define TFLAG xflag.F0
#define SFLAG xflag.F1
#define MFLAG xflag.F2
#define RFLAG xflag.F3
#define UFLAG xflag.F4

volatile UBYTE swsft ;
volatile UBYTE sensor ;
volatile UBYTE lcnt ;
volatile UBYTE mcnt ;
volatile UBYTE pcnt ;
volatile UBYTE scnt ;
volatile UBYTE rrx ;
volatile UBYTE llx ;
volatile UBYTE right ;
volatile UBYTE left ;
volatile UBYTE aport ;
volatile UBYTE cmd ;
volatile UBYTE ch ;
volatile UBYTE sbuf[8] ;
volatile UBYTE sindex ;

/* interrupt handler */
void interrupt(void)
{
  /* timer0 interrupt */
  if ( INTCON.T0IF == ON ) {
    /* clear flag */
    INTCON.T0IF = OFF ;
    /* initialize */
    TMR0 = CNTBEGIN ;
    /* impress */
    aport = PORTA ;
    if ( pcnt < rrx ) { aport.F0 = OFF ; }
    if ( pcnt < llx ) { aport.F1 = OFF ; }
    PORTA = aport ;
    /* increment */
    pcnt = pcnt + 1 ;
    /* judge */
    if ( pcnt == PCNTMAX ) {
      /* clear counter */
      pcnt = 0 ;
      /* reload */
      rrx = right ;
      llx = left  ;
    }
    /* increment */
    scnt = scnt + 1 ;
    /* judge */
    if ( scnt == SCNTMAX ) {
      /* clear counter */
      scnt = 0 ;
      /* set flags */
      SFLAG = ON ;
      TFLAG = ON ;
      /* increment */
      lcnt = lcnt + 1 ;
      /* update LED state */
      XLED = lcnt & ON ;
     }
  }
  /* judge interrupt term */
  if ( PIR1.RCIF == ON ) {
    /* clear flag */
    PIR1.RCIF = OFF ;
    /* get data */
    ch = RCREG ;
    /* store */
    *(sbuf+sindex) = ch ;
    /* update pointer */
    sindex++ ;
    /* judge */
    if ( ch == '\r' ) {
      sindex = 0 ;
      UFLAG  = ON ;
    }
  }
}

/* function prototype */
void  init_usr(void);
UBYTE get_sensor(void);
void  rs_putc(UBYTE x);
void  rs_puts(UBYTE *ptr);
void  crlf(void);
void  show_help(void);
void  show_sensor(void);
void  show_mode(void);

void main(void)
{
  /* initialize */
  init_usr() ;
  /* endless loop */
  while ( ON ) {
    /* update */
    XEN = RFLAG ;
    /* test mode */
    if ( MFLAG == ON )
    {
      /* command interpreter */
      if ( UFLAG == ON ) {
        /* clear flag */
        UFLAG = OFF ;
        /* get command */
        cmd = *(sbuf+0) ;
        /* help */
        if ( cmd == '?' ) { show_help(); }
        if ( cmd == 'E' ) { RFLAG = ON ; }
        if ( cmd == 'D' ) { RFLAG = OFF; }
        if ( cmd == 'R' ) { right = 75 ; }
        if ( cmd == 'r' ) { right = 5  ; }
        if ( cmd == 'L' ) { left = 75 ; }
        if ( cmd == 'l' ) { left = 5  ; }
        if ( cmd == 'S' ) { show_sensor(); }
        if ( cmd == 'M' ) { show_mode(); }
      }
    } else {
      /* shift register handling */
      if ( SFLAG == ON ) {
        /* clear flag */
        SFLAG = OFF ;
        /* shift */
        swsft = swsft + swsft ;
        /* mask */
        swsft = swsft & 3 ;
        /* get switch state */
        if ( XSW == OFF ) { swsft = swsft | ON ; }
        /* judge */
        if ( swsft == 1 ) {
          mcnt = mcnt + 1  ;
          mcnt = mcnt & ON ;
          RFLAG = mcnt ;
        }
      }
      /* move handling */
      if ( TFLAG == ON ) {
        /* clear flag */
        TFLAG = OFF ;
        /* get sensor */
        sensor = get_sensor() ; 
        /* default */
        right = 50 ;
        left  = 50 ;
        /* judge */
        if ( sensor == 1 ) {
          right = 60 ;
          left  = 40 ; 
        }
        if ( sensor == 4 ) {
          right = 40 ;
          left  = 60 ; 
        }
      }
    }
  }
}

/* define function body */
void init_usr(void)
{
  /* I/O values */
  PORTA = 0x03 ;
  PORTB = 0x00 ;
  /* I/O directions */
  TRISA = 0xf0 ; /* upper : inputs , lower : outputs */
  TRISB = 0xff ; /* all : inputs */
  TRISC = 0x80 ;
  /* initialize Timer 0 */
  {
    /*
       20MHz/4 = 5MHz (BUS clock) -> 5MHz/4 = 1.25MHz prescaler = 1:4
    */
    OPTION_REG = 0x01 ;
    /* 256 - 6 = 250 */
    TMR0 = CNTBEGIN ;
    /* enable timer0 overflow interrupt */
    INTCON.TMR0IE = ON ;
  }
  /* initialize UART */
  {
    /* enable TxD */
    TXSTA = (1 << BRGH) | (1 << TXEN);
    /* enable RxD */
    RCSTA = (1 << SPEN) | (1 << CREN) ;
    /* 9600 bps */
    SPBRG = 129 ;
    /* enable receive interrupt */
    PIE1.RCIE = ON ;
    /* clear */
    sindex = 0 ;
    /* periheral interrupt */
    INTCON.PEIE = ON ;
  }
  /* enable general interrupt */
  INTCON.GIE = ON ;
  /* clear flags */
  xflag = 0 ;
  /* set flag */
  if ( MSW == ON ) { MFLAG = ON ; }
  /* initialize variables */
  pcnt   = 0  ;
  right  = 50 ;
  left   = 50 ;
  scnt   = 0  ;
  mcnt   = 0  ;
  sindex = 0  ;
}

UBYTE get_sensor(void)
{
  UBYTE result ;
  UBYTE tmp ;
  /* get sensor data */
  tmp = PORTB ;
  tmp = tmp ^ 0xff ;
  /* default */
  result = 0 ;
  /* 6,3,1 bit */
  if ( tmp & 0x40 ) { result = result | 4 ; }
  if ( tmp & 0x08 ) { result = result | 2 ; }
  if ( tmp & 0x02 ) { result = result | 1 ; }

  return result ;
}

void  rs_putc(UBYTE x)
{
  /* judge empty */
  while ( TXSTA.TRMT == OFF ) ;
  /* transmit */
  TXREG = x ;
}

void  rs_puts(UBYTE *ptr)
{
  while ( *ptr != '\0' ) {
    rs_putc(*ptr);
    ptr++ ;
  }
}

void  crlf(void)
{
  rs_putc('\r');
  rs_putc('\n');
}

void  show_help(void)
{
  rs_puts("? help")              ; crlf();
  rs_puts("E enable")            ; crlf();
  rs_puts("D disable")           ; crlf();
  rs_puts("R rotate right")      ; crlf();
  rs_puts("r stop right")        ; crlf();
  rs_puts("L rotate left")       ; crlf();
  rs_puts("l stop left")         ; crlf();
  rs_puts("S show sensor value") ; crlf();
  rs_puts("M show mode")         ; crlf();
}

void  show_sensor(void)
{
  UBYTE tmp ;
  UBYTE smsg[4] ;
  /* get sensor */
  tmp = get_sensor() ;
  /* separate */
  *(smsg+3) = '\0' ;
  *(smsg+2) = (tmp & ON) + '0' ; tmp = tmp >> 1 ;
  *(smsg+1) = (tmp & ON) + '0' ; tmp = tmp >> 1 ;
  *(smsg+0) = (tmp & ON) + '0' ;
  /* show */
  rs_puts(smsg);
  /* new line */
  crlf();
}

void  show_mode(void)
{
  if ( MFLAG == ON ) { rs_puts("TEST"); }
  else               { rs_puts("MOVE"); }
  /* new line */
  crlf();
}


目次

inserted by FC2 system