目次

パターン生成スケッチ

 次の回路の動作テストのため、Arduinoから3ビットの
 信号パターンを生成します。
 (CLK、nTRG、nRESETを生成)



 オシロスコープ、ロジックアナライザーで設計通りになって
 いるのかを波形で確認するときに、繰返し、3ビットの信号
 を与えます。

 その組み合わせは、以下としました。

 n  CLK nTRG nRESET
 0   1    1    0
 1   1    1    0
 2   0    1    1
 3   0    1    1
 4   1    1    1
 5   1    0    1
 6   0    0    1
 7   0    0    1
 8   1    0    1
 9   1    0    1
10   0    0    1
11   0    0    1
12   1    0    1
13   1    0    1
14   0    0    1
15   0    0    1
16   1    0    1
17   1    0    1
18   0    0    1
19   0    0    1

 タイミングチャートでは、次のようになります。



 パターンを拾って16進数にするのは、面倒なので
 AWKを利用してパターンを変換しました。
 AWKスクリプトは、以下。

{
  result = 0 ;
  for ( i = 2 ; i < 5 ; i++ ) {
    result = result * 2 ;
    result += $i ;
  }
  printf("%s *(pat+%2d) = 0x%02X\n",$0,$1,result);
}

 Arduinoスケッチの中に、配列として保存できるように
 ファイルに設定を格納すると、次のようになります。

 0 1 1 0 *(pat+ 0) = 0x06
 1 1 1 0 *(pat+ 1) = 0x06
 2 0 1 1 *(pat+ 2) = 0x03
 3 0 1 1 *(pat+ 3) = 0x03
 4 1 1 1 *(pat+ 4) = 0x07
 5 1 0 1 *(pat+ 5) = 0x05
 6 0 0 1 *(pat+ 6) = 0x01
 7 0 0 1 *(pat+ 7) = 0x01
 8 1 0 1 *(pat+ 8) = 0x05
 9 1 0 1 *(pat+ 9) = 0x05
10 0 0 1 *(pat+10) = 0x01
11 0 0 1 *(pat+11) = 0x01
12 1 0 1 *(pat+12) = 0x05
13 1 0 1 *(pat+13) = 0x05
14 0 0 1 *(pat+14) = 0x01
15 0 0 1 *(pat+15) = 0x01
16 1 0 1 *(pat+16) = 0x05
17 1 0 1 *(pat+17) = 0x05
18 0 0 1 *(pat+18) = 0x01
19 0 0 1 *(pat+19) = 0x01

 配列にパターンを格納する処理は、setupの中に。

void setup(void)
{
  /* initialilze serial port */
  Serial.begin(9600);
  sindex = 0 ;
  /* set I/O values */
  PORTB = 0x00 ;
  PORTC = 0x00 ;
  PORTD = 0x01 ;
  /* set port directions */
  DDRB = 0xff ;
  DDRC = 0xff ; 
  DDRD = 0xfe ;
  /* clear flags */
  uflag = OFF ;
  tflag = OFF ;
  /* initialize ring buffer */
  *(pat+ 0) = 0x06 ; *(pat+ 1) = 0x06 ;
  *(pat+ 2) = 0x03 ; *(pat+ 3) = 0x03 ;
  *(pat+ 4) = 0x07 ; *(pat+ 5) = 0x05 ;
  *(pat+ 6) = 0x01 ; *(pat+ 7) = 0x01 ;
  *(pat+ 8) = 0x05 ; *(pat+ 9) = 0x05 ;
  *(pat+10) = 0x01 ; *(pat+11) = 0x01 ;
  *(pat+12) = 0x05 ; *(pat+13) = 0x05 ;
  *(pat+14) = 0x01 ; *(pat+15) = 0x01 ;
  *(pat+16) = 0x05 ; *(pat+17) = 0x05 ;
  *(pat+18) = 0x01 ; *(pat+19) = 0x01 ;
  state = 0 ;
  /* 10ms period */
  MsTimer2::set(10,update_trg);
  /* enable */
  MsTimer2::start();
  /* mode */
  mode = IDLE ;
}

 タイマー割込みで、パターンを出力するため
 周期を10msとしました。
 10msごとにフラグをセットします。

void update_trg()
{
  tflag = ON ;
}

 10msごとにtflagがセットされるので、シーケンサで
 処理させます。

  if ( tflag == ON ) {
    /* clear flag */
    tflag = OFF ;
    /* RUN */
    if ( mode == RUN ) {
      /* get pattern */
      tmp = *(pat+state) ;
      /* impress */
      PORTC = tmp ;
      /* update state */
      state++ ;
      if ( state == 20 ) { state = 0 ; }
    }
    /* IDLE */
    if ( mode == IDLE ) {
      PORTC = 0x00 ;
    }
  }

 シーケンサを動かすために、変数stateを用意します。
 また変数modeは、ビットパターンを出力するか否かの
 判断に利用します。

 変数mode、stateは、コマンドを用意して、シリアルで
 変更します。

  if ( uflag == ON ) {
    /* clear flag */
    uflag = OFF ;
    /* new line */
    crlf();
    /* get command */
    cmd = *(sbuf+0) ;
    /* help */
    if ( cmd == '?' ) { show_help() ; }
    /* eanble */
    if ( cmd == 'P' ) {
      /* clear state  */
      state = 0 ;
      /* mode : RUN */
      mode = RUN ;
    }
    /* disable */
    if ( cmd == 'p' ) {
      /* mode : IDLE */
      mode = RUN ;
    }
  }

 スケッチにまとめます。

#include <MsTimer2.h>

#define OFF 0
#define ON  OFF+1

#define XIDLE 0
#define RUN   XIDLE+1

volatile byte tflag;
volatile byte uflag;
volatile char sbuf[8];
volatile byte sindex;
volatile byte mode ;
volatile byte state ;
volatile byte pat[20];

void  rs_putchar(char x)
{
  Serial.write(x);
}

void  rs_puts(char *ptr)
{
  while ( *ptr ) {
    rs_putchar( *ptr );
    ptr++ ;
  }
}

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

void  show_help()
{
  rs_puts("? help");                    crlf();
  rs_puts("P enable sending pattern");  crlf();
  rs_puts("p disable sending pattern"); crlf();
}

/* Serial Receive interrupt routine */
void serialEvent()
{
  char ch;

  if ( Serial.available() > 0 ) {
    /* get 1 charactor */
    ch = Serial.read();
    /* store */
    *(sbuf+sindex) = ch ;
    /* increment */
    sindex++ ;
    /* judge */
    if ( ch == '\r' ) {
      sindex = 0 ; 
      uflag = ON ;
    }
  }
}

void update_trg()
{
  tflag = ON ;
}

void  setup (void)
{
  /* initialilze serial port */
  Serial.begin(9600);
  sindex = 0 ;
  /* set I/O values */
  PORTB = 0x00 ;
  PORTC = 0x00 ;
  PORTD = 0x01 ;
  /* set port directions */
  DDRB = 0xff ;
  DDRC = 0xff ; 
  DDRD = 0xfe ;
  /* clear flags */
  uflag = OFF ;
  tflag = OFF ;
  /* initialize bit pattern */
  *(pat+ 0) = 0x06 ; *(pat+ 1) = 0x06 ;
  *(pat+ 2) = 0x03 ; *(pat+ 3) = 0x03 ;
  *(pat+ 4) = 0x07 ; *(pat+ 5) = 0x05 ;
  *(pat+ 6) = 0x01 ; *(pat+ 7) = 0x01 ;
  *(pat+ 8) = 0x05 ; *(pat+ 9) = 0x05 ;
  *(pat+10) = 0x01 ; *(pat+11) = 0x01 ;
  *(pat+12) = 0x05 ; *(pat+13) = 0x05 ;
  *(pat+14) = 0x01 ; *(pat+15) = 0x01 ;
  *(pat+16) = 0x05 ; *(pat+17) = 0x05 ;
  *(pat+18) = 0x01 ; *(pat+19) = 0x01 ;
  /* 10ms period */
  MsTimer2::set(10,update_trg);
  /* enable */
  MsTimer2::start();
  /* others */
  state = 0 ;
  mode  = XIDLE ;
}

void loop (void)
{
  byte tmp ;
  char cmd ;
  /* UART handling */
  if ( uflag == ON ) {
    /* clear flag */
    uflag = OFF ;
    /* new line */
    crlf();
    /* get command */
    cmd = *(sbuf+0) ;
    /* help */
    if ( cmd == '?' ) { show_help() ; }
    /* enable */
    if ( cmd == 'P' ) {
      /* clear state  */
      state = 0 ;
      /* mode : RUN */
      mode = RUN ;
    }
    /* disable */
    if ( cmd == 'p' ) {
      /* mode : IDLE */
      mode = XIDLE ;
    }
  }
  /* timer interrupt */
  if ( tflag == ON ) {
    /* clear flag */
    tflag = OFF ;
    /* RUN */
    if ( mode == RUN ) {
      /* get pattern */
      tmp = *(pat+state) ;
      /* update state */
      state++ ;
      if ( state == 20 ) { state = 0 ; }
    }
    /* IDLE */
    if ( mode == XIDLE ) {
      tmp = 0x00 ;
    }
    /* impress */
    PORTC = tmp ;
  }
}


目次

inserted by FC2 system