PICにチャレンジ
世の中にマイクロチップはいろいろありますが、安いチップと言ったらPICでしょう。今回手にしたPIC12F615は、秋月電子で1個75円(執筆時点)と、非常に低価格です。
このチップを使って、遊んでみることにします。
遊ぶために必要なものですが、
・MPLAB X IDE
・XC8
・PICkit3
といったところです。
統合開発環境(IDE)とコンパイラはマイクロチップ社のサイトからダウンロードしました。
PICKit3は、マイクロチップ社の純正品ですと6千円程度で販売されていますが、互換機はゼロプレッシャーソケットと接続ケーブル付きでも3千円程度だったりします。
私は人柱覚悟で互換機を入手しました。
そのおかげで、いろいろと苦労しました。
まずはLチカ
何はともあれ、IoTのHello worldともいえるLチカを動かしてみることにします。
C言語のプログラムのソースは、次のようになります。
/* * CNC Power unit * * File: main.c * Author: masato * * Created on 2017/02/05, 8:02 */ // PIC12F615 Configuration Bit Settings // 'C' source line config statements // CONFIG #pragma config FOSC = INTOSCIO // Oscillator Selection bits (INTOSCIO oscillator: I/O function on GP4/OSC2/CLKOUT pin, I/O function on GP5/OSC1/CLKIN) #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register) #pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT enabled) #pragma config MCLRE = OFF // MCLR Pin Function Select bit (MCLR pin function is digital input, MCLR internally tied to VDD) #pragma config CP = OFF // Code Protection bit (Program memory code protection is disabled) #pragma config IOSCFS = 8MHZ // Internal Oscillator Frequency Select (4 MHz) #pragma config BOREN = ON // Brown-out Reset Selection bits (BOR enabled) // #pragma config statements should precede project file includes. // Use project enums instead of #define for ON and OFF. #include <xc.h> void main(void) { // レジスタセット TRISIO = 0b00001000; ANSEL = 0b00000000; IOC = 0b00000000; CMCON0 = 0b00000000; int val = 0; GP0 = 0; GP1 = 0; GP4 = 0; GP5 = 0; while(1){ val ^= 1; GP2 = val; _delay(1000000); } return; }
この状態に落ち着くまでにいろいろと右往左往しました。
まず難関だったのが、各レジスタの設定でした。
どのレジスタにどのような値を設定すればよいのか、手にすることが出来たのは英語で書かれたデータシートだけでした。英語を読み解く力が乏しい私としては、Googleさんの力を借りながらの設定となりました。
CONFIGURATION WORD REGISTER (Configuration Bit)はもとより、TRISIOやANSELといった SPECIAL FUNCTION REGISTERS のうちどれを設定する必要があるのか、またないのか。的確な情報を見つけられませんでした。
仕方なくデータシートを眺めつつ、このレジスタを設定する必要があるのではないかと推測しながらトライアンドエラーで設定をするという情けない状態になってしまいました。
さらに迷走を助長させた原因として、_delay()
関数の引数ですが、マイクロ秒で指定するところをミリ秒で指定するものと勘違いしていたことでした。
LEDが点滅することを期待していたのに点灯してしまいました。ぼんやりと点灯していれば点滅が早すぎて点灯しているように見えるのかなと想像できたのですが、くっきりと点灯していました。そんなこともあって、何かレジスタの設定が間違っていて、点灯しているのではないかと無駄な時間を使ってしまいました。
点滅しない原因究明
こんな簡単なプログラムで間違うところと言ったら、レジスタの設定値ぐらいと考えて、ひとつづつチェックしようと、各GPIOの出力が正しく制御できているか確認するところから始めました。
GP2を含めて全てのGPIOをループの外で0または1にセットして、設定通りに出力されているかテスターを使ってチェックしました。
すると、想定通りの電圧が出力されていることがわかりました。
このことからレジスタの設定は、問題なさそうです。
続いて、GP2をループな中で設定するように変更してみます。
再びテスターでチェックしてみると、先程の半分の電圧しか確認できません。
ここでやっと気が付きました。
電圧が半分ってどういうこと?もしかして、高速で点滅してる?
_delay()
の引数を一けたづつ上げてみました。すると、点滅したのです。
出来た!という喜びより、そんな事かよ!!という情けなさのほうが大きかったことはとても口にできません。
オシロスコープがあればもっと早く解決していたのかもしれません。しかし、この程度の回路でオシロスコープなんて使わない(使えない)でしょ。現にテスターで原因が判明したし。
そのほかの愚痴
Configuration BitはIDEのメニューから、[Window]-[PIC Memory Views]-[Configuration Bits]と進んで開かれたツールで比較的簡単に記述できるようになっていたのですが、当初はその機能を知らずに2進数で指定しようとしてしまいました。
当初、PICkit3互換機でチップを認識できませんでした。壊れることを覚悟して、ボタンを押しながらUSBをつなぐとか、いろいろやっているうちに認識するようになりました。しかし、いまだに時々認識しなくなります。
PICkit3互換機で、USBから給電した際にプログラムを焼くことが出来ませんでした。外部電源で、5Vかけた時は焼けるようになりましたが、3.3Vでは焼けません。互換機のせいでしょうか?