目次
前
次
パターン生成スケッチ
次の回路の動作テストのため、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 ;
}
}
目次
前
次