だが,自分の大切な記録として残しておく。
設計仕様
- RA1とRB3に接続した押しボタンスイッチで,PICの動作を変えたりできるようにする。
- とりあえずテストのため,ボタンが押された状況をUART(printf)で送信。
- ボタンは「オフトリガー」すなわちある程度押され,離した時に処理を開始する。
- [RA1] 単独,[RB3] 単独,[RA1] と [RB3] の同時押し,以上3つを判定する。
オフトリガーで同時押しも実装しようとしたのは,micro:bitが良い動きだったから。
ボタンで割り込みがかかるとかっこいいのだが,難しそうなので諦め,mainループ内で判定することにした。
/**
Section: Included Files
*/
#include "mcc_generated_files/system.h"
#include "mcc_generated_files/mcc.h"
#include <stdio.h>
/*
Main application
*/
unsigned long int GLOBAL_TIME = 0;
unsigned long int NEXT_TIME = 0;
char RECEIVED_CHAR = ' ';
char prev_key_state = 3;
char current_key_state = 3;
char key_data = 3;
char pressed_key = 3;
char KEY_STATE = 0;
void My_TMR1_ISR(void)
{
GLOBAL_TIME++;
current_key_state = ((_RA1)<<1)|(_RB3);
if (GLOBAL_TIME>NEXT_TIME) {
// printf("Interrupted at %lu.\n",NEXT_TIME);
NEXT_TIME=NEXT_TIME+100; // means 1 sec
// printf("RA1 state:%d\n",_RA1);
// printf("RB3 state:%d\n",_RB3);
// printf("current_key_state = %d.\n",current_key_state);
}
switch(KEY_STATE) {
case 0:
if (current_key_state != prev_key_state) {
KEY_STATE=1;
prev_key_state=current_key_state;
}
break;
case 1:
case 2:
if (current_key_state == prev_key_state) {
KEY_STATE++;
} else {
KEY_STATE=0;
}
break;
}
}
int main(void)
{
// initialize the device
SYSTEM_Initialize();
TMR1_SetInterruptHandler(My_TMR1_ISR);
NEXT_TIME=100;
// TMR1_Start();
while (1) {
// test code
_LATA0=(_RA1)*(_RB3); // means LED=ON when RA1 and/or RB3 are pressed
// UART RX
if (UART1_IsRxReady()) {
RECEIVED_CHAR=UART1_Read();
printf("%c was received at %lu.\n",RECEIVED_CHAR,GLOBAL_TIME);
// printf(" -->> current_key_state = %d.\n",current_key_state);
// printf(" -->> prev_key_state = %d.\n",prev_key_state);
// printf(" -->> SW_STATE = %d.\n",KEY_STATE);
}
// KEY routine
if (KEY_STATE==3) {
key_data=current_key_state;
KEY_STATE=0; // means clear
// printf("key_data = %d.\n",key_data);
if (key_data==3) {
switch (pressed_key) {
case 3:
break;
case 1:
printf("RA1 pressed.¥n");
// RA1 program
pressed_key=3;
break;
case 2:
printf("RB3 pressed.¥n");
// RB3 program
pressed_key=3;
break;
case 0:
printf("Both RA1 and RB3 pressed.¥n");
// RA1 and RB3 program
pressed_key=3;
break;
}
} else {
pressed_key = pressed_key & key_data;
}
}
}
return 1;
}
|
いわゆる「チャタリング処理」を施している。いろいろ試行した結果,20msecとした。タイマーを用いているが,のちのち間違えそうなので,タイマーそのものは10msecごと。3回読んで(つまり20msec間)スイッチの状態が同じなら,チャタリングではないと判定した。
それでも,「同時押し」では,例えば [RA1] 押した -> さらに[RB3] 押した と離散的なデータが取れてしまう。考えた末,やはりオフトリガー,すなわちスイッチが1個,または2個完全に離された状態を判定して,そこまで片方しか押されなかったのか,同時押しだったのかを覚えておくようにした。最後の方の pressed_key = pressed_key & key_data;
スイッチが2個だけなので,単純にビット操作を使うとうまくいった。
0 件のコメント:
コメントを投稿