--------------------------------------------------------------------- #include <xc.h> #include <stdlib.h> #include "skMonitorLCD.h" // LCDモニター用 #define _XTAL_FREQ 8000000 // delay用に必要(クロック8MHzを指定) // コンフィギュレーション1の設定 #pragma config FOSC = INTOSC // 内部クロック使用する(INTOSC) #pragma config WDTE = OFF // ウオッチドッグタイマー無し(OFF) #pragma config PWRTE = ON // 電源ONから64ms後にプログラムを開始する(ON) #pragma config MCLRE = OFF // 外部リセット信号は使用せずにデジタル入力(RA3)ピンとする(OFF) #pragma config CP = OFF // プログラムメモリーを保護しない(OFF) #pragma config CPD = OFF // データメモリーを保護しない(OFF) #pragma config BOREN = ON // 電源電圧降下常時監視機能ON(ON) #pragma config CLKOUTEN = OFF // CLKOUTピンをRA4ピンで使用する(OFF) #pragma config IESO = OFF // 外部・内部クロックの切替えでの起動はなし(OFF) #pragma config FCMEN = OFF // 外部クロック監視しない(OFF) // コンフィギュレーション2の設定 #pragma config WRT = OFF // Flashメモリーを保護しない(OFF) #pragma config PLLEN = OFF // 動作クロックを32MHzでは動作させない(OFF) #pragma config STVREN = ON // スタックがオーバフローやアンダーフローしたらリセットをする(ON) #pragma config BORV = HI // 電源電圧降下常時監視電圧(2.5V)設定(HI) #pragma config LVP = OFF // 低電圧プログラミング機能使用しない(OFF) // メインの処理 void main() { char s[8] ; unsigned int cap ; OSCCON = 0b01110010 ; // 内部クロックは8MHzとする ANSELA = 0b00000100 ; // アナログはAN2を使用し、残りをすべてデジタルI/Oに割当 TRISA = 0b00000100 ; // AN2(RA2/CPS2)だけ入力その他のピンは出力に割当てる(RA3は入力専用) PORTA = 0b00000000 ; // 出力ピンの初期化(全てLOWにする) // 容量検知モジュール(CPSM)の設定 CPSCON0 = 0b00001000 ; // オシレータは中範囲(中速の発信周波数)で利用する CPSCON1 = 0b00000010 ; // CPS2から入力する // タイマー1の設定 T1CON = 0b11000001 ; // 容量検知オシレータでTIMER1をカウントする、プリスケーラカウント値 1:1 TMR1H = 0 ; // タイマー1の初期化 TMR1L = 0 ; PEIE = 1 ; // 周辺装置割り込みを許可する GIE = 1 ; // 全割り込み処理を許可する CPSON = 1 ; // 容量検知モジュール開始 MonitorInit() ; // LCDモニターに送信出来る様に初期化する while(1) { // 容量検知モジュールの値を読み込む CPSON = 0 ; // 容量検知モジュール停止 cap = (TMR1H*256) + TMR1L ; // カウント値を読み込む TMR1H = 0 ; // タイマー1の初期化 TMR1L = 0 ; CPSON = 1 ; // 容量検知モジュール開始 // 読んだ値をLCDモニターに表示する utoa(s,cap,10) ; // カウント値を文字列に変換する MonitorPutc(0x11) ; // モニターの表示位置を設定する MonitorPuts(" ") ; // 表示を消す MonitorPutc(0x11) ; // モニターの表示位置を設定する MonitorPuts(s) ; // 表示する // 400ms後に繰り返す __delay_ms(400) ; } } ---------------------------------------------------------------------このプログラムにはデバッグモニタープログラム「skMonitorLCD.c」「skMonitorLCD.h」が必要です。
電極 | 触れていない時 | 触れた時 | 0.5mmの青アクリル裏 から触れた時 |
リードジャンプワイヤー | 62720〜62445位 | 39620〜39430位 | − |
20mm x 20mm x 0.3mm の銅板 | 57995〜57675位 | 38830〜38745位 | 49100〜49045位 |
ビット | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
機能 | CPSON | CPSRM | CPSRNG | CPSOUT | T0XCS |
CPSRM | レンジ | CPSRNG | オシレータモード | 公称充電電流 |
0 | Low | 00 | オフ | 0.0μA |
01 | 低範囲(Low) | 0.1μA | ||
10 | 中範囲(Medium) | 1.2μA | ||
11 | 高範囲(High) | 18μA | ||
1 | High | 00 | ノイズ検出用 | 0.0μA |
01 | 低範囲(Low) | 9μA | ||
10 | 中範囲(Medium) | 30μA | ||
11 | 高範囲(High) | 100μA |
CPSCON1 | チャンネル | 端子番号 |
00000000 | チャンネル0、CPS0 | 7(RA0) |
00000001 | チャンネル1、CPS1 | 6(RA1) |
00000010 | チャンネル2、CPS2 | 5(RA2) |
00000011 | チャンネル3、CPS3 | 3(RA4) |
--------------------------------------------------------------------- #include <xc.h> #define _XTAL_FREQ 8000000 // delay用に必要(クロック8MHzを指定) #define ROBE_NUMBER 2 // 接続している電極の個数を指定 unsigned int CPS_data[2][ROBE_NUMBER] ; // 容量検知用データ // コンフィギュレーション1の設定 #pragma config FOSC = INTOSC // 内部クロック使用する(INTOSC) #pragma config WDTE = OFF // ウオッチドッグタイマー無し(OFF) #pragma config PWRTE = ON // 電源ONから64ms後にプログラムを開始する(ON) #pragma config MCLRE = OFF // 外部リセット信号は使用せずにデジタル入力(RA3)ピンとする(OFF) #pragma config CP = OFF // プログラムメモリーを保護しない(OFF) #pragma config CPD = OFF // データメモリーを保護しない(OFF) #pragma config BOREN = ON // 電源電圧降下常時監視機能ON(ON) #pragma config CLKOUTEN = OFF // CLKOUTピンをRA4ピンで使用する(OFF) #pragma config IESO = OFF // 外部・内部クロックの切替えでの起動はなし(OFF) #pragma config FCMEN = OFF // 外部クロック監視しない(OFF) // コンフィギュレーション2の設定 #pragma config WRT = OFF // Flashメモリーを保護しない(OFF) #pragma config PLLEN = OFF // 動作クロックを32MHzでは動作させない(OFF) #pragma config STVREN = ON // スタックがオーバフローやアンダーフローしたらリセットをする(ON) #pragma config BORV = HI // 電源電圧降下常時監視電圧(2.5V)設定(HI) #pragma config LVP = OFF // 低電圧プログラミング機能使用しない(OFF) // 容量検知モジュールの初期値を読み込む処理 void CPS_Init() { int i ; // 接続している電極の分だけ繰り返す for (i=0 ; i<ROBE_NUMBER ; i++) { CPSCON1 = i ; // 読み込むチャンネルを設定する TMR1H = 0 ; // タイマー1の初期化 TMR1L = 0 ; CPSON = 1 ; // 容量検知モジュール開始 __delay_us(5000) ; // 5msの間タイマー1をカウントさせる // 容量検知モジュールの値を読み込む CPSON = 0 ; // 容量検知モジュール停止 CPS_data[0][i] = (TMR1H*256) + TMR1L ; CPS_data[1][i] = 0 ; } } // 容量検知モジュールに接続されている電極の現在値を読み込む処理 void CPS_ScanRobe() { unsigned int cap ; int i ; // 接続している電極の分だけ繰り返す for (i=0 ; i<ROBE_NUMBER ; i++) { CPSCON1 = i ; // 読み込むチャンネルを設定する TMR1H = 0 ; // タイマー1の初期化 TMR1L = 0 ; CPSON = 1 ; // 容量検知モジュール開始 __delay_us(5000) ; // 5msの間タイマー1をカウントさせる // 容量検知モジュールの値を読み込む CPSON = 0 ; // 容量検知モジュール停止 cap = (TMR1H*256) + TMR1L ; if (cap <= (CPS_data[0][i]*0.9)) { CPS_data[1][i] = cap ; // ONとする } else { CPS_data[1][i] = 0 ; // OFFとする CPS_data[0][i] = cap ; } } } // 容量検知モジュールに接続されている電極の状態を調べる処理 // num : 調べる電極の番号を指定する int CPS_StateRobe(int num) { if (num > ROBE_NUMBER) return( -1 ) ; // 数値指定エラー if (CPS_data[1][num-1] == 0) return( 0 ) ; // 電極に触れていない else return( 1 ) ; // 電極に触れている } // メインの処理 void main() { OSCCON = 0b01110010 ; // 内部クロックは8MHzとする ANSELA = 0b00000011 ; // アナログはAN0/AN1を使用し、残りAN2/AN3はデジタルI/Oに割当 TRISA = 0b00000011 ; // ピンRA0(AN0)/RA1(AN1)を入力、残りは出力に割当てる(RA3は入力専用) PORTA = 0b00000000 ; // 出力ピンの初期化(全てLOWにする) // 容量検知モジュール(CPSM)の設定 CPSCON0 = 0b00001100 ; // オシレータは高範囲(高速の発信周波数)で利用する // タイマー1の設定 T1CON = 0b11000001 ; // 容量検知オシレータでTIMER1をカウントする、プリスケーラカウント値 1:1 TMR1H = 0 ; // タイマー1の初期化 TMR1L = 0 ; PEIE = 1 ; // 周辺装置割り込みを許可する GIE = 1 ; // 全割り込み処理を許可する // 容量検知モジュールの初期値を読み込む CPS_Init() ; while(1) { // 容量検知モジュールの現在値を読み込む CPS_ScanRobe() ; // 電極1(CPS0)の状態でLED1を点灯させる処理 if (CPS_StateRobe(1) == 1) RA2 = 1 ; // LED1を点灯 else RA2 = 0 ; // LED1を消灯 // 電極2(CPS1)の状態でLED2を点灯させる処理 if (CPS_StateRobe(2) == 1) RA4 = 1 ; // LED2を点灯 else RA4 = 0 ; // LED2を消灯 } } ---------------------------------------------------------------------プログラムについて
#define ROBE_NUMBER 2 // 接続している電極の個数を指定例えば、3個にする場合は3と指定して、CPS2端子を利用します、次の続いているチャンネルを使い
検知状態 | 触れていない時 | 触れた時 | 0.5mmの青アクリル裏 から触れた時 |
5msの間カウントした場合 | 2040〜2030位 | 1450〜1440位 | 1721〜1719位 |
10msの間カウントした場合 | 4070〜4038位 | 2992〜2987位 | 忘れた |
while(1) { CPS_ScanRobe() ; }とこんな感じですね。
void interrupt InterTimer( void ) { if (TMR0IF == 1) { // タイマー0の割込み発生か? TMR0 = ???? ; // タイマー0の初期化 CPS_ScanRobe() ; TMR0IF = 0 ; // タイマー0割込フラグをリセット } }とこんな感じですね。
if (cap <= (CPS_data[0][i]*0.9)) {の行が有りますこれを97%にするなら0.9から0.97と変更して下さい。
リンク切れ見直し(*5) 2017/01/11
MPLAB X用に記事変更(*4) 2015/10/14
"skMonitorLCD.c"変更により"実験1"のプログラム変更(*3) 2014/02/01
追記(*2) 2013/06/03
追記(*1) 2013/02/12
【きむ茶工房ガレージハウス】
Copyright (C) 2006-2020 Shigehiro Kimura All Rights Reserved.