「PIC AVR 工作室」サイトの日記的なブログです。
サイトに挙げなかった他愛ないことを日記的に書き残してます。
PIC AVR 工作室 ブログ



タイマー2の動作の件、昨日の文章ではなんとなく奥歯に
モノが挟まったような書き方をしましたが、もう一度
実験してみて、結果を紙に書き出してみたら、
「何が変なのか」が判りました。

結論を先に言うと、AVRstudioの内部処理で
使用している(であろう)フラグか何かの初期化処理が
上手く動作していないということ。バグでしょう。
AVRstudioは、タイマー1だけでなくタイマー2
にもバグが潜んでいるようです。

どういうことかというと…

タイマー0とタイマー2それぞれにおいて、フェーズ
コレクトPWMを使用してシミュレートをかけると、
ある条件下では全く同じ動作結果が得られます。

が、ある条件では動作内容がタイマー2だけ動作が狂います。
その条件と動作内容を以下に記します。

↓この設定でプログラムを作り、シミュレーションを実施します
・タイマー0と2でフェーズコレクトPWM(モード5)を使用
・OCRxA(TOP値として使用される)に3を設定
・OCRxB(出力が反転するカウンタ値)に2を設定
・COMxBに0b10(カウントアップ時にコンペア
 マッチするとLOW出力、カウントダウン時なら
 HIGH出力)を設定

この設定でタイマー0、タイマー2それぞれでシミュレート
を行うと、1回目は両方とも同じ結果が得られますが、
一旦停止してからもう一度最初からシミュレートを
やり直すと、タイマー0は上記と全く同じ結果が得られる
(あたりまえですが)のに対して、タイマー2では
1回目と異なる結果が得られます。

(OCxBの出力(というか、シミュレーター画面の
 PINxの値)が、1回目は両方とも最初の5カウントの
 間0のままで、6カウント目から1出力になるのですが、
 2回目のシミュレートを実行した時、タイマー2だけは
 1カウント目から3カウント目までも1が出力されます。
 言葉で書くと判り難いですね…すみません。)

カウンタが初期状態のとき(リセット直後)は、コンペアマッチ
してないはずなので、仕様に愚直ならタイマー0の動作が正しい
と思います。
タイマー2も、1回目のシミュレーションでは同じ
結果が得られます。

2回目以降、なぜ動作が異なるのかというと、ここからは
憶測ですが、タイマー2のカウントダウン時のコンペアマッチ
のフラグを初期化しないまま、次のシミュレーションが
開始してしまうということかと思います。
で、リセット直後にもかかわらずコンペアマッチ状態であると
認識されてしまい、出力が1になる…と。

実際AVRstudio自体を再起動すると、1回目はまた
タイマー0と同一になり、2回目からは誤動作します。
つまり、1回目のシミュレーションと2回目以降のシミュレーション
という”条件”によって再現するわけです。

タイマー0に対し、タイマー1やタイマー2は、あとから
追加された機能だろうと思うので、AVRstudio自体の
品質がまだ確保されていないってことなのでしょうかねぇ?

いずれにしても、今の私の開発環境ではこれ以上はどうする
こともできそうにありません。

もしICDを使ってデバッグできるなら、実機にプログラムを
流し込んで動作確認することが出来るんでしょうけど、
私は環境持ってませんし… (AVR ISP mk2しか
持ってません。JTAGICE-mk2は高いし…)

シミュレーターには「バグは付き物」という前提でテストを
するなら、やはりICDの環境は必須なのかもしれません
ねぇ…

ただ、今の私にできるのは、シミュレーターでも信用できる
機能のみを利用するということだけ。
ひとまずは、その範囲内で実現できることをしたいと思います。

もしかして、ICD環境の販促の為に、わざとバグfixを
先延ばしにしているんでしょうかね…?
(意地悪く考えすぎ??)



コメント ( 0 )
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする




気になったので、タイマー0、タイマー1、タイマー2
の各タイマーについて、フェーズコレクトPWMモードだと
どんな動作になるのか、AVRstudioの
シミュレーターで確認してみました。

まずはタイマー0をモード5(フェーズコレクトPWM)で
使用してみました。
さすがにタイマー0は思ったとおりに動作してくれます。
問題なし。

次にタイマー1をモード11で使用してみました。
相変わらず、モード3と同じ動作になってしまいます。
(モード11は0b1011なので、やはり上位2ビットが
 無視されて0b0011=3として処理されているような
 気がします)

そしてタイマー2をモード5で使用してみました。
こちらは、TOP値にOCR2Aがきちんと適用
されています。ただ、カウンタ値=OCR2Bに
なっても思ったように反転しません。
詳説すると、カウンタが上昇中のときは出力がずっと1。
下降の途中(OCR2Bとマッチ)の時に0に
なり、カウンタ=BOTTOMの時に1出力に
戻るという風に見えます。

結構ラフにテストしたので、タイマー2のほうは
もしかしたらちょっと手違いがあるかもしれませんが、
でもやっぱりタイマー2もだめですねぇ。シミュレーター
が仕様どおりに動いていないようです。

シミュレーターだけのバグなのか、それともerattaに
載ってないバグの発覚を恐れ、シミュレーター自体
の仕様を実際のチップにあわせてあるのか…
(考えすぎ?)

どちらにしても、私の脳みそ及び実験器具では手に
負えそうにありません。

シミュレーターの結果が仕様書どおりでなければ、
(信用できなければ)それはひとまず使用できない機能と
判断すべきでしょう。

そもそもMEGA48だけNGなのか、それとも
全チップともダメなのか… うーん、困ったものです。

ひとまずcbi、sbiを使って、1サンプリング
あたり8クロック(2.5MHz)での実現を先行し、
あとで追加仕様として3.33MHz対応なり、
4MHz対応なりを考えるのが良さそうな気がします。

当初、AVRのMEGA48でサクッと完成させ、
その次にdsPICを使って同じ機能のもの(もう少し速いもの)
を造り、さらには今後CPLDを使ってもっともっと
速いものを造ろうと思っているので、ここで立ち止まる
よりは先に進んでからあとで考える方が賢い気がします。


(補足)
この書き込み、及び1つ前の書き込みのテストで使用したAVRstudioのバージョンですが、12/18公開の
SP2を適用済みの最新版を使用しました。




コメント ( 0 )
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする




タイマー1高速PWMをモード15(高速PWMで
TOP値がOCR1Aとする)がAVRstudioの
シミュレータで上手く動作しない件、色々調べてみました。

以下に整理してみます。

まずは、タイマー1だけダメなのかと思って、
タイマー0、タイマー2用にテストプログラムを作って
みました。

まずタイマー0ですが、モード7(同じく高速PWMで
TOP値をOCR0Aに)で動かしてみると、なんと
すんなり動きました。カウント値も出力PINも
想定どおりの動作です。やっぱ、考え方などは
間違えてなかった様子。

そしてタイマー2ですが、これもモード7(高速PWM
でTOP値をOCR2A)で動かしてみると…
タイマーのカウンタ自体はちゃんと0~4で繰り返して
くれるんですが、なぜか出力PINに結果が現れません。
COM2A、COM2Bの設定も間違ってないのに…

ちなみにタイマー1のモード15でシミュレーター
を動かしつづけてその動作をずっーと眺めていると、
TOP値が0x03ff(10ビット幅)のフェーズ
コレクトPWMとして動いているようです。つまり
モード3になっちゃってます。
(WGMの上位2ビットが無視されているのでしょうか?)

実験用のソースプログラムはしらみつぶしに眺めたんですが、
間違えはないようです。どうやらシミュレーターがバグって
いる様子なので検索を掛けてみると…

http://avrwiki.jpn.ph/wiki.cgi?page=AVR%A4%E8%A4%AF%A4%A2%A4%EB%BC%C1%CC%E4(FAQ)#p5
AVRwikiでこのような記述を見つけました。
2行だけなので詳しいことは判りませんが、
やはり「位相基準PWM」(=フェーズコレクトPWM)
になってしまうという記述があります。

多分これはタイマー1を高速PWMで使用した場合に
関する指摘でしょう。
…やっぱりねぇ。


では、ちゃんと動くタイマー0用に回路図を書き換え
られればいいのですが、話はそう簡単には行かないんですよ…

タイマー0のB出力(OC0B)はPD5pinに繋がって
いるんですが、これはSRAM及び74HC4040への
アドレス出力に使っている4本と重なってしまいます。

アドレス指定の4本は、A、B、C、Dいずれかのポートうち、
上位4ビットの連続したPINが空いているものを選ぶ必要が
あります。でなければアドレス指定が1クロックで収まらなく
なるので。
一番都合が良かったのがDポートの上位4ビットと
いうわけです。よってタイマー0だけは使うに使えません。

一方、タイマー1もタイマー2もシミュレーターが
不調です。いちかばちかというか、行き当たりばったりと
いうか、そんな状態でプログラム組んじゃうと、
完成品の動作が正しいのかどうかを検証する術が
なくなってしまいます。
(ちゃんとしたロジアナが手元にあったり、厳密に
 調整されたテスト波形出力装置でもあれば実機で
 検証ができるんでしょうが、持ってませんし。)

というわけで、現実的な答えを考えないとならない岐路に
立たされました。

(1)シミュレーターのバグフィックスを待つ
(2)高速PWMを使わず、cbi、sbi命令を使う
(3)いちかばちか、プログラムを組んでみる
(4)高速PWMを使わないロジックを考える

…(3)は無いだろうなぁ。(1)もずいぶん前から放置
されているみたいだし。ってことは(2)が目下のところ
現実的かという気がします。

あとは(4)ですが、フェーズコレクトPWMを使って
0~2、2~0でカウンタを動かし、カウンタが0の時だけ
(もしくは2の時だけ)出力を反転できれば、6クロックで
動くと思うんですけど(0~3、3~0かな?)。
これだと4MHzはやっぱり無理で、3.33…MHzに
なっちゃいますね。

もうちょっと悩んでみよう…。



コメント ( 0 )
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする




タイマー1のPWMの件、もしかしたらシミュレーター
自体の不具合なのかなぁ?

ここ1年近く、AVRstudioのアップデートを
行ってなかったと思うんですが(gccのアップデート
はしてたんですが)、それが原因???

あとで時間が出来たら、ちょこっと調べてみよう…。

こんなこと言っておいて、単なるプログラムのバグ
だったりしたら恥ずかしいなぁ…



コメント ( 0 )
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする




掲示板にあるとおり、シバ某さんからご指摘頂いた件を
目下検討中です。

回路図の構想どおりにPB2を/WEのストローブ信号
として使えればいいなぁと思っているので、現在その方向で
山根氏の本を読み返しながら、お勉強的な実験をしている
ところです。

シミュレーターを使って、タイマー1を高速PWMモード
のモード15で使用。カウンタの最大値をOCR1A=4に設定。
OCR1Bに3を入れておくことで、カウンタが0~3はHIGH、
カウンタが4の時はLOWという出力が出来るだろうと考えています。

ただ、なぜだかシミュレーターではまだ上手く動作していません…

これを、タイマー0(8ビットのタイマー)を使ってモード7
で実験すると上手く行くんですが、そもそもタイマー0
はOC0B出力がPD5なのでSRAMへのアドレス指定用
ポートとバッティングしてしまいます。PD5はSRAM
アクセス用4ビットアドレスとして必要なので、
これは変えられません。

タイマー1のOC1B出力(=PB2)であれば、
回路図には全く手を加えずに使えるので、なんとか
タイマー1で動かしたいのですが、私の頭がまだ
追いついていないようで、上手く動いていません。

データシートのErattaまで見直してみたのですが、
タイマー1のPWM関連のErattaは無いようですし…。


なぜタイマー1では、OCR1Aとカウンタが
一致してもカウンタが0に戻ってくれなのか?
なぜOCR1Bと一致してもPB2の出力が反転
しないのか?

今のところ私の頭では原因究明できていません。
うーん。こまった…。

タイマー0のモード7(高速PWM)とタイマー1の
モード15(高速PWM)では何か決定的な違いが
あるのでしょうかねぇ?



コメント ( 0 )
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする



« 前ページ