
左写真が実験1の風景です。
---------------------------------------------------------------------
#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.