RaspberryPi[19] GPIO割込み
GIPOから入力されるパルスをカウントしてみます。wiringPiISRを使用しました。この関数はBOTH 、 FALLING、RISINGの3種類でエッジ割り込みをかけるようですが、立ち上がり、立ち上がりともキレイに取り込めないので、BOTHを選択してIOの状態で立上がりと立下りを判別してます。チャタリングを防止するために、一回割り込みが入ったら、usleepで止めてます。本来なら一定時間割り込み禁止を設定するほうが良いと思うのでそのうち直します。
#include <stdio.h>
#include <sys/time.h>
#include <wiringPi.h>
#include <unistd.h>
// Which GPIO pin we're using
#define PIN_OPT 2
#define PIN_ROT 3
// How much time a change must be since the last in order to count as a change
#define IGNORE_CHANGE_BELOW_USEC 10000 //10msec
// Current state of the pin
static volatile int state_opt;
static volatile int state_rot;
// Time of last change
struct timeval last_change_dwn_cnt_opt;
struct timeval last_change_dwn_cnt_rot;
static volatile int dwn_cnt_opt = 0;
static volatile int dwn_cnt_rot = 0;
static volatile int up_cnt_opt = 0;
static volatile int up_cnt_rot = 0;
// Handler for interrupt
void dwn_cnter_opt(void) {
if((state_opt = digitalRead(PIN_OPT))==0){
dwn_cnt_opt++;
}else{
up_cnt_opt++;
}
// printf("dwn_c:%d up_c:%d\n",dwn_cnt_opt,up_cnt_opt);
usleep(IGNORE_CHANGE_BELOW_USEC);
}
void dwn_cnter_rot(void) {
if((state_rot = digitalRead(PIN_ROT))==0){
dwn_cnt_rot++;
}else{
up_cnt_rot++;
}
// printf("dwn_c:%d up_c:%d\n",dwn_cnt_opt,up_cnt_opt);
usleep(IGNORE_CHANGE_BELOW_USEC);
}
int main(void) {
// Init
wiringPiSetup();
// Set pin to output in case it's not
pinMode(PIN_OPT, INPUT);
pinMode(PIN_ROT, INPUT);
// Bind to interrupt
wiringPiISR(PIN_OPT, INT_EDGE_BOTH, &dwn_cnter_opt); // BOTH or FALLING or RISING
wiringPiISR(PIN_ROT, INT_EDGE_BOTH, &dwn_cnter_rot); // BOTH or FALLING or RISING
// Get initial state of pin
state_opt = digitalRead(PIN_OPT);
state_rot = digitalRead(PIN_ROT);
printf("state_opt:%d state_rot:%d\n",state_opt,state_rot);
// Waste time but not CPU
for (;;) {
sleep(1);
printf("dwn_cnt_opt:%d up_cnt_opt:%d dwn_cnt_rot:%d up_cnt_rot:%d\n",dwn_cnt_opt,up_cnt_opt,dwn_cnt_rot,up_cnt_rot);
}
}