TIOCB3は系統0,系統1,系統2,...,系統7
TOCXA4は系統8,系統9,系統10,...,系統15
TOCXB4は系統16,系統17,系統18,...,系統23
を周期8で連続して出力する
(1度に3系統ずつ出力される)
ポート1からの8ビットで01,02,04,08,10,20,40,80
を出すようにすれば,24個系統のAND回路で24系統の信号に分離できる。
バッファレジスタは使わない
初期設定手順
1.カウント動作停止
TSTRのSTR3ビットを0にクリアし、
TCNT3のカウント動作を停止する。
リセット同期PWMモードの設定は、TCNT3が
停止した状態で行なう。
2.カウンタクロックの選択
TCRのTPSC2〜TPSC0ビットでチャネル3の
カウンタクロックを選択する。
(外部クロックを選択した場合は、TCRのCKEG1、
CKEG0ビットで外部クロックのエッジを選択
する。今回これはなし)
3.カウンタクリア要因の選択
TCR3のCCLR1、CCLR0ビットでカウンタクリア
要因をGRA3のコンペアマッチに設定する。
4.リセット同期PWMモードの設定
TFCRのCMD1、CMD0ビットでリセット同期PWM
モードを設定する。
TIOCA3、TIOCB3、TIOCA4、TIOCB4、TOCXA4、
TOCXB3端子は自動的にPWM出力端子となる。
5.TCNTの設定
TCNT3は、H'0000としてください。TCNT4は、
設定する必要はない。
6.GRの設定
GRA3は周期レジスタである。GRA3には、周期を
設定してください。GRB3、GRA4、GRB4には、
PWM出力波形変化タイミングを設定する。
ただし、設定値は、TCNT3とコンペアマッチする
範囲で設定する。
X
≦ GRA3 (X:設定値)
7.GRA3のコンペアマッチで割り込むように設定
割り込みA参照
8.GRB3、GRA4、GRB4のうち一番大きな値のところでコンペアマッチ
割り込みを設定
割り込みB参照
7.カウント動作開始
TSTRのSTR3ビットを1にセットして、
TCNT3のカウント動作を開始してください。..
実行時の割り込み
割り込み2
GRB3、GRA4、GRB4を設定し,
一番大きな値のところでコンペアマッチ割り込みを設定
割り込み1
0-7を繰り返す周期カウンタを1アップする
P1のビットパターンを変更する。変更順は
00000001
00000010
00000100
00001000
:
10000000
IMIA3の割り込み:36 0x90-0x93
IMIB3の割り込み:37 0x94-0x97
IMIA4の割り込み:40 0xA0-0xA3
IMIB4の割り込み:41 0xA4-0xA7
このプログラムでのシリアル通信制御テスト
A,B,C,...V,W,Xの入力
系統0〜24のパルスをそれぞれ50μsec長くする
a,b,c,...v,w,xの入力
系統0〜24のパルスをそれぞれ50μsec短くする
0の入力
系統0〜24のパルスをすべて1500μsecの長さにする
1の入力
系統0〜24のパルスをすべて異なる長さにする
*/
#include "3048fone.h"
#include "h8_3048fone.h"
#define SELECT_PORT P1
/*パルス幅は最初1000,1000,1200,1000,1000,1000,2000,2000μsec*/
/*
1200,1100,2000,1200,1800,1700,1700,2000μsec*/
/*
1500,1100,2000,1300,1400,1500,2000,1600μsec*/
/*とする*/
/*★注意1 使用していない系統の値は1500に固定すること*/
/*★注意2 値は1000〜2000とする*/
int
pulseWidth[24]={ /*単位μsec*/
1000,1000,1200,1000,1000,1000,2000,2000,
1200,1100,2000,1200,1800,1700,1700,2000,
1500,1100,2000,1300,1400,1500,2000,1600
};
const unsigned char
portout[8]={1,2,4,8,0x10,0x20,0x40,0x80};
volatile int IntCounter=0;
/*割り込み回数を数えるカウンタ 0-7を繰り返す*/
/*****初期化関数*****/
void
initMultiPulseGen()
{
ITU.TSTR.BIT.STR3=0; /*ITU
ch3カウントストップ*/
ITU3.TCR.BIT.TPSC=3;
/*φ/8を使用(1クロック8/25μsec (=0.32μsec))*/
ITU3.TCR.BIT.CCLR=1; /*GRAとのコンペアマッチでTCNTクリア*/
ITU.TFCR.BIT.CMD=3;/*TFCRのCMD1、CMD0ビットでリセット同期PWMモード*/
ITU.TOCR.BIT.OLS3=0;/*マニュアル記述が逆だ*/
ITU.TOCR.BIT.OLS4=0;/*マニュアル記述が逆だ*/
ITU3.TCNT=0;
/*カウンタクリア*/
ITU3.GRA=( ( (unsigned short
int)(2500*25) )>>3 )-1; /*FRA3 2.5msec周期でTCNTはクリア これは固定*/
}
void startMultiPulse()
{
ITU3.TIER.BIT.IMIEA=1; /*GRA3コンペアマッチで割込*/
E_INT();
/*CPU割り込み許可*/
IntCounter=0;
/* ITU3.TCNT=ITU3.GRA-5;*/
SELECT_PORT.DR.BYTE=portout[IntCounter];
ITU.TSTR.BIT.STR3=1; /*ITU ch3カウントスタート*/
}
#pragma asm
.SECTION MYVEC,
DATA, LOCATE=H'000090
.ORG H'000090
;IMIA3
.DATA.L
_imia3INT
.DATA.L
_imib3INT
.ORG H'0000A0
;IMIA4
.DATA.L
_imia4INT
.DATA.L
_imib4INT
.SECTION P,CODE,ALIGN=2
;これを忘れてはいけない
#pragma endasm
#pragma
interrupt(imia3INT)/*この名前の関数は割り込みルーチン仕様である*/
/*プログラム中から呼び出してはならない*/
/*IMIA3の割り込み関数*/
void
imia3INT()
{
int *pwPtr;
unsigned short int grb3,gra4,grb4;
ITU4.TIER.BIT.IMIEB=0; /*GRB4コンペアマッチで割込なし*/
ITU4.TIER.BIT.IMIEA=0; /*GRA4コンペアマッチで割込なし*/
ITU3.TIER.BIT.IMIEB=0; /*GRB3コンペアマッチで割込なし*/
pwPtr=&pulseWidth[0+IntCounter];
ITU3.GRB=grb3=(
( (unsigned short int)((*pwPtr)*25) )>>3 )-1; /*GRB3
系統0の値を設定*/
pwPtr+=8;
ITU4.GRA=gra4=( ( (unsigned short int)((*pwPtr)*25) )>>3 )-1; /*GRA4
系統8の値を設定*/
pwPtr+=8;
ITU4.GRB=grb4=( ( (unsigned short int)((*pwPtr)*25) )>>3 )-1; /*GRB4
系統16の値を設定*/
if (grb3<gra4)
{
if (gra4<grb4) {
/*ITU4.GRBが最大*/
ITU4.TIER.BIT.IMIEB=1;
/*GRB4コンペアマッチで割込*/
} else {
/*ITU4.GRAが最大*/
ITU4.TIER.BIT.IMIEA=1;
/*GRA4コンペアマッチで割込*/
}
} else
{
if (grb3<grb4) {
/*ITU4.GRBが最大*/
ITU4.TIER.BIT.IMIEB=1;
/*GRB4コンペアマッチで割込*/
} else {
/*ITU3.GRBが最大*/
ITU3.TIER.BIT.IMIEB=1;
/*GRB3コンペアマッチで割込*/
}
}
/*ここで3つの割り込みフラッグをクリアする必要がある*/
ITU3.TSR.BIT.IMFB=0;
/*Clear IMFB3*/
ITU4.TSR.BIT.IMFA=0; /*Clear
IMFA4*/
ITU4.TSR.BIT.IMFB=0; /*Clear
IMFB4*/
/*次のフラッグは自分のもの*/
ITU3.TSR.BIT.IMFA=0; /*Clear IMFA3*/
}
#pragma
interrupt(imib3INT)/*この名前の関数は割り込みルーチン仕様である*/
/*プログラム中から呼び出してはならない*/
/*IMIB3の割り込み関数*/
/*割り込みテーブルはIntTbl.srcに書いてある*/
void
imib3INT()
{
IntCounter++;
IntCounter&=7;
SELECT_PORT.DR.BYTE=portout[IntCounter];
ITU3.TSR.BIT.IMFB=0; /*Clear IMFB3*/
}
#pragma
interrupt(imia4INT)/*この名前の関数は割り込みルーチン仕様である*/
/*プログラム中から呼び出してはならない*/
/*IMIA4の割り込み関数*/
/*割り込みテーブルはIntTbl.srcに書いてある*/
void
imia4INT()
{
IntCounter++;
IntCounter&=7;
SELECT_PORT.DR.BYTE=portout[IntCounter];
ITU4.TSR.BIT.IMFA=0; /*Clear IMFA4*/
}
#pragma
interrupt(imib4INT)/*この名前の関数は割り込みルーチン仕様である*/
/*プログラム中から呼び出してはならない*/
/*IMIB4の割り込み関数*/
/*割り込みテーブルはIntTbl.srcに書いてある*/
void
imib4INT()
{
IntCounter++;
IntCounter&=7;
SELECT_PORT.DR.BYTE=portout[IntCounter];
ITU4.TSR.BIT.IMFB=0; /*Clear IMFB4*/
}
main()
{
char ch;
int i;
initSCI1();
/*SCI-ch1の初期化*/
SELECT_PORT.DDR=0xff;
/*P3はすべて出力に設定*/
initMultiPulseGen();
/*multiwidthpulse発生器の初期化*/
startMultiPulse();
/*multiwidthpulse発生器起動*/
while
(1)
{
/*ここでpulseWidth[]の値を変更すれば出力パルス幅が変化する*/
ch=getCharSCI1();
if
('A'<=ch && ch<='X')
{
i=ch-'A';
pulseWidth[i]+=50;
if (2000<pulseWidth[i])
pulseWidth[i]=2000;
} else
if ('a'<=ch && ch<='x')
{
i=ch-'a';
pulseWidth[i]-=50;
if (pulseWidth[i]<1000)
pulseWidth[i]=1000;
} else
if (ch=='0')
{
for (i=0;i<24;i++)
pulseWidth[i]=1500;
} else
if (ch=='1')
{
for (i=0;i<24;i++)
pulseWidth[i]=1000+40*i;
}
}
}