2. I2C による LCD(AQM0802A) への表示
学習用のフォルダ「C:\PIC_Practice\chap4_2」を作成して下さい。これでは C:ドライブのルートに作成していますが、ご自分で管理できる所ならば、どこでも構いません。このフォルダ「chap4_2」の中に次の5つのファイルを入れて下さい。下のリストの
main.c の範囲をドラッグして選択します、その状態で右クリックしてコピーします。それをメモ帳などのエディタに貼り付けて、名前を付けて保存で名前を
main.c とします。同様に、 SciCommand.c、HardProfile.h、ST7032i_lib.c、ST7032i_lib.h
のそれぞれの範囲をコピーして、それぞれの名前で保存して下さい。ファイルの境目の目印である・・・
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
・・・は、無視して良いです。これは、以降のサンプルでも同様です。基板や Pickit 3 の接続は この図 のようにしておき、電源を入れておいてください。
リスト chap4_2
さて、MPLAB-X-IDE から、前章のプロジェクトの制作を参照しながら、下図のプロジェクト画面となるようにしてください。

パソコンと基板を Pickit 3 と RS232C ケーブルで接続し、基板の電源を入れておいてください。「Make and Program Device Main Project」(下矢印)をクリックし、ファームウェアをダウンロードします。

ダウンロードが完了すると既に動作を開始しています。LCD の一行目に表示されている SN は、Timer1 の割り込み(#int_timer1)
でカウントアップされている SecNum の値です。
さて、LCD の制御に使う I2C を使えるようにするには、次の記述をします。PPS機能を #pin_select を使って PIN 割当をしています。
// I2C のハードウェア動作を指示
#pin_select SCL1OUT = PIN_B6
#pin_select SCL1IN = PIN_B6
#pin_select SDA1OUT = PIN_B4
#pin_select SDA1IN = PIN_B4
#use i2c( MASTER, FAST, I2C1, FORCE_HW )
この記述は、SCL と SDA にディフォールト(PPS) のピンを割り当ています。どの PINにどの機能を割り当てる事ができるかは、16F1619.h
の PIN_SELECT の項目を参照してください。また、 LCD(I2C) の制御コードを使うようにするためにこの後に #include "ST7032i_lib.c"
を実行しています。
main 関数の無限ループでは・・・ while(TRUE)
{
if (SecNum != SecNumS) {
stiLCD_SetCursor(0, 0);
printf(stiLCD_Putc, "SN:%lu", SecNum);
SecNumS = SecNum;
output_toggle(PIN_C2);
}
exe_command(); // Execute RS232C Command
}
・・・と記述し、前章と同様に LED を一秒ごとに点滅させており、同時に SecNum を LCD の一行目に表示しています。同時に exe_command();
を実行し、RS232C のモニターが常時アクティブになっています。LCD のコントラスト調整は、ソフトで行います。AQM0802A と AQM1602Y
では、最適値が異なっています。ST7032i_lib.h の中に次の記述があります。 // コントラスト調整用定数
#define CONTRAST 0x18 // for 3.3V(AQM0802A)
//#define CONTRAST 0x28 // for 3.3V(AQM1602Y)
現在は、AQM0802A が生きており、AQM1602Y はレムにされていますので AQM1602Y を使用されている場合は、レムを入れ替えてください。別に、モニターから
'T5xx' (xxは十進数:0~63) コマンドで変更することができます。
[ COLUMN ]
プロジェクト・ウインドウに、複数のプロジェクトがでています。ここでは、chap4_1 とchap4_2 というようになっています。今、有効なプロジェクトは、プロジェクト名が太字(
chap4_2 )になっています。これを変更したい場合は、マウスのポインタを有効にしたいプロジェクト名( たとえば chap4_1 )の上に持っていって右クリックをします。そうするとコンテキストメニューが開き、その中に「Set as Main Project」という項目が有りますので、それをクリックすると chap4_1 を有効なプロジェクトに切り替えることができます。
3. A/Dを計測しバー(AQM1602Y)で表示する
学習用のフォルダ「C:\PIC_Practice\chap4_3」を作成して下さい。これでは C:ドライブのルートに作成していますが、ご自分で管理できる所ならば、どこでも構いません。このフォルダ「chap4_3」の中に次の5つのファイルを入れて下さい。下のリストの
main.c の範囲をドラッグして選択します、その状態で右クリックしてコピーします。それをメモ帳などのエディタに貼り付けて、名前を付けて保存で名前を
main.c とします。同様に、 SciCommand.c、HardProfile.h、ST7032i_lib.c、ST7032i_lib.h
のそれぞれの範囲をコピーして、それぞれの名前で保存して下さい。LCD は前章の AQM0802A から AQM1602Y に差し替えてください。そして、ターゲット基板と「書込み&ディバッグ基板」を接続し、パソコンとの間を RS232C通信ケーブルと Pickit 3 USBケーブルで接続してください。ターゲットの電源を入れておいてください。
リスト chap4_3
さて、MPLAB-X-IDE から、前章のプロジェクトの制作を参照しながら、下図のプロジェクト画面となるようにしてください。

パソコンと基板を Pickit 3 と RS232C ケーブルで接続し、基板の電源を入れておいてください。「Make and Program Device Main Project」(下矢印)をクリックし、ファームウェアをダウンロードします。

ダウンロードが完了すると既に動作を開始しています。LCD の1行目には A/D-CH7(温度センサの出力) の値を、2行目には A/D-CH8(
VR1の出力) の値を、それぞれ電圧(V) で表示し、その右側に擬似レベルバーで表示しています。
さて、LCD の制御に使う I2C の設定は、前章と全く同じです。
ただ、今回使用するLCDは、16桁・2行(AQM1602Y) です。先のプロジェクトで使った LCD(AQM0802A) を挿したままでも壊れることはありませんが、レベルバーは表示外となりますし、コントラスト設定値の違いでコントラストがまともではないでしょう。双方とも基本的に同じライブラリで動作します。ただ、下記のCONTRASTの定義値だけが違います。どちらの
LCDもコントラストは、コマンドで設定しますが、その最適値にかなりの違いがあります。
ST7032i_lib.h の始めに、その2種の LCDのデフォルト値を記述しています ・・・
// コントラスト調整用定数
//#define CONTRAST 0x18 // for 3.3V(AQM0802A)
#define CONTRAST 0x28 // for 3.3V(AQM1602Y)
・・・ これでは、上の行はレム文にされていて、下の行が生きています。今回のLCDは AQM1602Y であるので下の行を使います。
【 A/Dの設定と読み込み 】
main.c のトップの、デバイスファイル( #include <16F1619.h> ) のすぐ下に ・・・
#device ADC = 10
・・・ と記入し、コンパイラに A/Dの使用を宣言します。
次に main()関数の始めに ・・・
setup_adc_ports(sAN7 | sAN8 | VSS_VDD); // RC3,RC6がアナログ入力
setup_adc(ADC_CLOCK_INTERNAL); // FRC(内蔵発振)
set_tris_c(0b01001001); // Port_C Mode Set
・・・ とします。これで A/Dの7チャンネルと8チャンネルは使えるようになります。
読み込みは ・・・
set_adc_channel(7); //チャネル選択、引数にチャンネル番号を指定
delay_us(15); //アクイジション待ち
fdata = read_adc(); //A/D変換データ10ビット読込み
・・・ とすればできます。
【 A/D値のレベルバー表示 】
sti_all_set_cgram(cgram_levHdt[0]); // 一括登録する(8文字分)
・・・ を実行することにより、LCD の CGRAM領域に、ST7032i_lib.h ファイルに定義している 64バイト(8キャラクタ分)のデータ(
cgram_levHdt[] ) を連続して書き込んでいます。実際に使用しているのは「 |, ||, |||, ||||, |||||」の5つです。後の3つはスペースと同じになっています。この登録している5つのキャラクタを使用してレベルバーを表示しています。フルスケールは
3.3V (黒ベタ8文字) です。使用できるユーザー定義のキャラクタを書き込む CGRAMの領域は、LCDによって異なりますので、仕様書を確かめなければなりません。
AQM1602Y では、8キャラクタが使用できます。ちなみに AQM0802A では、6キャラクタが使用できます。
この定義したキャラクタを使い、表示位置(X,Y)およびA/D値を引数で受け取り、実際にLCDに表示するのは ・・・
void DspLevelHorizontal(int x, int y, float Data) // 水平方向表示の疑似レベルメーター
・・・ という関数です。レベルバーの表示幅は8文字分固定としています。このLCDでは、CGRAMアドレス00〜07に定義している文字は、アドレス08〜0Fでも重複して読み込める事に注意してください。詳細は
AQM1602Y の仕様書を参照してください。
4. HEF (EEPROM代替え)に変数を記憶させる
学習用のフォルダ「C:\PIC_Practice\chap4_4」を作成して下さい。これでは C:ドライブのルートに作成していますが、ご自分で管理できる所ならば、どこでも構いません。このフォルダ「chap4_4」の中に次の6つのファイルを入れて下さい。下のリストの
main.c の範囲をドラッグして選択します、その状態で右クリックしてコピーします。それをメモ帳などのエディタに貼り付けて、名前を付けて保存で名前を
main.c とします。同様に、 SciCommand.c、HardProfile.h、ST7032i_lib.c、ST7032i_lib.h、HEF_Access.c
のそれぞれの範囲をコピーして、それぞれの名前で保存して下さい。前の章と同名であっても、内容が変わっている場合もありますので、このリストから取得してください。そして、ターゲット基板と「書込み&ディバッグ基板」を接続し、パソコンとの間を
RS232C通信ケーブルと Pickit 3 USBケーブルで接続してください。ターゲットの電源を入れておいてください。LCD は AQM1602Y
を使います
リスト chap4_4
さて、MPLAB-X-IDE から、chap4_1のプロジェクトの制作を参照しながら、下図のプロジェクト画面となるようにしてください。

パソコンと基板 を Pickit 3 と RS232C ケーブルで接続し、基板の電源を入れておいてください。「Make and Program
Device Main Project」(下矢印)をクリックし、ファームウェアをダウンロードします。

ダウンロードが完了すると既に動作を開始しています。LCD に HEF (High-Endurance Flash) から読み込んだ 8個のデータが、2行に渡って表示されています。
さて、PIC16F1619 には、EEPROMがありません。私も始めは、困ったものだと思ったのですが、どうやらプログラムフラッシュの一部をその代替に使用することにしているようです。一般的に、メモリの書き換え上限はEEPROMで10万回以上、プログラムフラッシュでは1万回程度となっています。ところがブログラムフラッシュの末端128バイトは
HEF と呼ばれる特殊なフラ ッシュになって、HEF は High-Endurance Flash を意味し、EEPROMと同等の10万回以上の書き換え耐性を持たせているようです。末端の128バイトとは言え、ここはプログラムメモリの一部であることは間違いありませんのでプログラム容量が若干減ることになりますが普通はここまで使うことは無いでしょう。上の表は、
PIC16F1619 のデータシートの一部です。先に、128 バイトと言いましたが、データ 1つは 14bit で構成されているので、128word
と言うべきかも知れません。しかし、14bit には2バイトを入れることができませんので、この 14bit を1 バイトとして扱います。この HEF
の書き込み・読み出しのテストをモニター(RS232C) を使って実行します。
それでは実際にコマンドを使って HEF にデータを書き込み、そしてそれを読み出して見ましょう。
テラタームを起動してください。 コマンド '?+Enter' でメニューが表示されます。
TD |Read HEF
T1 |Write HEF-1
T2 |Write HEF-2
T3 |Write HEF-3
---------------
TS |Valuable -> HEF
TX |Change Valuable
TL |HEF -> Valuable
V |Version
? |Help
これらのコマンドを実行する前に、LCDの表示について先に説明しておきます。ソフトが起動された時に、main()関数のループの前で HEF の読み込みを行い、その結果を
LCD に表示しています(コードを参照)。それ以外に、LCD に表示を実行するのは、モニターコマンドの 'TD' のみです。
読み書きは、1ブロック単位で行われます。ここでは 1ブロックを8ワードとしています。上の写真の LCD の1行目のデータは左から Index
が 7,6,5,4 、2行目のデータは、3, 2,1,0 の値を 16進数で示しています。上のモニター図の右下に、読み書き用バッファ(buf[8])
の位置と Index との関係を示しています。
【コマンド】
'TD' : HEF 読出し・表示(LCD)コマンドで、指定された HEFの場所から 8word読み出して出力します。
'T1' : コードに記入しているデータを 8word書き込みます。何を書いたかをテラタームに出力します。
'T2' : コードに記入している違うデータを 8word書き込みます。何を書いたかをテラタームに出力します。
'T3' : コードに記入している全て '00'を 8word書き込みます。何を書いたかをテラタームに出力します。
以上は、基本的な読み書き確認のテスト用です。コードを読んでいただければ了解できると思います。
'TS' : 変数 TIMS, CALIB, TESの値を HEFに書き込みます。書いたものをテラタームに出力します。
'TX' : 変数 TIMS, CALIB, TESのRAM上の値を初期値とは違う値にし、それをテラタームに出力します。
'TL' : 変数 TIMS, CALIB, TESの値を、HEF に保存されているものを読み出してRAM に上書きします。
そしてそれをテラタームに出力します。
上のモニター図に、詳細なコメントを付けています。左側が基本的な読み書き確認テスト、右側が実際の変数を使った読み書きテストです。モニターコマンドの実行関数である
exe_command()関数のコードと、上図の実行結果を照らし合わせながら解読してください。
CCS-C のヘッダーファイル(16F1619.h) の中に次の定義があります。
void read_program_memory(__ADDRESS__ address, unsigned int8* dataptr, unsigned int16 count);
void write_program_memory(__ADDRESS__ address, unsigned int8* dataptr,
unsigned int16 count);
これらを利用すれば容易にプログラム・メモリにアクセスできます。自分でこれらを書くとなれば、本当はもっと複雑な手順を記述しなければなりません。書き込みには、前もって必要な消去も含まれているようです。
HES_Access.c の始めに、上の2つの関数の引数として使うものを次のように定義しています。
//======== HEF Buffer & etc ========
int16 buf[8]; // HEF Buffer(8 word))
#define TopAdr 0x1FF8 // Access HEF top address(0x1F80-0x1FFF)
#define buff (int8*)buf // as int8 pointer
#define dnum 16 // 8 word
上の関数の「引数の型」に合わせる必要があります。つまり、バイトとしてデータを処理しています。今回は、1ブロック・8word ですが、もっと多く(128以内)を使う場合は、ここの記述を修正します。ただし、メモリマップを強く意識しながら行ってください。
変数の保存と復活に関しては、HEF_Access.c の中に記述しています。
//======== Target Variable ========
int16 TIMS = 1000; // TimerS
float CALIB = -18.5; // Calibration
int8 TES = 15; // TES
//======== HEF programming Adrs ========
// Index(BUF[]) Byte
const int16 eTIMS = 0; //TimerS 2
const int16 eCALIB = 2; //CALIB 4
const int16 eTES = 6; //TES 1
「 Target Variable」は、対象の変数の宣言と初期値を定義しています。ここに、自分が使う HEF に保存したい変数を定義します。ただし、今回は1ブロック・8バイトの
HEFアクセスですので、それを超えないように注意しなければなりません。「HEF programming Adrs」の Indexの数値は、その変数が
buf[ ] のどの位置から始まるかを自分で指定します。レムの Byte の数値は、その変数の所用メモリサイズを byte で書いています。TIMS を、0,1 を使うようにすると、CALIB
は 2,3,4,5 を使い、 TES は 6 を使うというように自分でマップしてください。buf[7] は、今回は使用していません。いずれにしても、お互いの変数のマップ領域が重ならないように注意しましょう。
void SaveField(int16 index, char *pa, int8 sn); // SAVE of domain(RAM->HEF)
void LoadField(int16 index, char *pa, int8 sn); // LOAD of domain(HEF->RAM)
上の2つの関数は、1つの変数の値を buf[ ] に代入したり、buf[ ] から引用したりを実行しています。
void SaveHEF(void); // Write necessary variable to HEF
void LoadHEF(void); // Read necessary variable from HEF
この2つの関数は、いくつかの変数をまとめて HEF に書き込んだり、読み出したりを実行しています。
EEPROM が実装されてなくとも、HEF (High-Endurance Flash) が実装されていれば、困らないことが分かります。今回は 1ブロック 8ワードで3つの変数を格納しました。基板の電源を切って再度、電源を入れた時に、前に保存した値が残っていることを確認(コマンド:'TL')してください。この機能は PIC16F1619 では 128バイトまで使えますので、余程のことが無い限り不足することはないと思います。
5. 温度を測定し LCDに表示する
学習用のフォルダ「C:\PIC_Practice\chap4_5」を作成して下さい。これでは C:ドライブのルートに作成していますが、ご自分で管理できる所ならば、どこでも構いません。このフォルダ「chap4_5」の中に次の6つのファイルを入れて下さい。下のリストの
main.c の範囲をドラッグして選択します、その状態で右クリックしてコピーします。それをメモ帳などのエディタに貼り付けて、名前を付けて保存で名前を
main.c とします。同様に、 SciCommand.c、HardProfile.h、ST7032i_lib.c、ST7032i_lib.h、HEF_Access.c
のそれぞれの範囲をコピーして、それぞれの名前で保存して下さい。前の章と同名であっても、内容が変わっている場合もありますので、このリストから取得してください。そして、ターゲット基板と「書込み&ディバッグ基板」を接続し、パソコンとの間を
RS232C通信ケーブルと Pickit 3 USBケーブルで接続してください。ターゲットの電源を入れておいてください。LCD は AQM1602Y
を使います
リスト chap4_5
さて、MPLAB-X-IDE から、chap4_1のプロジェクトの制作を参照しながら、下図のプロジェクト画面となるようにしてください。

パソコンと基板 を Pickit 3 と RS232C ケーブルで接続し、基板の電源を入れておいてください。「Make and Program
Device Main Project」(下矢印)をクリックし、ファームウェアをダウンロードします。

ダウンロードが完了すると既に動作を開始しています。LCD の2行目に、計測した温度を表示しています。
使用している温度センサーの名称は LM61BIZ です。その仕様書を ここに 置いておきます。センサーの基板上の名称は「S1」です。基板の左上 (VR1の上) にあります。
【 A/Dの設定と読み込み 】
A/Dを使用する設定については、前章を参照してください。main 関数での無限ループは次のようになっています。
while(TRUE)
{
int i;
// A/D チャンネル7 計測 LCD表示
fdata = 0;
for(i=0; i<20; i++) // 20回連続で読み込み、平均を取る
{
set_adc_channel(7); //チャネル7選択(温度センサー設置チャンネル)
delay_us(15); //アクイジション待ち
fdata += read_adc(); //A/D変換データ10ビット読込み(加算していく)
delay_ms(1);
}
fdata = fdata / 20; //平均値を出す
fdata = (fdata * 3300) / 1024 + 0.005; //電圧(mV)へスケール変換
fdata = (fdata / 10) - 60 + CALIB; //温度へ変換(CALIB:補正)
stiLCD_SetCursor(0, 0); //LCD1行目の先頭へ
printf(stiLCD_Putc, "Environmental");
stiLCD_SetCursor(0, 1);
printf(stiLCD_Putc, " Temp.: %2.1f",fdata);
stiLCD_Putc(0x08); printf(stiLCD_Putc, "C "); // '°C'の表示
delay_ms(100);
exe_command(); // Execute RS232C Command
}
20回の読み込みの平均値を出し、それを一旦 mV 単位の電圧値に変換しています。次に、その電圧値を温度へ変換しています。仕様書では、センサーの出力電圧(Vo)は、
Vo(mV) = 10 x T(℃) + 600 と提示されています。Vo が分かれば、温度(T) は、T = (Vo / 10) - 60
で計算できることになります。計算した後、その値を LCD に表示しています(CALIB は補正)。
'°' の文字を・・・
sti_one_set_cgram(cgram_degdt); // '°'の登録
・・・で登録し stiLCD_Putc(0x08); で表示しています。
この温度センサー (LM61BIZ) は、とてもレンジ( -30 〜 85 ℃ ) が広いです。その代り、かなり誤差が大きいです(±2℃、最大±3℃)。しかし仕様書に書かれているように、出力電圧は摂氏温度にリニアに比例(+10mV/℃
)するように、工場で較正されています。それで、今の温度で測定値を較正すれば、誤差をかなり低減させることができると思います。その較正をモニターからのコマンド入力で以下のように行います。

コマンドとして 'TL' と 'Cxx' を追加しています。HEF に登録する変数は、 TIMS, CALIB, TES, IFL ですが、実際に使っているのは、CALIB,
IFL の2つです。HEF に変数を登録する詳細については、前章を参照してください。コマンド:TL で HEF に登録しているこれらの変数の値を確認できます。コマンド:Cxx
で較正するための補正値を指定し HEF に登録します。'xx' は、左の図の入力例のように実数(-1.8) の数値を入力します。この数値は小さいので、入力値の絶対値が5以下でなければ無視します。
また、main() 関数のループの前に・・・
LoadHEF(); // HEFの値の Load
if (IFL != 0) {
// 初めて電源ONの時に補正値を初期化する
IFL = 0; CALIB = 0; SaveHEF();
}
・・・というように変数の初期化が入っています。
初めての起動かどうかを IFL で判断しています。プログラムを書き込んだときは、フラッシュメモリは初期化されており、プログラムが書かれていない領域は、すべて
'FF' が書き込まれているので、IFL の値が 0かそれ以外かで、初回かどうかを判断し、初回であれば、補正値(CALIB) を 0とし IFL
も 0として、HEF に保存します。したがって電源を落としても、次回以降は、保存されている補正値を使用することになります。
なお念のため、補正なし(CALIB=0) の場合の LCD表示温度が基準となる温度計よりも +1.8℃であった場合は、コマンドは 'C-1.8'
として較正値を登録します。
|
6. SMT(信号計測タイマ)によるインターバルタイマー
学習用のフォルダ「C:\PIC_Practice\chap4_6」を作成して下さい。このフォルダ「chap4_6」の中に次の5つのファイルを入れて下さい。下のリストの
main.c の範囲をドラッグして選択します、その状態で右クリックしてコピーします。それをメモ帳などのエディタに貼り付けて、名前を付けて保存で名前を
main.c とします。同様に、 SciCommand.c、HardProfile.h、ST7032i_lib.c、ST7032i_lib.h
のそれぞれの範囲をコピーして、それぞれの名前で保存して下さい。前の章と同名であっても、内容が変わっている場合もありますので、このリストから取得してください。そして、ターゲット基板と「書込み&ディバッグ基板」を接続し、パソコンとの間を
RS232C通信ケーブルと Pickit 3 USBケーブルで接続してください。ターゲットの電源を入れておいてください。LCD は AQM1602Y
を使います
リスト chap4_6
さて、MPLAB-X-IDE から、chap4_1のプロジェクトの制作を参照しながら、下図のプロジェクト画面となるようにしてください。

パソコンと基板 を Pickit 3 と RS232C ケーブルで接続し、基板の電源を入れておいてください。「Make and Program
Device Main Project」(下矢印)をクリックし、ファームウェアをダウンロードします。

ダウンロードが完了すると既に動作を開始しています。インターバルタイマの割り込みでカウントしている SecNum を LCD に表示しています。
SMTの24ビットタイマでカウントしています。フルカウント(0xFFFFFF)は、16,777,215です。しかし、1秒のインターバルを得るのにカウントクロックを32MHzにすると、さすがに
24bitでもオーバーフローするので Fosc を16MHzにして動作させています。もちろん Fosc=32MHzの場合でも、Fosc/4を選択すれば、最長約2秒という長時間のインターバルを生成することもできます。
SMT については「SMT (信号計測タイマ) の使い方」としてリンク先に詳細に解説されています、ありがとうございます。
SMT には、11のモードがあることにご留意ください。これはその内の一番単純な「タイマーモード」になります。
ヘッダーファイル(16F1619.h) の「SMT」という項目を見ると・・・
#define SMT_MODE_WINDOWED_COUNTER 0x0A00
#define SMT_MODE_GATED_COUNTER 0x0900
#define SMT_MODE_COUNTER 0x0800
#define SMT_MODE_CAPTURE 0x0700
#define SMT_MODE_TIME_OF_FLIGHT 0x0600
#define SMT_MODE_GATED_WINDOWED_MEASURE 0x0500
#define SMT_MODE_WINDOWED_MEASURE 0x0400
#define SMT_MODE_HIGH_LOW_TIME_MEASUREMENT 0x0300
#define SMT_MODE_PERIOD_DUTY_CYCLE_ACQ 0x0200
#define SMT_MODE_GATED_TIMER 0x0100
#define SMT_MODE_TIMER 0
・・・という、11のモードが記述されていますので、setup_smt1 にてそのモードを指定します。CCS-C では、このように拡張関数が提供されているのでそれらを利用することで比較的楽に設定できます。リンク先(SMTの使い方) の内容とヘッダーファイルを見比べていると大方の拡張関数の使い方は分かると思います。
// タイマモード、クロック:Fosc、1周期のカウント数を指定(16,000,000 - 1:#define SMT_PERIOD参照)
setup_smt1(SMT_ENABLED | SMT_MODE_TIMER | SMT_CLK_FOSC, SMT_PERIOD);
smt1_start(); //start SMT1
これで、SMT のモードを設定し動作を開始しています。
while(TRUE)
{
if (SecNum != SecNumS) {
stiLCD_SetCursor(0, 1);
printf(stiLCD_Putc, "SecNum:%lu", SecNum);
SecNumS = SecNum;
}
exe_command(); // Execute RS232C Command
}
main()ではこの無限ループで、 SecNum が変化した時のみ LCDの表示を更新しています。
7. ZCD(ゼロクロス検出)による電源周波数の測定
学習用のフォルダ「C:\PIC_Practice\chap4_7」を作成して下さい。このフォルダ「chap4_7」の中に次の5つのファイルを入れて下さい。下のリストの
main.c の範囲をドラッグして選択します、その状態で右クリックしてコピーします。それをメモ帳などのエディタに貼り付けて、名前を付けて保存で名前を
main.c とします。同様に、 SciCommand.c、HardProfile.h、ST7032i_lib.c、ST7032i_lib.h
のそれぞれの範囲をコピーして、それぞれの名前で保存して下さい。前の章と同名であっても、内容が変わっている場合もありますので、このリストから取得してください。そして、ターゲット基板と「書込み&ディバッグ基板」を接続し、パソコンとの間を
RS232C通信ケーブルと Pickit 3 USBケーブルで接続してください。ターゲットの電源を入れておいてください。LCD は AQM1602Y
を使います
リスト chap4_7
さて、MPLAB-X-IDE から、chap4_1のプロジェクトの制作を参照しながら、下図のプロジェクト画面となるようにしてください。

商用AC電源の周波数を計測するテストです。これは、PIC fun様へのリンク「ZCD(ゼロクロス検出)の使い方」に詳しく解説されています、ありがとうございます。それをここでは CCS-C 版に移植したものです。
CN-ACPOW の 1-4 Pin 間に商用AC電源を加えます。参考先では、AC100Vを 330kΩの抵抗を経由して直接PICのピンに接続されています。抵抗値の計算方法などについてはこのリンクでの説明を良く読んでください。
ここのテストでは、トランスを介してAC 8V を加えました。写真の R2 は、AC100Vを加えて良いように参考先と同じ 330KΩを取り付けていますが、それにパラに 30KΩを付けて 27.5KΩとしました。どの電圧を加えてテストするかは、ご自分で決めてくだい。AC100Vを接続した場合は、感電にご注意ください。いずれにしろこの配線をしてAC電源を接続して置かないとテストは始まりません(CN-ACPOW
紫-青の配線)。制限電流を超える低い抵抗を取り付けると PIC を壊しますのでご注意ください。
パソコンと基板 を Pickit 3 と RS232C ケーブルで接続し、基板の電源を入れておいてください。「Make and Program
Device Main Project」(下矢印)をクリックし、ファームウェアをダウンロードします。

ダウンロードが完了すると既に動作を開始しています。表示の仕方は、参考のリンク先と同じで、上の行は、約0.5秒間隔の測定値、下の行は、20回測定の平均値です。main()
の無限ループ内で表示しています。計測値が表示されない、LED が点滅 (電源周波数での点滅ですから、やや薄い点灯に見える) していない場合は、ACの電圧と抵抗(R2)
の値の関係が合っていませんのでチェックしてください。
設定について説明いたします。
#FUSES ECH, PLLEN, NOWDT, PUT, NOBROWNOUT, NOLVP, NOZCDDIS //ZCDを生かす
・・・で ZCD機能を生かしています。
測定には必要ないのですがモニターのために・・・
#pin_select ZCD1OUT = PIN_C2 // LEDにZCD信号を出力する(モニタ用))
・・・を設定して、ZCD信号で LEDを参考のために点滅させています。
main() の初期設定で・・・
// 窓周期計測モード、クロック:Fosc、ZCD1、1回のみの測定モードを設定
setup_smt1(SMT_ENABLED | SMT_MODE_WINDOWED_MEASURE | SMT_CLK_FOSC
| SMT_WIN_INPUT_ZCD1 | SMT_SINGLE_DATA_ACQ_MODE);
setup_zcd(ZCD_ENABLE);
・・・とし、SMTと ZCD のセットアップをしています。
SMT_window信号は、ZCDとしており、ZCDは電源波形の半周期ごとにトグルになっているので、ZCDの1周期は電源の1周期と同じとなります。1秒のカウント数は
32,000,000(32MHz)であるので、それを計測信号の1周期のカウント数(temp)で割ればAC電源の周波数が出ることになります。
Freq = 32000000.0 / (float)temp; // 周波数に変換
これをテストしている地域は九州ですので 60Hzです。関東でしたら 50Hz になります。
1回のみの測定モードを設定しているので smt1_start(); を実行してループのトップに戻ります。
いずれにしろ CCS-C では、設定と表示のコードが、かなりシンプルにできることが良く分かると思います。
8. SMT(信号計測タイマ)による距離の測定
学習用のフォルダ「C:\PIC_Practice\chap4_8」を作成して下さい。このフォルダ「chap4_8」の中に次の5つのファイルを入れて下さい。下のリストの
main.c の範囲をドラッグして選択します、その状態で右クリックしてコピーします。それをメモ帳などのエディタに貼り付けて、名前を付けて保存で名前を
main.c とします。同様に、 SciCommand.c、HardProfile.h、ST7032i_lib.c、ST7032i_lib.h
のそれぞれの範囲をコピーして、それぞれの名前で保存して下さい。前の章と同名であっても、内容が変わっている場合もありますので、このリストから取得してください。そして、ターゲット基板と「書込み&ディバッグ基板」を接続し、パソコンとの間を
RS232C通信ケーブルと Pickit 3 USBケーブルで接続してください。ターゲットの電源を入れておいてください。LCD は AQM1602Y
を使います
リスト chap4_8
さて、MPLAB-X-IDE から、chap4_1のプロジェクトの制作を参照しながら、下図のプロジェクト画面となるようにしてください。

超音波距離計(HC-SR04) を下図の写真のように取り付けてください。パソコンと基板 を Pickit 3 と RS232C ケーブルで接続し、基板の電源を入れておいて、「Make
and Program Device Main Project」(下矢印)をクリックし、ファームウェアをダウンロードします。

ダウンロードが完了すると既に動作を開始しています。距離計(HC-SR04) をターゲットに向けると、そこまでの距離をセンチ(cm)で表示します。RS232C
で計測している値を表示しています。
設定について説明いたします。
//ゲート付きタイマモード、クロック:Fosc、SMT1SIG、繰り返しモードを設定
setup_smt1(SMT_ENABLED | SMT_MODE_GATED_TIMER | SMT_CLK_FOSC
| SMT_SIG_INPUT_SMTSIGx | SMT_REPEAT_DATA_ACQ_MODE);
モードは、ゲート付きタイマモードです。クロックは Fosc とし、SMT_sugnal の入力を SMTSIGx に設定、さらにスタートすると
繰り返しの測定をするモードにしています。また、下の設定で SMT1PWA の割り込みを許可します。
enable_interrupts(INT_SMT1PWA); //SMT1PWA の割り込み
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
割り込みルーチンは・・・
#int_smt1pwa
void pwa_isr(void)
{
temp = smt1_read(SMT_CAPTURED_PULSE_WIDTH_REG);
Fint = TRUE;
}
・・・としており、割り込みがかかる度にカウントしているレジスタ値を temp に読み込み Fintフラグを TRUEにします。Fint は、メインループで割り込みがあったことを検知するためのフラグになっています。
この超音波距離計(HC-SR04) のマニュアルをここに示しますので見て下さい。Trig端子に 10us のトリガパルスを加えると Echo 端子にターゲットまでの往復時間が HIGH であるパルスが返ってきます。
この Echo の時間を計測することで、ターゲットまでの距離を測定します。
この距離計(HC-SR04) の最大測定可能距離は、400cm となっています。余裕を見て往復 1,000cm を計測するとすれば、音速を340m/sとして・・・
10(m) / 340(m/s) = 29,412us の時間まで計測できれば良いこととなります。
クロックは Fosc(32MHz) で、SMT のカウンタは 24bitですから、最大カウント時間は・・・
(1 / 32)us × 0xFFFFFF(16,777,215) = 524,287 us
・・・です。したがって可能な連続計測積算回数は・・・
524,287 ÷ 29,412 = 17.82 となり、17回まではオーバーフローしないで積算できることになります。SMT の無い PICの
16bit のカウンタを使う事で苦労したことを思えばウソみたいですね。そこでここでは、繰り返し積算回数を 10回と定義します。
const int RN = 10; //距離測定繰り返し回数
main() のループで・・・
smt1_start();
for(i=0; i<RN; i++) { //繰り返しモードなのでRN回のSMT1SIGのHIを積算
output_high(TRIG); // Triger On
delay_us(11);
output_low(TRIG); // Triger Off
while(Fint == FALSE) exe_command(); //割り込み実行待ち
Fint = FALSE;
delay_ms(60);
}
temp /= RN; //平均値
・・・として、10回の計測をして平均値を出しています。
片道の距離(cm) = T(Echo:us) × 1/2 × 340(m/s) × 100(cm/m) × 1/1000000(us/s)
上の式をまとめると 片道の距離(cm) = 往復の時間T(Echo:us) × 0.017(cm/us)
----------------
すなわち往復の時間(us)が分かれば、上記の式によって片道の距離(cm)が出ることになります。
temp は Fosc をカウントしており、その周期は (1000000/32000000) = 0.03125(us) です。
したがって 0.03125 × temp により往復の時間(us)が出るので・・・
Distance = (0.03125 * (float)temp) * 0.017; //対象迄の距離(cm)
・・・の式により、対象までの距離がセンチ単位で算出できます。
次の計測に入る前に、レジスタの積算値をクリアしなければならないので・・・
smt1_reset_timer(); // カウンタクリア
・・・を実行し無限ループのトップに戻ります。
ここでは簡略的に音速は、約 340 m/s としましたが、常用されている速度としては、1気圧の乾燥空気中では 331.5 + 0.61t (
t は摂氏温度)が使われています。先に演習した「5. 温度を測定し LCDに表示する」で実行した温度を利用して式を立てれば、もう少し精度の高い測定になるでしょう。
それにしても前の PIC16F1938 の演習で、16bit のカウンタを使って苦労して距離を測定していましたが、SMT の 24bitカウンタを使えば楽に高精度の計測が可能なことがわかります。
|
9. SMTにより周期・Duty可変の信号を発生させる
学習用のフォルダ「C:\PIC_Practice\chap4_9」を作成して下さい。このフォルダ「chap4_9」の中に次の5つのファイルを入れて下さい。下のリストの
main.c の範囲をドラッグして選択します、その状態で右クリックしてコピーします。それをメモ帳などのエディタに貼り付けて、名前を付けて保存で名前を
main.c とします。同様に、 SciCommand.c、HardProfile.h、ST7032i_lib.c、ST7032i_lib.h
のそれぞれの範囲をコピーして、それぞれの名前で保存して下さい。前の章と同名であっても、内容が変わっている場合もありますので、このリストから取得してください。そして、ターゲット基板と「書込み&ディバッグ基板」を接続し、パソコンとの間を
RS232C通信ケーブルと Pickit 3 USBケーブルで接続してください。ターゲットの電源を入れておいてください。LCD は AQM1602Y
を使います
リスト chap4_9
さて、MPLAB-X-IDE から、chap4_1のプロジェクトの制作を参照しながら、下図のプロジェクト画面となるようにしてください。

このプロジェクトは、SMT1 と SMT2 のタイマー機能を使って、1HZ から 12KHz の矩形波信号を発生させて、さらにそのデューティを
0.1% から 99.9% まで可変にするものです。
パソコンと基板 を Pickit 3 と RS232C ケーブルで接続し、基板の電源を入れておいてください。「Make and Program
Device Main Project」(下矢印)をクリックし、ファームウェアをダウンロードします。

ダウンロードが完了すると既に動作を開始しています。現在発生している信号の情報として、LCDの上の行に周波数を、下の行にデューティを表示しています。コネクタ
CN-SENSER の 3 - 4(GND) 間に出力しています。ディフォールトは 1000HZ, Duty:50% です。オシロスコープで観察すると上図の右の一番上のようになっています。
周波数やデューティを変更するには、モニター(RS232C) を使って実行します。左図は、モニターを起動して操作している画面です。コマンド’?’
で使用できるコマンドの一覧を示します。
コマンド’P’で、現在の設定の確認をしています。左の例では 周波数 10Hz,Duty:50.0% が返っています。
次にコマンド’D35.5’ で、デューティ35.5%に変更しています。周波数はそのままです。
次にコマンド 'F10K' で、周波数を 10,000Hzに変更した上で、コマンド’P’で、現在の設定を再度確認しています。
次にコマンド 'F300' で周波数を 300Hzに変更し、コマンド’P’で、設定されている内容の確認をしています。
まずは、具体的に各コマンドを発行して動かして見てください。
コマンド 'D', 'F' は、入力のヘルプです。
Fxxx 1 =< xxx =< 12K
'xxx' must be upper range!
Dxxx 0.1 =< xxx =< 99.9
'xxx' must be upper range!
・・・のように表示されます。レンジの範囲外の数値を入力したときも同じメッセージが出ます。
実際に出力されている波形はオシロスコープが無いと分かりませんが、次の演習(「SMTによる信号の周期・デューティの測定」)で、確認ができます。
main.c のはじめに、次の記述があります。
;---------- #define CLOCKA 16000000
#use delay(clock=CLOCKA, internal)
// グローバル変数・プロトタイプ宣言
float Freq = 1000;
float Duty = 50;
int32 SMT_PERIOD = (CLOCKA / Freq) - 1;
int32 SMT_DUTY = (CLOCKA / Freq) * (Duty / 100); ;----------
ここに、このファームウェアで使う主要な共通変数を定義しています。クロックは 16MHz で動作させます。モニターのコマンドで周波数・デューティを変更できますが、それはコマンドでこの変数の値を書き換えて、さらに
SMT1 と SMT2 を再設定することで実現しています。
main() 関数の始めに・・・ ;----------
SMT_Setup(); // SMT1, 2 のセットアップ
enable_interrupts(INT_SMT1); //enabled SMT1 interrupt
enable_interrupts(INT_SMT2); //enabled SMT2 interrupt
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL); ;----------
・・・として、SMT1, 2 のセットアップをして、SMT1, SMT2 の割り込みを許可しています。
上で呼び出している「SMT1, 2 のセットアップ」は・・・ void SMT_Setup(void)
{
smt1_stop();
smt2_stop();
output_low(PIN_A4);
// タイマモード、クロック:Fosc、1周期のカウント数を指定(int32 SMT_PERIOD 参照)
setup_smt1(SMT_ENABLED | SMT_MODE_TIMER | SMT_CLK_FOSC, SMT_DUTY);
setup_smt2(SMT_ENABLED | SMT_MODE_TIMER | SMT_CLK_FOSC, SMT_PERIOD);
output_high(PIN_A4);
smt1_start(); //start SMT1 割り込みで自身を停止
smt2_start(); //start SMT2 連続、割り込みで SMT1_startを実行
}
・・・となっており、SMT2 が全体の周期を決める単純タイマーモードで動作します、これは LEDの点滅で確認できます。SMT1 も単純タイマーモードですが、
SMT_DUTY の時間後の割り込みで、自身で、smt1_stop(); を実行して動作を停止し、One Shot 動作をするようにしています、これは信号として
PIN_A4 に出力されます。以下の割り込みをご参照ください。
割り込みの記述は・・・ #int_smt1
void smt1_isr(void)
{
output_low(PIN_A4);
smt1_stop(); //自分自身でstop こうすれば One Shot なる
}
#int_smt2
void smt2_isr(void)
{
output_high(PIN_A4);
smt1_start();
output_toggle(PIN_C2); //LED点滅
}
・・・となっています。PIN_A4 が信号の出力(CN-SENSER 3pin) になります。回路図をご参照ください。
C言語の学習としては、SciCommand.c 内で記述しているコマンドの受付などは良い教材になると思います。ここでは、Tstf = strtod(p,
&tp); などの標準関数を使っていますが、これらの標準関数を使い慣れてまいりましょう。また、 CalculateFreq() 関数内で使っている
Count = sprintf(str, "%0.2f ", FreqS); などの sprintf 関数の使い方に慣れておくことも良いと思います。
10. SMTによる信号の周期・デューティの測定
学習用のフォルダ「C:\PIC_Practice\chap4_10」を作成して下さい。このフォルダ「chap4_10」の中に次の3つのファイルを入れて下さい。下のリストの
main.c の範囲をドラッグして選択します、その状態で右クリックしてコピーします。それをメモ帳などのエディタに貼り付けて、名前を付けて保存で名前を
main.c とします。同様に、ST7032i_lib.c、ST7032i_lib.h のそれぞれの範囲をコピーして、それぞれの名前で保存して下さい。前の章と同名であっても、内容が変わっている場合もありますので、このリストから取得してください。そして、ターゲット基板と「書込み&ディバッグ基板」を接続し、パソコンとの間を
RS232C通信ケーブルと Pickit 3 USBケーブルで接続してください。ターゲットの電源を入れておいてください。LCD は AQM1602Y
を使います
リスト chap4_10
さて、MPLAB-X-IDE から、chap4_1のプロジェクトの制作を参照しながら、下図のプロジェクト画面となるようにしてください。

このプロジェクトは、CCS, Inc. から提供されている「 ex_smt_period_duty.c 」を流用しています。指定端子に入力されている信号の周期とデューティを同時に測定するものです。
下の写真では、左の基板が、前章の「SMTにより周期・Duty可変の信号を発生させる」による信号発生で、右の基板が今回の「SMTによる信号の周期・デューティの測定」です。この2枚の基板の間をそれぞれの
CN-SENSERの Pin 3-4(GND) で接続しています(赤・茶の配線)。この2枚を用意できない場合は、右の基板(現動作基板)のコネクタ(CN-SENSER)の
Pin 3-4(GND) 間に測定したい信号を入力して下さい。また写真では、書き込み・モニター基板からの 8PINコネクタが左の基板にささっていますが、右の、今回動かす基板の方に挿してください。
パソコンと基板 を Pickit 3 と RS232C ケーブルで接続し、基板の電源を入れておいてください。「Make and Program
Device Main Project」(下矢印)をクリックし、ファームウェアをダウンロードします。

ダウンロードが完了すると既に動作を開始していますが、信号が入力されていないと測定できません。現在入力されている信号の情報として、LCDの上の行に周期を、下の行にデューティを表示しています。コネクタ
CN-SENSER の 3 - 4(GND) 間から信号を入れてください。

書き込み・モニター基板からの 8PINコネクタを、今回動かす基板(右)にさして RS232Cケーブルをパソコンに接続し Tera Term を起動すると、左図のモニターの画面のように、現在測定している数値を約
0.5秒間隔で送信してきています。
SMT の設定は次の通りです。 setup_smt1(SMT_ENABLED | SMT_MODE_PERIOD_DUTY_CYCLE_ACQ | SMT_CLK_FOSC | SMT_SIG_INPUT_SMTSIGx);
つまり、モードは、周期_デューティ同時測定モードで、クロックは Fosc(16MHz)、入力は SMTSIG1 です。
enable_interrupts(INT_SMT1PRA);
enable_interrupts(INT_SMT1PWA);
enable_interrupts(GLOBAL);
・・・で、2つの割り込みを許可します。
それぞれの割り込みの中で、周期とデューティの数値をレジスタから読み取っています。
割り込みが掛かって数値の読み取りが完了すると、フラグ(NewCapture)を TRUE とします。main()関数の無限ループの中ではそのフラグをチェックしていて、それが
TRUE になるとRS232C に送信し、LCD に表示しています。表示が終わると・・・ NewCapture = FALSE;
smt1_start(); //re-start SMT1
・・・とし、次の測定を開始します。これらのモードについては「SMT (信号計測タイマ) の使い方」でお調べください。日本語で解説されているのでありがたいです。この文書での、11個のモードの中の「@ 周期とデューティサイクルモード」にあたります。
【割り込み】 #INT_SMT1PRA
void period_isr(void)
{
SignalPeriod = smt1_read(SMT_CAPTURED_PERIOD_REG); //read captured period
NewCapture = TRUE;
}
#INT_SMT1PWA
void duty_isr(void)
{
SignalDuty = smt1_read(SMT_CAPTURED_PULSE_WIDTH_REG); //read captured
duty
}
各レジスタの読み込みも、このようにシンプルに行えます。先のリンクの「(1) 周期とデューティモードの動作」の項目に描いてある図と説明をご参照下さい。
いずれにしろ、CCS-C用 に用意された関数を使えば、比較的容易にデバイスの設定および読み取りが行えることが分かると思います。逆に言うと、コードを解釈するときに「何をしているのか?」という意図が分かりやすいという所が良いと思います。
|
【動かしましょう−5】
ここでは PIC12F1612 を動かしてみます。PIC演習用基板(5) を使用します。この PIC12F1612 は、比較的新しいデバイスですので、MPLAB-IDE ではサポートされていません。それで、このプロジェクトも MPLAB-X-IDE で制作することにいたします。
この PICは、前章で動かした、PIC16F1619 と同様に「新世代CIP(コアから独立した周辺モジュール)」が実装されています。ただし、PPS機能は搭載されていません。
[ COLUMN ]
MPLAB-IDE でプロジェクトを作成する時に、似たようなデバイスの名称(例えばPIC12F1501など) を使って行けば、プロジェクトを作成することはできます。main.c
のトップで #include <12F1612.h> を入れているのでコンパイルそのものは 12F1612 としてできます。ただ、Pickit
3 からのダウンロードは MPLAB-IDE からはできません。それで、ダウンロード作業のみを MPLAB IPE を使って行えば、開発そのものは MPLAB-IDE ででもできます。
[ Contents ]
1. 超音波距離計(HC-SR04)のテスト
2. 信号の周期・デューティの測定
1. 超音波距離計(HC-SR04)のテスト
学習用のフォルダ「C:\PIC_Practice\chap5_1」を作成して下さい。これでは C:ドライブのルートに作成していますが、ご自分で管理できる所ならば、どこでも構いません。このフォルダ「chap5_1」の中に次の3つのファイルを入れて下さい。下のリストの
main.c の範囲をドラッグして選択します、その状態で右クリックしてコピーします。それをメモ帳などのエディタに貼り付けて、名前を付けて保存で名前を
main.c とします。同様に、 ST7032i_lib.c の範囲をコピーして、 ST7032i_lib.c とし、次に、ST7032i_lib.h
の範囲をコピーして ST7032i_lib.h として保存して下さい。3つのファイルの境目の目印である・・・
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
・・・は、無視して良いです。これは、以降のサンプルでも同様です。
ターゲット基板に距離計(HC-SR04)を取り付け、更に書き込みディバック基板に Pickit 3 を接続し、PROGコネクタでターゲットに接続して電源を入れておいてください。
この章では、 MPLAB-X-IDE でプロジェクトを作成しますが、作成法については前章(chap4_1)をご参照ください。
リスト chap5_1
プロジェクト作成の結果が下図のようになるようにしてください。次に金槌マークのコンパイルを実行し、「BUILD SUCCESSFUL」が出ればOKです。

次に、下矢印マークのダウンロードを実行してください。ダウンロードが完了しましたら、PICkit 3 をモニター・デバッグ基板から外してください(下図参照)。そして、ターゲット基板の左端にある RESET スイッチを押してください。そうすると動作を開始し、LCD にターゲットまでの距離をセンチ単位で表示します。テラタームを起動し、19200bpsで開くと、下図の右図のように測定値を表示します。

この PIC は8Pinであるため、端子の余裕がありません、それでファームウェアの書き込みに必要な端子(PGD,PGC,MCLR)と実動作に必要な端子を共用しています。したがって書き込み後の
PICkit 3 の切り離しと RESET 操作が必要になります。PIKkit 3 の PGD,PGC,MCLRに接続される外部回路は OUT
になっていると書き込みはできません(OUTがぶつかる) ので、ターゲット基板を設計する場合は、共用する端子に接続する外部回路は IN (もしくはOpen)にする必要があります。この様な工夫は必要ですが、ディバッグで書き込みが必要なときに、その都度 PIC を抜き差しする必要がないのでとても重宝します。
このPIC12F1612 には、USARTとI2Cのモジュールがありません。したがって RS232C通信と LCDを表示するための I2C通信は、ソフトウェアで実装する必要がありますが、CCS-C ではその機能を持っています。
#use delay(clock=32000000)
#use rs232(baud=19200,xmit=PIN_A2) //送信のみ
#use i2c(MASTER, SDA=PIN_A0, SCL=PIN_A1, ADDRESS=0xa0)
・・・を記述することで、RS232C と I2C は使えるようになります。これはとてもありがたいです。
この、「距離測定」のソフトの内容は、全く前章(chap4_8)と同じですので、フローの解説はそちらをご参照ください。
2. 信号の周期・デューティの測定
学習用のフォルダ「C:\PIC_Practice\chap5_2」を作成して下さい。これでは C:ドライブのルートに作成していますが、ご自分で管理できる所ならば、どこでも構いません。このフォルダ「chap5_2」の中に次の3つのファイルを入れて下さい。下のリストの
main.c の範囲をドラッグして選択します、その状態で右クリックしてコピーします。それをメモ帳などのエディタに貼り付けて、名前を付けて保存で名前を
main.c とします。同様に、 ST7032i_lib.c の範囲をコピーして、 ST7032i_lib.c とし、次に、ST7032i_lib.h
の範囲をコピーして ST7032i_lib.h として保存して下さい。3つのファイルの境目の目印である・・・
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
・・・は、無視して良いです。
基板および Pickit 3 の接続をしておき、電源を入れておいてください。
この章では、 MPLAB-X-IDE でプロジェクトを作成しますが、作成法については前章(chap4_1)をご参照ください。
リスト chap5_2
プロジェクト作成の結果が下図のようになるようにしてください。次に金槌マークのコンパイルを実行し、「BUILD SUCCESSFUL」が出ればOKです。

計測する信号をターゲット基板の CN-SENSORコネクタの 3 - 4(GND)ピンに入力しておいてください。前章の chap4_9 で発生している信号でも良いです。その方が信号の周期とデューティが分かっていて良いかもしれません。次に、下矢印マークのダウンロードを実行してください。ダウンロードが完了しましたら、PICkit 3 をモニター・デバッグ基板から外してください(下図参照)。そして、ターゲット基板の左端にある RESET スイッチを押してください。そうすると動作を開始し、LCD の上の行に周期を、下の行にデューティを表示します。

この PIC は8Pinであるため、端子の余裕がありません、それでファームウェアの書き込みに必要な端子(PGD,PGC,MCLR)と実動作に必要な端子を共用しています。したがって書き込み後の
PICkit 3 の切り離しと RESET 操作が必要になります。PIKkit 3 の PGD,PGC,MCLRに接続される外部回路は OUT
になっていると書き込みはできません(OUTがぶつかる)ので、ターゲット基板を設計する場合は、共用する端子に接続する外部回路は IN(もしくはOpen) にする必要があります。この様な工夫は必要ですが、ディバッグで書き込みが必要なときに、その都度 PIC を抜き差しする必要がないのでとても重宝します。
このPIC12F1612 には、USARTとI2Cのモジュールがありません。したがって RS232C通信と LCDを表示するための I2C通信は、ソフトウェアで実装する必要がありますが、CCS-C ではその機能を持っています。これでは、 I2Cのみを下記の記述で実装します。
#define CLOCKA 16000000
#use delay(clock=CLOCKA, internal)
#use i2c(MASTER, SDA=PIN_A0, SCL=PIN_A1, ADDRESS=0xa0)
・・・これで I2C を使えるようになります。これはとてもありがたいです。
この小さな PICに LCDの表示まで実装しているので、ROM の使用率は 91%になっていますが問題なく動作しています。
この、「信号の周期・デューティの測定」のソフトの内容は、全く前章(chap4_10)と同じですので、フローの解説はそちらをご参照ください。
【 参考 】 XC8 から CCS-Cへの移植例 ラズパイ Zero によるインターネット・ラジオ
|