プログラミング初心者です。SH7144でエンコーダのパルス信号をそのまま出力する方法が分かりません。エンコーダ入力=出力だとエンコーダのエッジ検出が追いつきません。位相計数モードでカウントはできるのですが、出力波形をエンコーダのA相エッジカウント数(設定)で"1"を出力したいです。IRQでやるべきか、位相計数モードでうまくできるのかもわかりません。仕様としては、エンコーダから来る信号のA相エッジ数を検出し回数をカウント。あるカウント数になったら出力する。または出力を変える。分かる方教えてください。
「そのまま出力する方法が分かりません。」はマイコンの入力パルス信号をそのままマイコンが出力するで良いでしょうか?入出力ピンが無駄になるので、このようなことはしないと思います。CPUあってのマイコンです。エンコーダのパルス信号を分岐してマイコンと他の回路に入力すれば良いように思います。
「エンコーダ入力=出力だとエンコーダのエッジ検出が追いつきません。」は、エンコーダーの回転数が早くてマイコンがエッジ検出できないということでしょうか?7144だと50MHz以上では動作できなないのでこれ以上の信号は根本的に無理だと思います。また、汎用ポートで読み込んで汎用ポートで出力する場合の遅れが問題とも読み取れます。汎用ポートを読み込んで、汎用ポートから出力を続けて実行する以上のスピードは出せません。
「カウントはできる」と「仕様としては、・・・・」からコンペアマッチで割り込みをかけて汎用ポートをセットするで行けそうな感じもしますが、やはりそれなりの遅延があります。PLDやACシリーズでカウンターとデコーダー回路を作っても数十nSの遅れは発生します。
ありがとうございます。参考になります。
初めてC言語の制御プログラムを書くのと、SH7144の資料も乏しいので、できれば参考になるソースがあるといいのですが。
エンコーダの入力はA相は(PA8)をTCLKCとして設定してあり、B相は(PA9)をTCLKDとして設定しています。
(PA6)TCLKAと(PA7)TCLKBの足は壊れた??ので、入力できません。
特に設定している記述は下記です。
PFC.PACRL1.BIT.PA8MD=1
PFC.PACRL1.BIT.PA9MD=1
MTU2.TMDR.BIT.MD=4;
カウントできるというのは、「MTU2.CNT」を変数に設定してデバッグで表示しています。
よろしくお願いします。
追記、実際にやりたいことはエンコーダ(A相)のパルスエッジを検出し、カウント。ある設定値(変数)がカウントと一致すると出力パルスを出す。
簡単に記載するとこんな感じです。
7144のマニュアル11.4.6 位相計数モードの出だしに、「ただし、TCRのCCLR1、CCLR0 ビット、TIOR、TIER、TGR の機能は有効ですので、インプットキャプチャ/コンペアマッチ機能や割り込み機能は使用することができます。」とありますので、現状の接続のままチャンネル2を位相計数モードで使って、コンペアーマッチ機能の割り込みでポートを設定すれば、目的は達成できると思います。実際に試してみる時間と環境がありません。
確かにルネサスホームページにアプリケーションノートなどは少ないようです。すでに参照されているかもしれませんが、CQ出版TECH I Vol.41 SH-2マイコンで学ぶ組み込み開発入門サポートページにエンコーダー入力や割り込みのサンプルがあります。残念がら、そのものズバリのサンプルは無いようです。SHは比較的シンプルです。ハードウエアマニュアルだけで何とかなると思います。概要やレジスタの説明だけでなく動作説明も読んでください。遅れに関しても動作タイミングで解説されてます。
たびたびありがとうございます。
私自身がC言語での制御プログラミングが初めてで、Whileのループにはまったりしています。
動作確認用LEDを点滅させるために、While(t--)を使って点滅するとエンコーダ入力に不具合があったりして、プログラムの見直しをしています。
CMTで上手くできれば良いのですが、for文とかでチャレンジ中です。
「SH-2マイコンで学ぶ組み込み開発入門」についても購入済みですが、やはり、ずばりというプログラムの記述が無くて悪戦苦闘しています。
SH7144のMTU2、位相計数モードの取込最高周波数ないし、スピードが分かるようでしたら教えてください。
チョコです。
ハードウェア マニュアルの「26.3.6 マルチファンクションタイマパルスユニットタイミング」
には、「タイマクロックパルス幅(位相計数モード)」として2.5(min)tpcycと規定されて
います。周辺モジュールクロックサイクル時間(tpcyc)は25ns(min)となっているので、
位相計数モードでの入力クロックの周期は25ns×2.5×2=125ns(min)となります。
つまり8MHzが最高になります。
ありがとうございます。
初心者で分からないことだらけなんですが。
周辺モジュールのクロックは40MHzが最高速度なのでしょうか?(ハードウェアマニュアルにも記載されていて、気になったのですが。)
12.5MHzの発振子を付けているのですが、×4倍モードは使用できないということでしょうか?
それと、エンコーダと接続し位相計数モード4を使用しているのですが、4逓倍入力というのは内部での計算方法という解釈ですか?
周辺モジュールクロックで4逓倍カウンタ入力を計算しているのであれば、125ns×4=500ns(min)ということになるのですが。
分かるようでしたら回答願います。
> 周辺モジュールのクロックは40MHzが最高速度なのでしょうか?
> 12.5MHzの発振子を付けているのですが、×4倍モードは使用できないということでしょうか?
マニュアルに書いてある通りのはずで、解釈はあっていますよ。
---
> 4逓倍入力というのは内部での計算方法という解釈ですか?
ちょっと質問の意味がよくわからないのですが、12.5MHzの事例を計算してみます。
まず、「周辺モジュールクロックサイクル時間(tpcyc)は25ns(min)」という値が、40MHzの時間表現になっています。
後は、その2.5倍のパルス幅がH,Lの2個で125nsという計算のようなので、
例えば12.5MHzのクロックを使用するとなると、
周辺はx2で25MHz(40ns)となり、MTUのパルス幅は、40ns×2.5×2=200ns (5MHz) になるはずです。
位相計数モードが良くわかっていなくて、4逓倍の位相計数モード1と2逓倍の位相計数モード4があることがやっと理解できたところです。
内部カウンタMTU.CNTの波形を利用し、高速に動作するエンコーダ(50KHz程度で動作する,5500rpmで400P/R)入力に対しての逓倍出力を出したいのですが、なぜかMTU.CNTの波形が飽和(サチる?)ので。
MTU.CNT分解能がどこまであるのか、調べてはいますが。分かるようでしたら教えてください。
MTU.CNTの波形をどのようにして確認しているのか、教えて下さい。できればプログラムソースもしくはアウトラインも知りたいです。確認方法に問題がないかを確認するためです。
波形はオシロスコープでモニタしてます。
ソースですが。エンコーダの部分だけだと下記のようになります。
PD9ピンをオシロスコープで見ています。
TCNTの最下位ビットの変化を波形として見たいというプログラムでしょうか。
提示された部分だけだと、PD9はLのままだと思います。
PD9を更新しているところが他にありませんか?
このソースに関しては、TCNTの最下位ビットをモニタするためのプログラムになってます。
実際に近いソースは下記になります。
TCNTの波形を利用し内部パルスを作り、桁上がりを利用して逓倍(変数)しています。
PD9は最初に"1"にしています。
うーん。何だか違和感があります。
後に提示されたソースでは、
グローバル変数として、
PD.DR.BIT.B9= 1;
に初期化した後(私は普段このような使い方はしません)、
main関数で
PD.DR.BIT.B9 = EN_cnt;
をした時に、EN_cnt(値0)になったままのように見えます。
TCNTをモニタするとしたら、定期的にTCNTを読み取って、PD9に設定する処理が必要なはずなのですが、そのような処理が見当たらないのが、違和感の元です。
ループするwhile(1)が抜けていました。
//
int EN_cnt; /* 4逓倍入力値 */
int ENC_count; /* 回転カウント値 */
double ENC_countx;
double DSET ; //パルス逓倍数値 デジタル入力
int DSETD;
int DIG1;
PD.DR.BIT.B8= 1; //
PD.DR.BIT.B9= 1; //
PD.DR.BIT.B14= 1; //
PD.DR.BIT.B15= 1; //
void initENC(void)
{
PFC.PACRL1.BIT.PA8MD=1; /*A相(PA8,TCLKC)の定義*/
PFC.PACRL1.BIT.PA9MD=1; /*B相(PA9,TCLKD)の定義*/
PFC.PDIORH.WORD = 0xFFFF; /* PD0-15は出力ポート */
MST.CR2.BIT._MTU=0; /*モジュールスタンバイの解除 */
MTU2.TMDR.BIT.MD=4; /* 位相計数モード1 4逓倍*/
//MTU2.TMDR.BIT.MD=7; /* 位相計数モード4 2逓倍*/
MTU2.TCNT=0; /* カウントクリア 位相計数モード*/
MTU.TSTR.BIT.CST2=1; /*カウント動作スタート */
}
void main(void)
initENC();
extern int EN_cnt;
extern int ENC_count;
while(1)
PD.DR.BIT.B8 = PA.DR.BIT.B8; //
PD.DR.BIT.B9 = EN_cnt; //
PD.DR.BIT.B15 = ENC_count; // LED ON/OFF
EN_cnt = MTU2.TCNT; //エンコーダカウント読込 4逓倍カウント
ENC_count = (EN_cnt/2); //エンコーダの入力 4逓倍カウント÷2
ENC_countx = ENC_count; //
/* パルス逓倍 */
DSETD = ((ENC_countx)/2)*1000*(DSET*2);
DIG1 = ((DSETD/(10000))%10 & 0x0f);
PD.DR.BIT.B14 = DIG1; //逓倍パルス
やっと理解できました。
観測される挙動ですが、TCNTが0xFFFFになる一定時間まではPD9が変化するが、それ以降はPD9がHのままという事は考えられませんか?TCNTがオーバーフローしたら、ふつうは0に戻るような気がしますが、マニュアルを見るとTCNTのクリア要因(TCRのCCLR2-0)の初期状態が、TCNTのクリア禁止となっており、そのあたりが気になります。
観測している波形はずっとパルス出力されています。
"H"のままということはありません。
エンコーダからの入力が停止したら、"H"になりますが。
クリアの設定したほうが良いのでしょうか?
そうすると、何が問題なのか、わからなくなってきました。
「MTU.CNTの波形が飽和(サチる?)ので」
とはどういう状態を言っているのでしょうか?
以前から気にされている、周波数の上限や分解能との関連が、見えないのですが...
MTU.CNTの波形を観測しモーターに接続したエンコーダを回転させ、徐々にモータースピード(=エンコーダのパルススピード)を高速にしていくと、MTU.CNTの最下位波形がある程度の速度まではエンコーダのパルスに追従するのですが、ある程度の速度で飽和?してしまい、MTU.CNTの最下位波形パルス周期が大きくなります。
なぜこのような現象が起きているのか分かれば教えてください。