お世話になってます。
RX210で、8bitのtmr0を5ms周期、tmr1を500us周期でオーバーフロー割り込みとして使っているのですが、SCIの送信割り込みを使ってデータ送信を行うようにするとtmrの周期がずれてしまいます。SCIの送信割り込みは500msに1回5バイト程度のデータをテスト的に送信しています。送信タイミングに同期して周期が遅れているようで、SCIの送信を止めるときっちり
5ms、500us周期で割り込みがかかります。割り込みはレベルはtmr0、1、SCIともにOVIに4を設定しています。tmr0、1を5などSCIよりも高レベルに設定しても改善しませんでした。
他に見るべきところは有りますでしょうか?
もんたさん、こんにちは。NoMaYと申します。
少し質問があります。tmrの周期がずれるとのことですが、どういう風(例えば、最初の1バイトを送信する時に、あるいは最後の1バイトを送信する時に、とか)に、どの程度ずれるのですか?
また、500ms毎にデータを送信するとのことですが、この500msのタイミングは何で作っていますか? もうひとつタイマを使っている? それともtmr0(もしくはtmr1)を100回(もしくは1000回)カウントしてタイミングを計っているのでしょうか?
あと、SCIの送信割り込みを使ってデータ送信を行っているとのことですので、まず、この500msのタイミングで1バイトを送信して(というか送信バッファに書いて)、以後、送信終了(もしくは送信データエンプティ)割り込みで次の1バイトを、それによる送信割り込みで更に次の1バイトを、と順に送信しているのですよね?(リカルドさんが仰っていたことでは送信割り込みの出番が全く無くて話が合わないような気がしましたので。)
それから、5バイト程度のデータといのは"Hello!"といったような固定データなのでしょうか? それともA/D変換など多少なりとも時間の掛かる何らかの処理をして得られるデータなのでしょうか?
それで、返事を聞く前に推測を書いてしまうのですが、もしずれが数usから数十usというのなら、今までのH8SやR8Cでは、たまたま運良く5ms周期や500us周期の割り込みとSCIの送信割り込みのタイミング重ならなかっただけ、ということはないでしょうか?
NoMaYさん
送信の500msの周期はTMR0の5msの周期を利用して500ms間隔で送信しています。
500ms周期でバッファに5バイトライトしています。
以下の処理が5バイト分(5回)コールされます。
送信データはaaaa\r\nという固定文字です。
int rsPutch(char ch, const char c)
{
struct RingBufferTx *tx_p;
tx_p = &tx[ch]; /* アクセス用ポインタ設定 */
if(tx_p->count == COM_TX_BUF_SIZE){ /* バッファフルの時はエラーで戻る */
return -1;
}
clrpsw_i(); /* 割込禁止 */
tx_p->buffer[tx_p->save++] = c; /* 1バイトデータのバッファ読み込み */
if(tx_p->save >= COM_TX_BUF_SIZE) /* リングバッファ最大 */
tx_p->save = 0; /* 最初に戻す */
getCountTx(tx_p); /* バッファデータ算出 */
intTxEnable(ch, 1); /* 送信割り込み許可 */
setpsw_i(); /* 割込許可 */
return 0;
以下はtmr0の5ms周期の波形ですが
ずれは結構大きくて遅れるときは10msとかになっている感じです。
送信割り込みが連発しているため、タイマ割り込みが 途中で割り込めない状態が発生しているように見えます。 送信割り込み処理中とタイマ割り込み処理中にどこかの ポートをHにしてモニタしてみると、全体像が見えると思います。 送信割り込みの内容ですが、TDRに書き込んで送信してから TENDを待つ構造になっているのは、待ち時間が長くてもったいないです。 送信データエンプティ割り込み(TXI)を使っているなら、 その時点でTDRは空いているため、TDRに書き込むだけで良く 送信割り込み間の空き時間を長くする事ができ、 タイマが割り込みやすくなるはずです。 H8SよりRXの方が処理速度が速くなったため、タイマ割り込みが 割り込みにくくなってしまったのが原因ではないかと思っているの ですが、同一優先度の場合、ベクタ番号が小さい方が優先度が高いはずで、 CMT,TMRの方がSCIよりも優先度が高く、なぜタイマが割り込めないのかが 疑問として残っています。
int rsPutch(char ch, const char c) { struct RingBufferTx *tx_p; tx_p = &tx[ch]; /* アクセス用ポインタ設定 */ if(tx_p->count == COM_TX_BUF_SIZE){ /* バッファフルの時はエラーで戻る */ return -1; } clrpsw_i(); /* 割込禁止 */ tx_p->buffer[tx_p->save++] = c; /* 1バイトデータのバッファ読み込み */ if(tx_p->save >= COM_TX_BUF_SIZE) /* リングバッファ最大 */ tx_p->save = 0; /* 最初に戻す */ getCountTx(tx_p); /* バッファデータ算出 */ intTxEnable(ch, 1); /* 送信割り込み許可 */ setpsw_i(); /* 割込許可 */ return 0; }
タイミングを重視するならば、割り込みの禁止/許可をしないで済む方法を考えるべきでは?
これでオーバーフロー割り込みを使って割り込み処理の中で TCNT カウンタの初期化を行ってたんであれば、そりゃ割り込み周期はどん〃ずれてきますよ。