趣味の電子工作などの記録。時にLinuxへ行ったり、ガジェットに浮気したりするので、なかなかまとまらない。※サイト移転しました(tomono.eleho.net ⇒ tomono.tokyo)
RSS icon
  • PIC32MXの動作周波数を確認してみる

    投稿日 2012年 7月 2日 コメントはありません

    Lチカは動いたものの、結局何MHzで動作しているのかよくわからなかったPIC32MXですが、実際の動作周波数を調べてみます。

    方法はいろいろありますが、知りたいのはプログラムの実行速度なのでデバッガの表示と実際の速度から推定する手段をとってみます。

    まず、ループで時間待ちするプログラムのコードに着目します。

    ソースからは1回の点灯期間/消灯期間の間にfoo()という関数が10万回ループすることがわかります。ループ以外の時間はほとんど無視できると思われるのでループに着目します。

    デバッガでプログラムをいったんスタートしてブレークし、Disassembly Listingを表示しながらアニメーション実行をさせると、

    の赤い四角で囲った部分が「for(i=0;i<index;i++);」のループ内であることがわかります。実際には、最後のbne命令はDelayed Branch命令なので、その次のnopも実行しているはずです。また、ループ内にはlw命令が入っていて、メモリからのリードサイクルが発生することになりますが、頻度は低いのでここではそれが速度の制約にはおそらくならないでしょう。
    となると、1ループで5命令を5clkかけて実行することになります。つまり、foo()関数では時間待ちとして約50万clkサイクルを要することになるわけです。

    一方で、runモードで実際の実行時間を計ってみると、

    H区間/L区間ともに約75msであることがわかりました。ここから計算すると、50万clkサイクルが75msなので、75000000ns/500000=150ns=6.67MHzということになってしまいました。

    どうやらconfigビットの設定がおかしいようですので、調べていくと、#pragma config の設定はMPLAB IDEの「Help」→「Topics」→「Language Tools」→「PIC32MX Config Setting」の中にあることがわかりました。

    そこで、これを参照してConfigの設定を

    と修正したところ、H区間/L区間ともに約15msになりました。計算すると、1サイクルが30ns=33.3MHzということになりました。
    ちなみにFPLLODIV = DIV_1 のままでは暴走してしまいました。まあ、66.6MHzとなるとしかたないでしょう。

    こんどはConfigの設定を

    と修正すると、内部オシレータ(8MHz)が直接SYSCLKとして使用されるはずですが、H区間/L区間はともに約75ms=6.67MHzに戻りました。

    ここまでの結果から考察すると、1ループが5clkで回っているのではなく6clkになっていると考えると辻褄が合うようです。
    (75000000ns/600000=125ns=8MHz、15000000ns/600000= 25ns=40MHz)

    そこで、「Project」→「Build Option」→「main.c」でCategoriesをOptimizationを選択して、最適化を「0」から「s」に変更してみます。

    すると、青の部分をみるとわかるように関数foo()の呼び出し自体が削除されてしまいました。orz・・・
    この状態でリアルタイム実行させてみると、370~380nsでトグルしています。これは125nsの3クロック分、ということなのでしょう。 Configの設定を「FNOSC = FRCPLL」に変更すると70~80nsのトグルになりましたので、こちらも25nsの3クロック分、赤で囲んだ部分のループ(Delayed Branchで実行されるnopを含めて3clk)ということであっていそうです。

    修正したLチカプログラムをアップロードしておきます。

    • ループでLチカ
      100万回ループで150msの待ち時間を作って、0.3秒周期でLEDが点滅します。
      ただし、最適化をかけてしまうと待ち時間そのものがなくなってしまいます。
      <追伸>SYS_FREQの定数定義が間違っていました(直し忘れ)。修正していませんのでご注意を。
    • 割り込みでLチカ
      タイマー割り込みで100ms周期(1秒間に10回) でLEDが点滅します

    いずれもCPUは40MHz動作(SYSCLKは40MHz、PBCLKは20MHz)です。


  • DIPの32bitマイコンをためしてみる

    投稿日 2012年 7月 1日 コメントはありません

    先日、秋月電子のWebサイトを見ていたらPIC32MXのDIP版が載っていました。・・・で、とりあえず買ってきてみました。物はPIC32MX120F032BでMIPS4Kコアの32bitマイコンです。MIPSといえば昔はワークステーションに載っていたようなCPUですが、それがプリンタやプレイステーションなどの機器を経て、とうとうPICマイコンの世界まで降りてきてしまいました。

    で、最初はお約束のLチカです。

    DIPなのでブレッドボードに載せます。

    左に見えているAE-UM232Rは単にUSBから3.3V-50mAの電源を取っているだけです。

    左端の抵抗はMCLRのプルアップ抵抗です。PIC32(PICkit3に依存かもしれませんが)はMCLRのプルアップ抵抗がないとリセットが解除されないようです。8bitのPICではなくても動作するものがほとんどだったので要注意です。

    MPLABを立ち上げて、ポートAのbit0(2pin)に接続した白色LEDを点滅させます。

    LEDチカチカのプログラムですが、さすがに32bitマイコンとなると初期設定が多く、初期設定の部分をゼロから書くのは大変です。(このへんはPIC24も同じですが、PIC24は頑張ればLチカくらいはゼロから書けます)
    なので、サンプルプログラムを探して参考にして動かすことにしました。

    Lチカまでは結構大変なので、役に立つか分かりませんが圧縮したものを置いておきます。

    ループで点滅するものと、割込みで点滅するものの2種類です。
    ここで不思議なのは、CONFIGレジスタの設定はサンプルプログラムから持ってきた(その前に自分で書いたものもあったのですが、結局同じだった)のですが、結果としてSYSCLKが80MHzになるように思われることです。割込み動作のものの結果をみてもSYSCLK=80MHz、PBCLK=40MHz動作に思えます。しかしながら、データシート類では最大動作周波数は40MHzとされています。
    このあたりはもう少し調査してみる必要がありそうです。

    また、8bitのPICであればAPIとか面倒なことを考えずにデータシート類を見て直接ポートを叩けば良かったのですが、32bitとなるとMIPSのアドレス空間(ksegとかusegとか)を考えないといけなかったりするので直接叩くのは少し面倒くさそうです。サンプルプログラムからAPI(でいいのかな?)を調べていったりする必要がありそうです。