初心者です。はじめてタイマーを使ってみました。
2つのLEDを1秒ごとに交互にLチカをさせたかったのですが同時に点滅してしまいます。
質問①
どう記述すれば交互に点滅しますか?
質問②
オシロで測定すると1,060sで60msecほどずれがあります。
タイマーとはこういうものなのですか?
それともCの記述の仕方、または周期の計算がおかしいのでしょうか?
クロック:4MHz
プリスケール:256
質問③
1秒点灯2秒消灯などもひとつのタイマーでできるのでしょうか?
どう記述すればいいのでしょうか?
よろしくおねがいします。
tmr0について
Re: tmr0について
PORTAbits.RA1とPORTAbits.RA0を最初に別の値(例えば1と0)で初期化しておけば、両方とも反転するプログラムなので「交互に点滅」になると思います。ぱおぱお さんが書きました:質問①
どう記述すれば交互に点滅しますか?
(1÷(4MHz÷4(何クロックで1回タイマーが動くか)))×256(プリスケール)×256(タイマーの最大値+1)×16(ソフトウェアでの分周) = 1.048576秒ぱおぱお さんが書きました:質問②
オシロで測定すると1,060sで60msecほどずれがあります。
タイマーとはこういうものなのですか?
それともCの記述の仕方、または周期の計算がおかしいのでしょうか?
クロック:4MHz
プリスケール:256
となるので、こういうものでしょう。
試していませんが、1,000,000÷(256×16)=244.140625なので、
割り込み処理にTMR0に(256-244=)12を加える処理を追加すると、ぴったりにはならないが改善するかもしれません。
ぴったりにするには、クロック周波数と分周比を工夫します。
例えば変数stateを用意して0で初期化し、1秒ごとにぱおぱお さんが書きました:質問③
1秒点灯2秒消灯などもひとつのタイマーでできるのでしょうか?
どう記述すればいいのでしょうか?
stateが0 → stateを1に、点灯
stateが1 → stateを2に、消灯
stateが2 → stateを0に、消灯
のようにすればできると思います。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: tmr0について
片方のLEDを反転させればいいわけですから、以下のコードでも可能でしょう。ぱおぱお さんが書きました: 質問①
どう記述すれば交互に点滅しますか?
タイマそのものの精度はどうなんでしょう?ぱおぱお さんが書きました: 質問②
オシロで測定すると1,060sで60msecほどずれがあります。
タイマーとはこういうものなのですか?
1,060sで60msecなら57ppmになります。温度補償のない水晶ならそのくらいはあり得ます。
まあ、みけCAT さんが書いている分周比のせいである可能性のほうがおおきいは思いますが。
Re: tmr0について
例えば、5.1200MHzの水晶の1024クロック(4(クロックに1回インクリメント)×256(回インクリメントされるごとに割り込み))ごとの割り込みは0.2ms間隔になるので、みけCAT さんが書きました:ぴったりにするには、クロック周波数と分周比を工夫します。
この割り込み5000回ごとに1回処理をすると、(水晶の誤差や処理にかかる時間を無視すれば)ちょうど1sごとの処理になります。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: tmr0について
(1÷(4MHz÷4(何クロックで1回タイマーが動くか)))×256(プリスケール)×256(タイマーの最大値+1)×16(ソフトウェアでの分周) = 1.048576秒ぱおぱお さんが書きました:質問②
オシロで測定すると1,060sで60msecほどずれがあります。
タイマーとはこういうものなのですか?
それともCの記述の仕方、または周期の計算がおかしいのでしょうか?
クロック:4MHz
プリスケール:256
となるので、こういうものでしょう。
試していませんが、1,000,000÷(256×16)=244.140625なので、
割り込み処理にTMR0に(256-244=)12を加える処理を追加すると、ぴったりにはならないが改善するかもしれません。
ぴったりにするには、クロック周波数と分周比を工夫します。
クロック周波数の工夫?の仕方がわからなかったので
プリスケールを16、分周を245にして誤差を少なくする方法にしてみました。
例えば変数stateを用意して0で初期化し、1秒ごとにぱおぱお さんが書きました:質問③
1秒点灯2秒消灯などもひとつのタイマーでできるのでしょうか?
どう記述すればいいのでしょうか?
stateが0 → stateを1に、点灯
stateが1 → stateを2に、消灯
stateが2 → stateを0に、消灯
のようにすればできると思います。[/quote]
実現(記述)できるかはわかりませんがイメージはわかりました。
挑戦してみます。ありがとうございます。
Re: tmr0について
連投で申し訳ありません。みけCAT さんが書きました:(1÷(4MHz÷4(何クロックで1回タイマーが動くか)))×256(プリスケール)×256(タイマーの最大値+1)×16(ソフトウェアでの分周) = 1.048576秒ぱおぱお さんが書きました:質問②
オシロで測定すると1,060sで60msecほどずれがあります。
タイマーとはこういうものなのですか?
それともCの記述の仕方、または周期の計算がおかしいのでしょうか?
クロック:4MHz
プリスケール:256
となるので、こういうものでしょう。
試していませんが、1,000,000÷(256×16)=244.140625なので、
割り込み処理にTMR0に(256-244=)12を加える処理を追加すると、ぴったりにはならないが改善するかもしれません。
ぴったりにするには、クロック周波数と分周比を工夫します。
TMR0に12を加えるとは直接
TMR0 = 0x0C;
とすればいいのでしょうか?
Re: tmr0について
加えるとは加えるであり、TMR0 += 0x0C;のことです。ぱおぱお さんが書きました:TMR0に12を加えるとは直接
TMR0 = 0x0C;
とすればいいのでしょうか?
関数呼び出しや条件分岐などの処理の分クロックが進んでいるので、足したほうがいいと考えました。
もっとも、プリスケールが256なので、256命令は使わないので代入でもいいのかもしれませんが。
※試していないので完全に間違っているかもしれません
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: tmr0について
なるほどです。みけCAT さんが書きました:加えるとは加えるであり、TMR0 += 0x0C;のことです。ぱおぱお さんが書きました:TMR0に12を加えるとは直接
TMR0 = 0x0C;
とすればいいのでしょうか?
関数呼び出しや条件分岐などの処理の分クロックが進んでいるので、足したほうがいいと考えました。
もっとも、プリスケールが256なので、256命令は使わないので代入でもいいのかもしれませんが。
※試していないので完全に間違っているかもしれません
ちなみにTMRが動いてるかどうかの確認方法はありますか?
いろいろ触ってたら分周などを変えてもなんの変化もしなくなってしまいました。
Re: tmr0について
扱っているマイコン(?)がわかりませんが、ぱおぱお さんが書きました:ちなみにTMRが動いてるかどうかの確認方法はありますか?
TMR0がレジスタとして実装されていて、各レジスタの値が確認できるシミュレータが利用できる機種および環境であれば、シミュレータを利用するのが一つの確認方法でしょう。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: tmr0について
MPLAB Xのシミュレータでちゃんと動作していることが確認できました。みけCAT さんが書きました:扱っているマイコン(?)がわかりませんが、ぱおぱお さんが書きました:ちなみにTMRが動いてるかどうかの確認方法はありますか?
TMR0がレジスタとして実装されていて、各レジスタの値が確認できるシミュレータが利用できる機種および環境であれば、シミュレータを利用するのが一つの確認方法でしょう。
さらにTMR0に12を加えたら誤差がなくなりました。
みけCATさんいつもありがとうございます。