目次

デジタル回路で車を動かす

 IchigoJamのBASICで、ライントレーサを動かす
 ことができました。

 プログラムでできることは、回路でも可能です。

 最近は、マイクロコンピュータで済ませる傾向が
 ありますが、何らかの原因でプログラムを失うと
 動作できません。

 ハードウエアだけで実現する方法を考えます。

 プログラムを眺めます。

 20 R=IN(1):L=IN(2)
 25 ? L,R
 30 OUT 4,1:OUT 2,1
 50 IF R=0 THEN OUT 4,R:WAIT 15
 60 IF L=0 THEN OUT 2,L:WAIT 15
100 GOTO 20

 デジタル回路で繰り返しさせるには
 カウンタを利用。次のようにすれば
 よいはず。




 カウンタ4024は、Q1からQ7をもっていますので
 Q6が'1'になった瞬間にリセットし、0から32を
 繰り返します。

 デジタル回路でプログラムと等価なことを
 やらせるには、カウンタ利用のシーケンサ
 を使います。

 カウンタはクロックを入れておけば
 必ずループを作るので、カウンタの
 出力にデコーダを接続して、他回路
 に命令を出す構成にします。

 図で描くと、以下。



 シーケンサは、ステートマシンとも呼ばれるので
 カウンタの出力をステートとして、何をするのか
 を書き出します。

 0 
 1 ドライブ回路に(1,1)を出力
 2 
 3 センサー情報を記憶
 4 ドライブ回路にセンサー情報を加工した値を出力
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 0に戻る

 このシーケンサでは、時間待ちを何もしない
 ステートを用意して対応。

 シーケンサを実現する回路は、以下。



 Q1からQ5があるので、状態は0から31になってます。

 Q1からQ4の出力をデコーダに伝達するには、Q5が'0'を
 出力している場合に限定。Q1からQ4では、0から15を
 出力しますが、Q5が'1'のときは、0を出力しカウンタ
 として動作していないように見せます。

 シーケンサの出力信号をデコードして
 センサー信号を記憶し、襷がけにして
 ドライブ回路に出力するようにします。




 ドライブ回路に、制御信号を出力するため
 セレクタを使っています。セレクタのため
 RSラッチを使って、切り替えておきます。

 全体をまとめます。



 シーケンサ部分をPIC12F1501を利用すると、次の回路に。



 発振器、カウンタ、デコーダを1チップにまとめれます。

 ファームウエアは、以下。

/*
  File Name : seqx.c
  
  Pin assignment
    GP0 -> set     (74HC74 SET)
    GP1 -> trigger (74HC74 CLK)
    GP2 -> monitor LED
    GP3 -> RESET
    GP4 -> input
    GP5 -> input

*/
/* redefine data type */
typedef unsigned char UBYTE ;

#define OFF 0
#define ON  OFF+1

#define CNTBEGIN 6

volatile UBYTE tflag ;
volatile UBYTE sflag ;
volatile UBYTE aport ;
volatile UBYTE state ;
volatile UBYTE xcnt ;
volatile UBYTE ycnt ;

/* function prototype */
void init_usr(void);
void snd_set(void);
void snd_trg(void);

/* interrupt handler */
void interrupt(void)
{
  /* timer 0 generate 1kHz */
  if ( INTCON.T0IF == ON ) {
    /* clear flag */
    INTCON.T0IF = OFF ;
    /* initialize */
    TMR0 = CNTBEGIN ;
    /* set flag */
    tflag = ON ;
  }
}

void snd_set(void)
{
  /* get PORTA state */
  aport = PORTA ;
  /* send 'L' */
  aport = aport & 0xfe ;
  /* impress */
  PORTA = aport ;
  /* send 'H' */
  aport = aport | ON ;
  /* impress */
  PORTA = aport ;
}

void snd_trg(void)
{
  /* get PORTA state */
  aport = PORTA ;
  /* send 'H' */
  aport = aport | 2 ;
  /* impress */
  PORTA = aport ;
  /* send 'L' */
  aport = aport & 0xfd ;
  /* impress */
  PORTA = aport ;
}

void main(void)
{
  /* user initialize */
  init_usr();
  /* endless loop */
  while ( ON ) {
    /* timer handler */
    if ( tflag == ON ) {
      /* clear flag */
      tflag = OFF ;
      /* update */
      state = state +  1 ;
      /* update */
      state = state % 4 ;
      /* enable sequence */
      sflag = ON ;
      /* increment */
      xcnt = xcnt + 1 ;
      /* judge */
      if ( xcnt == 250 ) {
        xcnt = 0 ;
        ycnt = ycnt + 1 ;
      }
      /* monitor */
      aport = PORTA ;
      if ( ycnt & 1 ) { aport = aport | 4 ; }
      else            { aport = aport & 0xfb ; }
      /* impress */
      PORTA = aport ;
    }
    /* sequence */
    if ( sflag == ON ) {
      /* clear flag */
      sflag = OFF ;
      /* set */
      if ( state == 0 ) { snd_set(); }
      /* latch */
      if ( state == 2 ) { snd_trg(); }
    }
  }
}

/* define function body */
void init_usr(void)
{
  /* 4MHz */
  OSCCON = (0x0d << 3) | 0x03 ;
  /* disable A/D converter */
  ADCON0.ADON = OFF ;
  ADCON2      = 0 ;
  /* disable D/A converter */
  DACCON0.DACEN = OFF ;
  /* disable compare module */
  CM1CON0.C1ON = OFF ;
  CM1CON0.C1OE = OFF ;
  /* I/O state */
  PORTA = 0x01 ;
  /* I/O directions */
  TRISA = 0xf8 ; /* bit0,1,2 as output , others as input */
  /* pull-up */
  WPUA = 0x30 ;
  /* initialize Timer 0 */
  {
    /*
       4MHz/4 = 1MHz -> 1MHz/8 = 125kHz prescaler = 1:8
       125kHz/250 = 500Hz
    */
    OPTION_REG = 0x02 ;
    /* 256 - 6 = 250 */
    TMR0 = CNTBEGIN ;
    /* enable timer0 overflow interrupt */
    INTCON.T0IE = ON ;
  }
  /* enable general interrupt */
  INTCON.GIE = ON ;
  /* clear flag */
  tflag = OFF ;
  sflag = OFF ;
  /* others */
  state = 0 ;
  xcnt = 0 ;
  ycnt = 0 ;
}


目次

inserted by FC2 system