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



タイマー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でシェアする