R8C/15、タイマーCでPWM & rmpa_b()関数を試す
1.題名通りに
今度は、タイマーCのコンペアマッチで、PWMを、やってみました。
理屈は、タイマーZの時と、同じです。
コンペア1で、サンプリング周期を決定し、コンペア0に、AD変換で取り込んだ値を代入します。
このAD変換の値を、コンペア0に代入する場所は、今回も、
コンペア1の割り込み関数の所に、記述しました。
rmpa_b()関数について
HEWのコンパイラの、組み込み関数です。
積和を計算します。
Cコンパイラユーザーズマニュアル(nc30uj.pdf)に、記述が、あります。
RMPA
[機 能]
[書 式]
初期値 : init、回数 : count、乗数の格納されている先頭アドレスをそれぞれ p1、p2 とし
て、積和演算を行い結果を返します。
#include <asmmacro.h>
int rmpa_b(long init, int count, char *p1, char *p2);/* 8bit での演算の場合 */
long rmpa_w(long init, int count, int *p1, int *p2); /* 16bit での演算の場合 */
これは、アセンブリ言語の、強力な、積和演算の命令コードを、使っています。
R8C/Tinyシリーズのソフトウエアマニュアル(rjj096002_r8csm.pdf)に、記述が、あります。
RMPA
【構文】
RMPA.size
B , W
【機能】
・A0を被乗数番地、A1を乗数番地、R3を回数とする積和演算を行います。演算は符号付きで行い、結果
はR2R0(R0) *1に格納します。
・演算中にオーバフローするとOフラグが“1”になり、演算を終了します。R2R0(R0) *1には、最後の加
算結果を格納しています。A0、A1、およびR3は不定です。
・命令終了時のA0またはA1の内容は、最後に読み出したデータの次の番地を示します。
・命令実行中に割り込み要求があった場合は、演算の加算終了後(R3の内容が1減算された後)に割り込み
を受け付けます。
.............
30回の積和演算を、行って、どれくらい時間が掛かるのか?
シミュレーションで、測ってみました。
2.タイマーCでPWM
上手くもないプログラムですが、
動作は、確認できました。
まず、タイマーCでPWMを作って、それから、AD変換設定のset_AD8()を作り、
AD変換の結果を、コンペア1の割り込み関数に、記述するだけです。
/***********************************************************************/
/* */
/* FILE :AD_PWM_1.c */
/* DATE :Fri, May 13, 2005 */
/* DESCRIPTION :Main Program */
/* CPU TYPE :Other */
/* */
/* This file is generated by Renesas Project Generator (Ver.4.0). */
/* */
/***********************************************************************/
#include "start.h"
void set_timerC(void);
void set_AD8(void);
void main(void)
{
set_CLK20();
set_LED();
set_timerC();
set_AD8();
asm("FSET I"); //割り込み許可
tcc00 = 1; //タイマCカウント制御開始ビットのセット
adst=1; //AD変換開始
while(1);
}
void set_timerC(void)
{
pd3_4=1; //P3_4をタイマCの出力に設定
p3_4=1; //初期値=1
tcc00=0;
tcc01=0; //タイマCカウントソース f1
tcc02=0;
tcc12=1; //タイマC カウンタリロード選択ビット 1
tcc13=1; //コンペア0選択ビット アウトプット=1
tcc14=0; //コンペア0一致で出力を L に設定
tcc15=1;
tcc16=1; //コンペア1一致で出力を H にする
tcc17=1;
tcout4=1; //コンペア出力を CMP1_1に設定
tm0=0; //カウンタ 初期値
tm1=256;
ilvl0_cmp1ic =1; // コンペア1割り込み優先レベル(レベル1)
ir_cmp1ic = 0; // コンペア1割り込み要求フラグクリア
}
void set_AD8(void)
{
pd1_0 =0; //p1_0 読み出しモード AN8
p1_0 =0; //初期値=0
ch2 =1; //AN8
ch1 =0;
ch0 =0;
md =0; //単発モード
adgsel0 =1; //Port1グループ選択
adcap =0; //ADSTビットで開始
cks0 =1; //f2を選択 cks1=0にする
bits =0; //8bit
cks1 =0;
vcut =1; //Vref接続
smp =1; //サンプルホールドあり
}
#pragma interrupt comp1_int (vect=16)
void comp1_int(void)
{
tm0 =ad; //タイマC TM1カウンタの値をセット
adst=1;
}
AD変換入力に、2KHzのcos波形を入力しました。
出力結果
1次ローパスフィルタは、10kΩ、4400pFの組み合わせです。
3.rmpa_b()関数を試す
HEWは、シミュレーションモードにて、新規作成します。
シミュレートモードにすると
HEWの右側の方のボタンに、トレースポイント設定ボタンが、出てきます。
これを、クリックして、以下のように、設定します。
トレースというボタンを押しておきます。トレースウィンドが開きます。
そして、メインウィンドウで、ブレークポイントを設定し、ランすると
トレースウィンドは、変化します。
、
時計のボタンを操作すると、ブレークポイントからの相対時間が、表示されます。
つまり、30回の積和計算で、
準備も入れて、11μs 900ns 必要と、言うことが解ります。
1/(11μs 900ns)=84KHzと、かなり、優秀ですね。
これなら、PWM出力のための、コンペア1の割り込み関数の中に、入れられそうです。
PWM出力の、サンプリング周波数も、かなり、高いものに、設定できそうですね.....
うーん、マンダム....
ところで、
デバッグのボタンの中で、区間時間測定のボタンが、表示されませぬが...
皆様のHEWでは、如何ですか?
私のは Version 4.00.01.001で、最新だと、思うのですが...
それと、
割り込みの、シミュレートは、どないやるんやろ ?
KD30を、使うんやろか?
.....
H.17.5.18