PICKIT3 PIC
VPP/MCLR 1 --- 1 VPP/MCLR
VDD 2 --- 11 VDD (+5V)
VSS (GND) 3 --- 12 VSS (GND)
ICSPDAT 4 --- 40 PB7/ICSPDAT
ICSPCLK 5 --- 39 PB6/ICSPCLK
-- 6
Hi-Tech Cのコンフィグ
プログラムメモリとは別なconfigメモリはPICの動作を設定するヒューズとも言えるものです。
16F887のconfig1のビットの定義は下のようになっています。
Hi-Tech C の config 定義は Program Files\Hi-TECH Software\PICC\9.82\include
の中にPIC型番毎のヘッダーファイルに記載されています。
16F887は
PIC_config
これを
__CONFIG(FOSC_HS & WDTE_OFF & ,,,,,);
のように、マクロで 論理積 & を取ることでconfigを記述することができます。
なお、このヘッダーファイルには
// Register: PORTA
volatile unsigned char PORTA @ 0x005;
// bit and bitfield definitions
volatile bit RA0 @ ((unsigned)&PORTA*8)+0;
volatile bit RA1 @ ((unsigned)&PORTA*8)+1;
volatile bit RA2 @ ((unsigned)&PORTA*8)+2;
volatile bit RA3 @ ((unsigned)&PORTA*8)+3;
volatile bit RA4 @ ((unsigned)&PORTA*8)+4;
volatile bit RA5 @ ((unsigned)&PORTA*8)+5;
volatile bit RA6 @ ((unsigned)&PORTA*8)+6;
volatile bit RA7 @ ((unsigned)&PORTA*8)+7;
、、、、、、
のようにHi-Tech cで使えるポートおよびピット定義もされています。
PIC16Fのクロック
は、次の@/A何れかを選択して使います。
@OSC1/OSC2端子に外部発振(水晶HS、RC等)を接続してconfigで指定
APIC内部の8MHz発振信号INTOSCをOSCCONレジスタで分周率を指定
その仕組みは次の図を見ると解かってきます。
Hi-Tech C のインラインアセンブラ
Cの中に記述するアセンブラ命令は #asm と #endasm で挟み、1命令が1行
例えば、
#asm
nop
movwf
0x00
#endasm
#define ABC \
{
\
#asm \
movwf
0x00 \
nop \
#endasm
\
}
注)行末の\(英キーのバックスラッシュ)は、行を連結して処理
EEPROM データの作成
マクロ __EEPROM_DATA を使いデータは8バイト区切り
__EEPROM_DATA(0x01,0x04,0x08,0x00,0xfc,0xfd,0xfe,0xff);
2進表現は何故かBを後部に付ける(?)
__EEPROM_DATA(
00000000B,
11110000B,
10101010B,
10000000B,
00101100B,
00000000B,
11111111B,
00000000B
);
PIC16F88でLED点滅
PIC16F88は16F887と同じシリーズのコントローラーですが、 18ピンの小型で低価格なコントローラーです。ポートが少ないので欲張った使い方はできませんが、特定の用途には十分でしょう。
同じく、MPLABとHi-Tech c で開発することができます。下はLED点滅の例
PIC16F88 プログラム_
内部クロックを使う場合、configは FOSC_INTOSCIO を使います。
PIC16F88でAD変換
超高速という訳にはいきませんが、PICでもAD変換が可能です。
アナログ値で得られる測定値など各種データを、表示、記録、伝送することが可能となります。
注)上の回路のLCD接続は、本サイトの他のLCD回路の1番ピンと2番ピンの接続が逆になっています。秋月で入手できる台湾製LCDの多くは上のピン配列になっているようです。
下は、Hi-Tech C 用のプログラムです。
PIC_AD.c
このプログラムは、AN_IN の入力電圧(0〜5V)を10ビット値に変換して、その値を10進値(0〜1023)でLCDに表示します。動作テストは、10k程度のボリュームを、Vcc--AN_IN--GND
に接続して確認することができます。変換時間は1ms程度のようです。
PIC16F88のAD変換に関連するレジスタは下記のようになっています。
ADCS の各ビットでAD変換のためのクロック速度を設定
ADFM のビットで値のビットを左右何れに詰めるか
VCFG で測定のための基準電圧をセレクトしています。
変換は adconv() 関数で実行しています。
AD変換は手続きが複雑なので解かり難いのですが、動作実例をもとにアレンジしていく方が解かりやすいと思います。
PICによるADサンプリング速度はせいぜい1k sps程度ですから、これを超えるにはAD変換専用のデバイスを使う必要があるでしょう。
PIC16F88でPWM
PWM(パルス幅変調)はパルスのON/OFF比を変えることで、モーターなどに流れる電流値を変化させる技術です。スイッチング電源の出力電圧の安定化にも使われています。
下図の回路とプログラムは、AN0に入力したアナログ電圧をADRESレジスタにAD変換して読み込み、このデータをPMW機能でパルス幅変調してLEDの明るさを変化させています。
LEDに替え、DCモーターの制御回路にすれば回転速度を連続的に変化させることができます。
PIC_PWM.c
PWM動作
@ タイマーカウンタ TMR2 はシステムクロックの1/4周期で+1される。
A TMR2と、レジスタPR2 の値が一致するとTMR2は0にクリヤされ、
CCP1の出力ピンはHになる。この動作の周期はレジスタPR2にセットする値で決まる。
なお、TMR2がクリヤされる時、レジスタADRES(HとL計10ビット)の値が
CCPR1にコピーされる。
B CCPR1とTMR2の値は常に比較され、一致するとCCP1ピンがLになる。
出力パルスの周期はレジスタPR2にセットする値で決まり、パルスのデュティー比はレジスタADRESにセットする値で決まります。
出力のCCP1ピンへの割り当ては下のようにコンフィグで設定でき、
// CCP1 function on RB0
#define CCPMX_RB0 0xFFFF
// CCP1 function on RB3
#define CCPMX_RB3
デフォルトでRB0ですがRB3にもできます。
PMW制御の利用例としては下のようなサーボがあります。
【秋月電子カタログより】
上のサーボの場合は、B型ボリュームの中央でPMWパルス周期が20msとなるPR2の値を決め、VRを端から端まで回転させた時にパルス幅が0.5ms〜2.4msに変化するADRESの値を探します。
GND、RB0、5V の3本をサーボに接続することで動作させることができます。
PICの割込み
PIC16F88の割り込みに制御に関係するレジスタフラグ類はかなり複雑で、マイクロチップのマニュアルでその関係を確認すると下図のようになっています。(なお、同じPIC16F系でもコントローラーによってフラグレジスタの名称等が異なっているので要注意です)
全ての割り込みの許可不許可を制御するのが GIE であり、
ピン変化、INTピン、タイマ0以外の周辺割り込みを制御するのが PEIE となってます。
割り込み条件は上の論理図を見ると分かってきます。関係がORになっている割り込みは何れかの論理条件を1にすることで割り込みが発生します。AND条件の場合は双方の条件が1になることで 割り込みが発生します。
基本的には末尾の文字の
Eは
1: ENABLE (1で割り込みを可にするレジスタフラグ)
0: NOT ENABLE (0で割り込みを不可にするレジスタフラグ)
F は
1: FLAG (割り込み発生で1になるレジスタフラグ)
0: NOT_FLAG (割り込みを確認したら0にするレジスタフラグ)
という機能を表しています。
割込みの種類によって異なった割込みベクターが用意されているAVRと異なり、PICの割り込みは
static void interrupt int_tm(void)
{
}
のように、interrupt 専用の関数を宣言しますが関数名は自由です。
どんな割込みも同じアドレス(4番地)が呼び出されますから、複数の割り込みをENABLEにした場合、どの要因で割り込みが発生したかを知るためには、割込みが発生してからFLAGで判断する必用があります。
PICの割り込みはなるべくシンプルな使い方にとどめた方が良いでしょう。
メインと割り込み間でやりとりする変数は、スタック領域ではなく固定アドレスのRAM領域に確保されなければならないため、 関数の外で volatile
を宣言します。
割り込みとメインの双方で同じ変数を使う場合に注意しなければならないことは、メインでその変数を操作している瞬間に割り込みが入っても問題が発生しないようにしなければなりません。例えば、変数が複数バイトで処理の途中にオーバーフローを挟むようなことが発生すると予期しない誤動作を招くことになるからです。メイン側で処理の前後に割り込みを禁止するか、メインで操作途中を示すフラグを立てて、この間は、割り込み側で変数操作を禁止する等の処置をする必要があります。
こうした点にミスがあると、コンパイルエラーに上がってこないばかりか、再現性の無いトラブルを引き起こすため、ノイズによる暴走と見分けがつかないなど厄介なことになります。
PIC16F88でタイマー割り込み
タイマー割り込みにも複数の方法がありますが、システムクロックで動作するタイマー0のオーバーフロー割り込みは、一定の時間間隔で繰り返し実行したい処理や、所定時間後に開始したい処理、あるいはマルチタスクのようにメインルーチンの背景で実行する処理に使います。タイマー割り込みの方法自体は単純ですが、その使い方は奥深いものがあります。
ここで使う回路は、上の「PIC16F88でPMW」の回路と同じ回路を使います。
タイマー割り込みプログラム
タイマー0オーバーフロー割り込みは、8ビットタイマー0がオーバーフローすることで発生し、"interrupt" ルーチンが実行されます。この例では、メインでBポートをONして
icnt カウンタに数値をセットすることでカウンタがダウンカウントを開始し、タイムアウトでBポートがOFFされます。