積極的にメモっていく姿勢

題名詐欺。更新頻度の低さが売り。

MPLAB X (XC8) + PIC16F84A でサイモン作った - 技術編

tomio2480.hatenablog.com

前の記事の技術的な部分をふざけないで書きます.
ハードウェアからソフトウェアまで,順を追って書いたつもりです.

LED の見た目が一緒でも違うものかもよ

今回使用したLED,赤が2つありますが別物でした.
それに気づかず片方だけ点灯させてみて,抵抗を決めたので大変な目にあいました.
 
片方は 3.3kΩ でいい感じ,もう片方は 300Ω でいい感じです.
まさか,LEDで 3.3kΩ なんてつなぐ日が来るとは思いもしませんでしたが,
最初テストした方が 3.3k でちょうどよかったので,同じ抵抗を付けてはまりました.
 
最初は暗く点灯したのではんだを疑い,ちゃんと付けなおすも治らず.
次に,ソケットを疑い,ケーブルで電源とLED回路をつなげるも明るくならず.
抵抗で電圧が落ちすぎ?と思い,全部の電圧を測るも変なところは無し.
 
最終手段で LED がイカレていると思い,見た目の同じ LED に交換するも,
残念ながら同じく暗いまま.
 
結局,LED が別物なので違う抵抗をつけようということに......
これで結構な時間を費やしてしまったので,注意しましょう.

PICkit 3 を MPLAB X で使うなら,事前にファームウェアのアップデートが必要

MPLAB X を起動して,PICkit 3 をつなげて,OS には認識された.
が,MPLAB X のコンソールには,永遠に「connecting ...」と出ていて話にならない.
connecting... という文字列が嫌いになってしまいそうだ.
 
全く認識がされないし,PICkit 3 のSTATUS ランプがそもそも点かない
しかも,自動アップデート機能が働いてくれないらしい.
ファームウェアが古すぎて MPLAB X は何もしてくれないらしい.
 
MPLAB v8.92(X の前の最新版)をインストールして,自動アップデートをさせよ.
とのことだったので,インストールするも,始まらずキレかける
 
どうすんだよ!と MPLAB を起動した状態で USB を抜き差ししたら,
アップデートしますか?みたいなウィンドウ出てきて,勝った.
 
その後,MPLAB X を再起動したら無事つかえました.
 
公式ページに質問が載っていたけど,それしかない.慈悲がない.
( ■PICkit™ 3 Debug Express の質問 Q.13 )

参考

PGC / PGD ってどのポート?

自分の学の無さに泣きながら,Google 先生に聞きました.
さすが,16F84A ですね.みんな使ってるから,簡単にでてきました.

結局,RB7 = PGD,RB6 = PGC ということのようです.
どこを見ればよかったんだろう......
 
自分はブレッドボード上に書き込み用の回路を作っておいて使いました.
Bitbucket に上げた,回路図へのリンクも一応載せておきます. (fritzing を見ると PGD と PGC 書いてあるじゃんか......)

https://bitbucket.org/tomio2480/simon_electronic/src/ebf1522674bd92c249cda04e63e19947cbe71d45/PICkit_connection.png

 
参考

レジスタの設定どうやればいいんだよ

HI-TECH コンパイラの時と同じようにも書けるけど,
個人的には新しい書き方のほうが,一発で何したいかわかるので好きです.
 
ひとつずつ設定が見えるので,他の人が見てもよい感じです.

C:\Program Files (x86)\Microchip\xc8\v1.35\include

にあるヘッダファイルとデータシートを行ったり来たり,
知識がなくてもこれで何とかなりました.
(実際は,確認段階になると Google 先生に頼りながらでしたが......)
 
そして日本語版のデータシートの存在を,これを書きながら知ってしまった......
ずっと頑張って英語読んでたんだけど,まぁ勉強になったので......
 
参考

メモリ使用量を見ながらコーディングできるよ

MPLAB X の便利なところ.前の MPLAB に比べて非常に良くなった気がします.
自分のツイートに出ている画像は,エディタ部分の左下に表示させているもです.
 
参考

とにかく贅沢な仕様はメモリを殺す

せっかくゲームだし,音とかも綺麗に鳴らしたろ! → 大破
関数とかきれいに分けておいたほうが,後で改造できるね! → 大破
なるべく変数は使い分けたほうが,わかりやすいね! → 大破
 
という具合である.やりたいことは減らしていこう.
さもなくば,可読性や機能を犠牲にするほかなくなる.
 
正直,自分が勉強不足な感じなので,
もっとちゃんと作れさえすれば色々できたとも思う.

参考

__delay_*s() について

MikroC のほうでは,結構メモリを持って行ってしまうらしい.
XC8 ではマクロなので変数が使えない.不便だからループを書くと容量を食う.
アセンブリを書きましょう!という話に行くが,ジェネレータがあるという.
今回はそこまで切り詰められなかったけど,これからお世話になるかも.

参考

トークン連結演算子を使おうと変数は無理

マクロなので当たり前なんだけど,どうしても一度はやってしまうよね.

#define     LED(n)       PORTAbits.RA ## n
#define     SW(n)        PORTBbits.RB ## n
~~~
LED(SW(n)) = 0;

みたいな事故ね.

参考

XOR は使いどころを考えよう

// XOR を使って条件分岐
if(i == 100) PORTBbits.RB0 = 1;
if(i ^ 100) PORTBbits.RB0 = 1;

// XOR を使って 0 初期化
i = 0;
i ^= i

この 2 つのコードはプログラムメモリに対して,
逆の効果をもたらしました.
 
使用量は,条件のコードは増加,初期化のコードは減少しました.
下の画像を見てもらえばわかると思います.
どちらも,一か所だけ変えたときのデータです.

 
ちなみに,Facebook で XOR 交換についてはどうか,と訊かれたので,
その結果も載せておきます.
 

// コンパイル環境
// 出力をそのままコピーで申し訳ないですが......

Project Type: Application - Configuration: default
Device
PIC16F84A
 Checksum: 0x9ADF
Compiler Toolchain
XC8 (v1.35) [C:\Program Files (x86)\Microchip\xc8\v1.35\bin]
Production Image: Optimization: +space +asm 
Memory
Usage Symbols disabled. Click to enable Load Symbols.
Data 68 (0x44) bytes
Data Used: 7.4%
Data Used: 5 (0x5) Free: 63 (0x3F)
Program 1024 (0x400) words
Program Used: 2.1%
Program Used: 22 (0x16) Free: 1002 (0x3EA)
Debug Tool
 PICkit3: BUR142551932
Debug Resources
Program BP Used: 0  Free: 0
Data BP: No Support
Data Capture BP: No Support
Unlimited BP (S/W): No Support
// XOR

#include <xc.h>

void main(void) {
    unsigned char a, b;
    
    a = 1;
    b = 2;
    
    a ^= b;
    b ^= a;
    a ^= b;
    
    return;
}

/*
Data Used: 5 (0x5) Free: 63 (0x3F)
Program Used: 22 (0x16) Free: 1002 (0x3EA)
*/
#include <xc.h>

void main(void) {
    unsigned char a, b, temp;
    
    a = 1;
    b = 2;
    
    temp = a;
    a = b;
    b = a;
    
    return;
}
/*
Data Used: 6 (0x6) Free: 62 (0x3E)          // 1 増,temp の分だけ増加
Program Used: 22 (0x16) Free: 1002 (0x3EA)  // 変化なし
*/

 
今回の試験コードでは,メモリ節約に一役かっています.
プログラムメモリの消費が変わらず,データメモリの消費を防げるようです.
(この書き方だと変数が追加で必要になるので,その分しか変わりませんが......)
 
参考

include し忘れて関数使おうとしたとき

srand() とか memset() とかを使おうとしたときに,
ヘッダファイルを include してないと,こんなエラーが出る.

make[2]: *** [dist/default/production/Simon.X.production.hex] Error 1
C:\Program Files (x86)\Microchip\xc8\v1.35\sources\common\rand.c:6: error: (1098) conflicting declarations for variable "_srand" (main.c:50)

参考

rand() がうまく使えてるか不安

正直,ここまでは突き詰めませんでしたが,乱数のパターンがかなり怪しい.
アナログピンがあれば,オープンにして読み込めばいいかなと思っていましたが,
今回のマイコンにはそれがありませんので,rand() でいいやとなりました.
 
ただ,どうも周期が短い気がします.
正直,タイマーもちゃんと使えているか微妙なので,
シード値さえも信憑性が低いので,これからもの課題となりました.
 
参考

MPLAB X から Bitbucket に push する

これは別の記事に分けました.
調べてもあまりそれっぽい記事がないので,自分で書きました.

tomio2480.hatenablog.com