確定申告で「医療費控除は10万円を超える分」で、今まで支払金額が10万円を超えることはなかった。しかし、昨年は入院したので医療費が10万円を超えており、医療費控除について調べて見た。
控除の対象となる医療費は国税庁で紹介されているが、簡単に主なものを纏めると、
P PICミニBBシリーズ(1) 〜I2C接続4x3キーユニット
by fjk
abc889で、PIC用の汎用で使えるLCD表示ユニットをミニブレッドボード(BB-601)で作成した。そこで、同じように「I2C接続4x3キー」ユニットも作ってみることにした。ユニット間の接続はフラットケーブルもしくは、L型ソケット+L型ピンヘッダー(標準のピンヘッダーはピン長さが短いので、「連結ピンヘッダ(秋月電子 102959)」を加工)を使用した。L型コネクターへの曲げ加工方法は以下、

バイスに鉄板とピンを鋏み一気に曲げる
(ピンは少し隙間を空けてセット) |

ピンヘッダーはソケットに刺して曲げる
(ピンヘッダーは強度が弱いので)
|
●● ハードウェア ●●
【PIC-BASE14】 (回路・MCC設定の詳細についてはabc887を参照)
14ピンPICの汎用マイクロコントローラユニット(PIC-BASE14)として、ミニブレッドボードBB-601(秋月電子、105155、150円)で作成した。ユニットはPIC16F18xx系の14ピンPICが使えるものとし、(PPS使用を含め)ピン配置が同じPIC16F15xxやPIC16F17xxも利用可能である。
回路は、基本的にはabc887とほぼ同じだが、LEDとプッシュスイッチを各1個搭載(他のものに置き換え可)。チップの右側に、Vcc,Gnd,I2C,SPIなどに使用するピンが取り出せるようにした。
- 14ピンPIC搭載ユニットで、シリアル(USB)、I2C、SPIインターフェースを備える
- PIC-BASE14で使用可能なPICは、PIC16F1823/4/5、PIC16F18323/4/5/6、PIC16F18424/5/6、およびピン互換PIC(PIC16F1503、PIC16F15325,PIC16F1705,PIC16F1765など)

PIC-BASE14回路図 |

BB-601で作成したPICユニット
(abc889のLCDユニットと接続した例)
|
【PIC-4x3_Key】 (回路・MCCの設定の詳細はabc858を参照)
キーユニットは「4x3キーパッド作成キット用基板」(秋月電子、112316、105円)にタクトスイッチを並べた。キーパッド基板が大きいのでブレッドボードとしてEIC-301(秋月電子、100313、300円)を用いた。
- 4x3マトリクスプッシュキーユニットで、インタフェースはシリアル(USB)、I2C(スレーブ)
- I2Cスレーブ用のPICはPPSを利用したいのでPIC16F18325を使った。
- キーマトリクスとBBの接続には、基板内に納めるため8ピンのピンヘッダーとソケットを使い、接続ピンの位置がBBの中心部になるようにした。
- USBシリアル接続も可能だが、基本的にはUSBとI2Cの同時使用はできない。しかし、USB電源の(赤い)ジャンパー線を外すことで同時使用も可能。。

PIC-4x3_Key回路図 |

EIC-301で作成したキーユニット
|
- ※4x3キーパッドはM3(L=20mm)ビスとM3用プラスチックスペーサー(H=6mm)でEIC-301に固定。
【ユニット組み合わせ応用例】
PIC-BASE14、PIC-4x3_Key、および前報(abc889)で作成したLCD表示ユニット(PIC-LCD16x2)を接続し、キー入力があれば、LCDにキー入力データを表示し、さらにUSBシリアルでパソコンに送信を行う(キーユニットのUSBは使用していない)。I2CはPIC-LCD16x2ユニットからPIC-4x3_Keyユニットに接続している(手持ちに4ピンソケットがなかったので5ピンソケットを利用)。
-
●● ソフトウェア ●●
【PIC-Base14】
PICはPIC16F18325使用し、LCD表示するためi2cLCD_ST7032i.c/.h(zip)ライブラリも利用。
MCCでは、EUSART(USB)、I2C、A2はinput、A4はoutputに設定。さらにSCK、SDA、A2はWPUでプルアップ指定。なお、eusart.cおよびeusart.h のプログラムの詳細はabc889を参照。
当初、「C言語&MCCによるPICプログラミング大全」(技術評論社、後閑哲也著)を参考に、MCCでgenarateした関数の利用を試みたが、何故か正常に動作しなかった(要検討)。
そこで、abc842を参考に、I2Cマスター通信プログラムを作成した。。

MCC画面 (マスターピン設定) |

MSSP1設定

EUSART1設定
|
- ★プログラム abc890_master.c(zip)(修正済)
- ※"stdlib.h"のインクルードが抜けていました(3/14追加)
/*************************************************
* キーデータ(I2C)取得プログラム
* LCD(ACM1602)+I2C Slave key
************************************************/
#include "mcc_generated_files/mcc.h"
#include "i2cLCD_ST7032i.h"
#include "stdlib.h"
//#define BFSIZE 20 //EUSART.Hで宣言
#define SLVADR 0x40
uint8_t iBuf[8];
uint8_t rBuf[BFSIZE];
uint8_t sBuf[BFSIZE];
uint8_t sFlg;
/*------ メイン関数 -----*/
void main(void)
{
uint16_t key = 0;
uint16_t keyLate = 0;
uint16_t rDt;
SYSTEM_Initialize();
LCD_init(); // LCD初期化
INTERRUPT_GlobalInterruptEnable();
INTERRUPT_PeripheralInterruptEnable();
puts("***ready\r");
LCD_str(">- ready");
IO_RA4_SetHigh();
while (1) {
if(sFlg){
LCD_clr();
LCD_str(rBuf);
rDt = atoi(rBuf);
//--- スレーブへ送信
if(rDt % 2){
I2C1_Write1ByteRegister(SLVADR,0,'H');
puts("> H\r" );
}else{
I2C1_Write1ByteRegister(SLVADR,0,'L');
puts("> L\r");
}
sFlg = 0;
}
//--- スレーブから受信
I2C1_ReadNBytes(SLVADR, &key, 2);
if(key){
if(key != keyLate){
sprintf(sBuf, "%04X\n\r", key);
LCD_cursor(0,1);
LCD_str(sBuf);
puts(sBuf);
keyLate = key;
}
}else{
keyLate = key;
}
}
}
|
【PIC-4x3_Key】
I2C-slaveのソフトは「C言語&MCCによるPICプログラミング大全」を参考に少しアレンジした。
インターフェースはUSBシリアルとI2Cがあるが、5V供給電源がぶつかるので同時使用はできない。USB接続は、キーが押されるたびに、(keyDatデータ送信をコメントにすると)パソコンに1文字を送信する。I2C接続は、(割り込みで)送信要求があれば、現在のキー状態を送信する。
なお、LEDは使用していない(受信したデータは読み捨て)。
- <送信データ>
- @ USB(USARTt)(1文字ずつ送信)
- '0'〜'9'、'.'、'\n' (テンキー配列時)、または、'0'〜'9'、'*'、'#' (電話機配列時)の12文字
- A I2C (2バイト16ビット。キーマトリクスデータで複数キーの同時押し込みも確認できる)
- 上位12ビット(x)は押されているキーマトリクス情報(押されているビットが1)
- 下位4ビットは押されているキーで最初のキー位置データ(d、1〜12)
- {xxxx xxxx xxxx dddd} ・・・(キーが押されていなければ、16ビットデータは0)

MCC画面 (スレーブピン設定) |

MSSP1設定

EUSART1設定
|
- ★プログラム abc890_slave.c(zip)(修正済み)
- ※ハンドラの設定部分が抜けていました(3/12追加)
/********************************
* keyデータ送信(I2Cスレーブ)
* Slave Address = 0x40
********************************/
#include "mcc_generated_files/mcc.h"
#define SCN_DELAY() __delay_ms(30)
#define KEY_DELAY() __delay_ms(500)
uint8_t wState; // I2C書込みステート番号
uint8_t rState; // I2C読込ステート番号
uint16_t rDat; // I2C受信16ビットデータ
uint8_t keyStat; // キー入力状態
uint16_t keyM; // キーマトリクスデータ
uint8_t keyP; // キーデータ(1−12)
uint16_t keyDat; // マトリクス+データ
uint8_t k[] = {'0','1','4','7',
'.','2','5','8',
'\r','3','6','9'}; // テンキー配列
/*
uint8_t k[] = {'*','7','4','1',
'0','8','5','2',
'#','9','6','3'}; // 電話機配列
*/
/***** I2C Read Callback ****************/
void I2C1_ReadProcess(void) {
switch (rState) { // ステートで進む
case 0:
rDat = (uint16_t)I2C1_Read();
rState++; // 1byte目読込、次へ
break;
case 1:
rDat |= (uint16_t)I2C1_Read() << 8;
rState = 0; // 2byte目読込、最初に
break;
default:
break;
}
}
/***** I2C Write Callback *****************/
void I2C1_WriteProcess(void) {
switch (wState) {
case 0:
I2C1_Write((uint8_t)keyDat);
wState++; // keyDatの下位送信、次へ
break;
case 1:
I2C1_Write(keyDat >> 8);
wState++; // keyDatの上位送信、次へ
break;
case 2: // 送信完了
wState = 0; // 最初に戻る
break;
default:
break;
}
}
/**** キースキャン ******/
uint16_t keyScan(){
uint8_t kt;
uint16_t kyw;
X_A0_SetLow(); // X scan
SCN_DELAY();
kyw = ~PORTC & 0x0F;
X_A0_SetHigh();
Y_A1_SetLow(); // Y scan
SCN_DELAY();
kt = ~PORTC & 0x0F;
kyw |= (uint16_t)kt << 4;
Y_A1_SetHigh();
Z_A2_SetLow(); // Z scan
SCN_DELAY();
kt = ~PORTC & 0x0F;
kyw |= (uint16_t)kt << 8;
Z_A2_SetHigh();
return kyw;
}
uint8_t bitCount(uint16_t w){
uint16_t wsft = 1;
uint8_t i;
for (i = 1; i < 13; i++){
if(w & wsft) return i;
wsft <<= 1;
}
return 0;
}
/***** メイン関数 ***************/
void main(void) {
SYSTEM_Initialize();
I2C1_Open(); // I2C1初期化
I2C1_SlaveSetReadIntHandler(I2C1_ReadProcess);
I2C1_SlaveSetWriteIntHandler(I2C1_WriteProcess);
INTERRUPT_GlobalInterruptEnable();
INTERRUPT_PeripheralInterruptEnable();
X_A0_SetHigh(); // キーピン初期化
Y_A1_SetHigh();
Z_A2_SetHigh();
puts("*** Ready ***\n\r");
while (1){
keyM = keyScan();
if(keyM){
keyP = bitCount(keyM);
keyDat = (keyM << 4)+(keyP & 0x0F);
if(keyStat == 0){
putch(k[keyP - 1]);
printf(" %04XH\n\r",keyDat);
}
keyStat = 1;
KEY_DELAY();
}else{
keyDat = 0;
keyStat = 0;
}
}
}
|
【実行例】
スレーブの4x3キーを押すと、マスターがそのデータを読取り、パソコンのテラターム端末に押された16ビットのキー情報を表示することができた。
- マスターでリアルタイムキーデータを利用する時は、常時受信している 変数key が使える。
- キー位置とデータの変換は、slaveの配列によるキーデータ変換を参照。

キー入力実行例(4x3キーデータ表示) |

テラターム画面(I2C送受信表示例)
|
※ 本レポートの参考・利用は、あくまでも自己責任でお願いします。