MPLAB X IDE v5.45でPIC32MM0064GPL028用の新規プロジェクトを作成

環境のインストールについては以下の記事に書いた。
MPLAB X IDE 5.45 をインストールする。

以下のいずれかでMPLAB X IDEを起動する。

初めて起動するといろいろな窓が開いた状態だが、混乱の元なのでとにかく全部閉じる。



使用するプログラマをPCのUSBにつなぐ。
Toolのリストに表示されるので選択する。
ここではPICkit3をつないでいる。


Project NameとProject Locationを決める。
Projct Folderは「Project Name + .X」という名前で自動的に作成される。

以下のようにPICkit3の電源設定をしておく。




ゼロからスタートしてPIC32MM0064GPL028でLチカするまでの全過程(開発環境のインストールやパーツ購入も含む)のまとめ

この記事には新しい内容は含まれていないので、このサイトに散在している関連記事を自分で追える方には無用の記事だ。
まったく何も無いところから始めて、開発環境のダウンロード、インストールや秋月での必要パーツの購入から「PIC32MM0064GPL028でLチカする」までの全過程の関連記事を順にリストアップしただけの記事だ。

スタート段階で想定している環境は「Windows10のPCからインターネットへ接続できる環境」だ。
PICの開発環境はLinuxやOS Xにも対応しているので同様だと思われるがここでは触れない。

1.開発環境(ソフトウェア)を整える(無料)。
 MPLAB X IDE, XC32 Compiler, Microchip Code Configurator(MCC) の準備
 「MPLAB X IDE 5.45 をインストールする。
2.ハード関連を秋月で購入する(送料込み4780円)。
 PIC32 手始めキット(SNAPあり)
 参考記事
  「PIC32MM0064GPL028 – Lチカ用の回路の準備(DIP編) –
  記事後半「追記」以降
3.ブレッドボード上にPICの回路を準備する。
 「PIC32MM0064GPL028 – Lチカ用の回路の準備(DIP編) –
  記事前半部分
4.MPLAB X IDEで新しいプロジェクトを作成する。
 「MPLAB X IDE v5.45でPIC32MM0064GPL028用の新規プロジェクトを作成
5.「PIC32MM0064GPL028 – MPLAB Code Configuratorを使ってTimer1の割り込みでLチカさせる。 –




PIC32MM0064GPL028 + ST7735 でプログラム・メモリに置いた画像を表示させる。- データの準備GIMP編 -

PIC32MM0064GPL028 + ST7735 でプログラム・メモリに置いた画像を表示させる。- データの準備 –」のGIMP用改良覚書き

上の記事の頃はPaintShop Pro(PSP)というソフトを使っていた。
現在はGIMPを使っており、PSPはインストールしてない。
Gimpは使い慣れたPaintShop Proの代替になるか。
GIMPでやったらデータがうまく表示されなかったのでこの記事を書いている。

右がGIMPでの最初、左が改良後。

原因と対策は後で書くとして、まずはGIMPでの操作方法を書く。

128×128ピクセルの正方形にする操作
 範囲選択して

 選択範囲で切り抜き

 キャンパスサイズの変更

  縦横のサイズをそろえて、位置を決めて、リサイズをクリック

 画像の拡大・縮小

  128×128ピクセルに

色数を減らしてカラーパレットを作成
 画像 > モード > インデックス


  「色ディザリング」は「ディザリングしない」の方がきれいかも
あとはBMPとしてエクスポートすれば出来上がり。

Cのデータ・ファイルの作成
以前PSPで使った変換プログラムでやったら、上に載せたように色がおかしくなってしまった。
以前の画像と比較したら、そもそもBMPのファイル・サイズが違っていた。
バイナリ・エディタで見てみる。
下のように、情報ヘッダサイズが異なっていることが分かった。

PSPで作ったファイルは0x28 = 40、GIMPだと0x6C = 108となっている。
前回作った変換プログラムは値決め打ちで40に合わせて処理していたのでうまくなかった。
プログラムを書き直して情報ヘッダサイズを読み込んでその値を反映させるように改良した。
問題なく表示されるようになった。

この1.44インチのカラー液晶に実際に写真を表示させる話は「PIC32MM0064GPL028 + ST7735 でプログラム・メモリに置いた画像を表示させる。 – 表示する –
へ続く。




PIC32MM0064GPL028 + MCC で外部クロックで駆動する。

セラロックとか水晶発振子でなく発振器からのクロックで駆動する。
と思ったら、発振器を持ってなかった。
セラロックと水晶発振子しか持ってなかった。
なので、Arduino Nanoで4MHzを作ってクロックにした。
[crayon-671749703061b816823702/]
上は拾い物のコードで、中身は見てない、いずれまた機会があったら見る。
とりあえず、これだけで11ピンから4MHzのクロックが出る。
これを、当初、SOSCIにつないだのだがうんともすんともいわない。
Secondary Oscillator (SOSC) on the SOSCI and SOSCO pins
って書いてるのに。
でもExternal Clock Input Operationという図でクロックはOSC1につないである。
なので、Nanoの11ピンをPICのOSC1につないだらPICが動き出した。

追記(2020/03/06)
Arduinoのフォルダ内をfindstrで探してみた。
[crayon-6717497030624961115500/]
いっぱい出て来るけど328pがNanoなんだろうということでそこだけ拾う。
[crayon-6717497030626736965136/]
つまり
[crayon-6717497030628549594902/]
これですっきりした。
XCで書くなら、
 TCCR2Abits.WGA21 = 1;
 TCCR2Abits.COM2A0 = 1;
ってこと。




PIC32MM0064GPL028 + MCC で Ceralock で駆動する。

いまさら外付けでセラロックをつけて駆動するってのもあまり意味が無いように思う。
でも、精度とか求めたらそういう場面も出てくるかもしれない。
ということでちょっとやってみた。

PIC32 Family Reference Manual Section 6. Oscillators
を読む。
こう書いてある。

Primary Oscillator(POSC)の設定にしてOSC1とOSC2にセラロックをつなげばいいらしいとわかる。


MCCではOSC2の方が書いてないのだが、データシートでは9ピンと10ピンなので上のようにした。

で、Timer1の割込みで簡単なLチカをやってみたらちゃんと動いた。
試しにセラロックを引っこ抜いてみたらLチカが止まったので、ちゃんとセラロックで動いているんだろう。

System ClockをCLKO/OSC2につなぐ(上の(1))とクロックが出力される(下)。

デューティ比が50%でないのがちょっと不思議だが、周波数はちゃんと合ってる。
REFCLKOも設定すれば(上の(2))ちゃんと分周後のクロックが26ピンに出力される(下)。

MCCとデータシートで表記に統一性が無いような気がずっとしている。
クロックに関しても以下のような感じだ。
前半がMCCの表記で[]の中がデータシートの表記。
FRC Oscillator (8.0 MHz) Clock Source [Internal Fast RC (FRC) oscillator]
Primary Oscillator (3.5 MHz – 25 MHz) Clock Source [Primary Oscillator (SOSC) on the OSC1 and OSC2 pins]
External Clock (2 MHz – 25 MHz) Clock Source [Secondary Oscillator (SOSC) on the SOSCI and SOSCO pins]
LPRC Oscillator (32 kHz) Clock Source [Internal Low-Power RC (LPRC) Oscillator]
PrimaryとSecondaryの違いや意味がわかってないせいなのかな?




PIC32MM0064GPL028で音と電飾シリーズ – ホントに忘れたのでおさらい –

ごちゃごちゃで、きっと1週間で何やってるかわからなくなる、と書いていたら本当に分からなくなった。

一応、以前の状態をおさらいしながら言い訳。
以下のようにタイマー・モジュールを使っていた。

TMR1 : 8kHz(125us周期)のタイマー割り込みでblinksound();を呼ぶ。
    blinksound();
     クリック音のデータを順にCCP1RBに読み込む。
     1通り読み終えたらTMR1を止める。
MCCP1 : 62.5kHz周期、CCP1RBに読み込まれたデータ
     による可変デューティー比のPWMで音を鳴らす。
SCCP2 : 2Hzの周期の割り込みでblink();とblinksoundstart();を呼ぶ。
    blink();
     LEDを点滅する。
    blinksoundstart();
     クリック音データのカウンタを初期化し、TMR1をスタートさせる。
SCCP3 : 8kHzの周期の割り込みで、hornsound1();~hornsound3();
     をフラグに応じて呼ぶ。
    hornsound1();
     1つめの警笛データを順にCCP1RBに読む。
     1通り読み終えたらフラグに加算する。
    hornsound2();
     2つめの警笛データを順にCCP1RBに読む。
     1通り読み終えたらSW押下をチェックする。
     押してなければフラグに加算、押してれば繰り返す。
    hornsound3();
     3つめの警笛データを順にCCP1RBに読む。
     1通り読み終えたらフラグを初期化、SCCP2の割り込みを止める。

直したい点は、音の出力がクリック音と警笛音で共有されていることだった。
そこで、以下の解決策を考えた。
 SCCP2の使い方が贅沢すぎるので16bit×2つにしてSCCP3を空ける。
 で、空いたSCCP3で音を鳴らすことで、音源の重複を解消する。

ところが、SCCP3でPWMをやろうとしたところで不具合が出て止まった。
PIC32MM0064GPL028でMCCPのPWMは動くのにSCCPのPWMが動かなかった件」で解決したのだが、その間に上に書いた経緯をきれいさっぱり忘れてしまったのでこの記事を書いている。

で、現状。
TMR1 : 8kHz(125us周期)のタイマー割り込みでblinksound();を呼ぶ。
    blinksound();
     クリック音のデータを順にCCP1RBに読み込む。
     1通り読み終えたらTMR1を止める。
MCCP1 : 62.5kHz周期、CCP1RBに読み込まれたデータ
     による可変デューティー比のPWMで音を鳴らす。
SCCP2
 Primary : 2Hzの周期の割り込みでblink();とblinksoundstart();を呼ぶ。
    blink();
     LEDを点滅する。
    blinksoundstart();
     クリック音データのカウンタを初期化し、TMR1をスタートさせる。
 Secondary : 8kHzの周期の割り込みで、hornsound1();~hornsound3();
     をフラグに応じて呼ぶ。
    hornsound1();
     1つめの警笛データを順にCCP1RBに読む。
     1通り読み終えたらフラグに加算する。
    hornsound2();
     2つめの警笛データを順にCCP1RBに読む。
     1通り読み終えたらSW押下をチェックする。
     押してなければフラグに加算、押してれば繰り返す。
    hornsound3();
     3つめの警笛データを順にCCP1RBに読む。
     1通り読み終えたらフラグを初期化、SCCP2の割り込みを止める。
SCCP3 : 未使用

とりあえず同じ機能を維持したままSCCP3が空いた。
そもそも、2Hz周期の割り込み発生に32bitのタイマー使うとかだったから…。

追記
結局、SCCP3を別のスピーカーに割り当てて、警笛と点滅音を別々に鳴らすようにして完成。




PIC32MM0064GPL028でMCCPのPWMは動くのにSCCPのPWMが動かなかった件

MPLAB X IDE v5.10
XC32 v2.15
MCC v3.75
この記事の内容は、MCCの不具合による問題のようなので、MCCのバージョンが上がれば解決されると思う。
そもそもデータシートをちゃんと読む人には全く関係の無い話。

PIC32MM0064GPL028でMCCPのPWMで音を鳴らしたりして遊んでいた。
PIC32MM0064GPL028にスピーカーをつないで音声を鳴らす。
PIC32MM0064GPL028で左右ウインカー、ハザード、点滅音を実装してみる。
PIC32MM0064GPL028で音と電飾シリーズ – ホーンの音も追加 –
だんだん手が込んできて、SCCPでもPWMを使って音を鳴らそうとしたら全く何も出力されない。
MCCPと同じように設定しているのにだ。

SCCP2の例で先に解決策を書く。
 MCCがOCAENをDisabledにしてしまっているのでそこを変更する。
 方法1:sccp2_compare.c の void SCCP2_COMPARE_Initialize (void){} の最後に
     CCP2CON2bits.OCAEN = 1;
     を追加する。

 方法2:MCCのRegistersで直接変更する。

方法2の方が楽だ。

MCCP1とSCCP2を両方動かすとMCCP1だけ信号が出る。
SCCP2もタイマー割り込みにしてコールバックの中でLチカするとちゃんとLチカする。

散々捜し歩いても解決策が見つからなかった。
データシートを丹念に読むばもしかしたら気づいたかも知れないが、MCCどっぷりなのでそこまでちゃんと読む気が無くなっている。
結局、MicrochipのForumで質問したらすぐに教えてくれた。
あわてて、渋々データシートを読むと以下のようになっている。

MCCP1の場合はCCP1CON2のOCAEN~OCFENが出力ピンのOCM1A~OCM1Fに対応して出力するかどうかを決めている。
SCCP2の場合はCCP2CON2のOCAENが出力ピンのOCM2に出力するかどうかを決めている。
SCCPではOCBEN~OCFENは使わない。

なのに、MCCの吐き出すコードではSCCPに関してこのレジスタがDisabledに設定されてしまっている。
そのためピンに信号が出力されなかった。




PIC32MM0064GPL028のSCCPで16bitのタイマーを2つ使う。

PIC32MM0064GPL028のSCCPやMCCPは使い方がほとんど分かっていない。
今回はSCCPのタイマーを16bit×2のモードにして使ってみた。

ぴったりにはできないのだが、8kHzと2Hzを作ってみたい。
これは、最近やっている音の再生用の8KHzと模型のウインカーの点滅用の2Hzだ。


SYSCLKは16MHzにしてある。
(1)Timer Modeを16bitにする。
 2つ別々に同時カウントする16bitのタイマーとして使える。
(2)Prescalerを1:16とした。
 これは普通のタイマーと同じ。
(3)Secondary Timer Periodを0x7D(125)とした。
 このタイマーは単純にこの数を数えるという用途でしか使えない。
 16000000 ÷ 16 ÷ 125 = 8000
 となって8kHzの割り込みを発生させることになる。
(4)Primary Timer Periodを0xFFFFとした。
 このタイマーには下の欄のOutput Propertiesに設定する機能を付加できる。
 もちろん、単純なカウント用にも使える。
 実はこの付加機能の設定がまだよくわかっていないのだ。
(5)Event Durationを7th Time Base Period Matchとする。
 こうすると、
 16000000 ÷ 16 ÷ 65535 ÷ 7 = 2.18
 となり、割り込みの発生周期を指定周期分さらに遅くすることができる。
 このEvent Durationは1~16倍まで選択できる。
 これで、計算上少し端数が出るにしても、ほぼ2Hzを作ることができた。

ちなみに、タイマー割り込みで実行させたい処理を書く場所はsccp2_tmr.cの以下の赤線の部分だ。

PrimaryかSecondaryかをよく見て間違えないように書く。
なお、青線は、タイマー割り込みの許可・禁止のフラグを区別するために引いた。
PrimaryがCCT2で、SecondaryがCCP2なのを覚えておく必要がある。




PIC32MM0064GPL028で音と電飾シリーズ - ホーンの音も追加 -

今回から「PIC32MM0064GPL028で音と電飾」シリーズ化いたしました(笑)。
PIC32MM0064GPL028にスピーカーをつないで音声を鳴らす。
PIC32MM0064GPL028で左右ウインカー、ハザード、点滅音を実装してみる。

模型に電飾の話とArduinoのPWMで音という話。
それぞれ別々だとあまり面白くもなかった。
特に電飾の方はただの低レベルLチカなので面白くない。
ただ、両方合わさると結構いろいろ悩み事が増えるし、搭載タイマー総出の様相を呈してくるとちょっと燃える。
現状を動画で示すとこんな感じだ。

自動車保安用の電装品を想定しているので、ウインカー、ハザード、そのカチカチ音、車幅灯ときて、今回はとうとうクラクションの音も鳴らしてみた。
クラクションは長く押し続けたらその間鳴り続けるようにしたい。
この段階ですでにどの機能にどのタイマーをどう割り振っているかもうごちゃごちゃになりそうだ。
1週間放置したら確実に忘れる。
無計画に行き当たりばったりでコーディングしているからだ。

現状の不満点を書いておくと、ホーンの音が軽トラっぽいことと、長く鳴らすと周期的にノイズが入ることだ。
音色は音データを探してくれば済むことなので、ノイズについて考えていくことにする。

中華ロジアナに付属のアナログ端子につないで出ている信号を見てみる。
規則的に信号のない部分がある。
下のように135usほどの無音部分だ。

16MHzで駆動しているので、これはクロックの2000周期分に相当する。
16000000 ÷ ( 1 ÷ 0.000135 ) = 2169
処理が間に合ってないとかいう種類の空白ではないだろう。
そこで、場所を調べてみると、先頭から163ms、そこから87ms、87ms、最後までが119msという感じだった。
実は、1つの音声データを3つに分割してPICに内蔵しており、長く伸ばす場合は2つ目のパートを繰り返すようにプログラムしている。
それぞれの長さが、163ms、87ms、118msなのだ。
ノイズというか空白の入る部分と3つのパートの境目が一致している。
下は、Audacityで真ん中部分の最初と最後の位置をms単位で表示させてみたところ。

250 – 163 = 87ms が真ん中部分の長さになる。
つまり、ノイズというよりはプログラムのミスで変な間が空いてしまっていると考える方がつじつまが合う。
見直したらよくわからない余分な処理が結構あったので、整理したらノイズはほとんど無くなった。




PIC32MM0064GPL028で左右ウインカー、ハザード、点滅音を実装してみる。

某掲示板で模型にLEDの点滅を仕込むのにPICを使う話が出ている。
PIC32MM0064GPL028でいろいろやった集大成のつもりで、表題のことをやってみた。

PIC32MM0064GPL028にスピーカーをつないで音声を鳴らす。
PIC32MM0064GPL028 + MCC でPWMを試してみる。


スイッチを押すたびに、左ウインカーの点滅と点滅音、右ウインカーの点滅と点滅音、ハザードの点滅と点滅音、車幅灯の点灯、消灯を順に繰り返す。

MCCの設定をProject Resourcesの表示順に画像で貼る。
Interrupt Module

Pin Module

System Module

MCCP1
PWMで音を鳴らす。
周期=16MHz÷0x100=62.5KHz、デューティ比はCCP1RBで決める。

SCCP2
ウインカーの点滅間隔を決める。
16MHz÷64÷0x1E848=2Hz

TMR1
音の周波数を変える間隔を決める。
125us=8kHz=音データのサンプリング周波数

コードも貼る。
main.c

sccp2_tmr.c

tmr1.c

main.cは全部だが、他はMCCの出力したコードに追加した部分だけ。

PIC32MM0064GPL028で音と電飾シリーズ – ホーンの音も追加 –」へ続く。