08 ソースコード3 ボタン処理
ソースコードをみたいと思います.
BlueLabをインストールすると、tutorialフォルダができています.
その中のPIOにボタンをつけてボタンの動作を検知するソースコードをみてみます.
C:\BlueLab41\apps\tutorials\buttons\part1
う~ん、イベントドリブンプルグラムは難しいです.
関数がどんなイベントを返してくるのかが様々なので、習得するのが難しいです.
#include <pio.h>
ボタンを取りつけるPIOを使うためのインクルードファイルです.
#include <stdio.h>
PCのデバッガにイベント情報を表示しますので、printf()を使うのでインクルードします.
#include <message.h>
イベントドリブンプルグラムのためのインクルードファイルです.
#define BUTTON_A (1 << 0) /* PIO0 is BUTTON_A */
#define BUTTON_B (1 << 1) /* PIO1 is BUTTON_B */
#define BUTTON_C (1 << 2) /* PIO2 is BUTTON_C */
#define BUTTON_D (1 << 3) /* PIO3 is BUTTON_D */
ボタンの割り当てです.以降で、ボタンCとボタンDを使います.
typedef struct
{
TaskData task; /* task is required for messages to be delivered */
} appState;
イベントハンドラをこれにひもづけします.なんでわざわざappStateというtypedefをするかはわかりません.
appState app;
appという実体を割り当てて、appにイベントハンドラをひもづけします.
static void app_handler(Task task, MessageId id, Message message);
static void handle_pio(Task task, MessagePioChanged *pio);
プロトタイプ宣言です.あとで説明します.
int main(void)
{
app.task.handler = app_handler;
appに、イベントハンドラapp_handler()をひもづけます
MessagePioTask(&app.task);
MESSAGE_PIO_CHANGEDというイベントが発生したときに、どのイベントハンドラを起動するかと指定する関数らしいです.
結果として、MESSAGE_PIO_CHANGED → app_handler()起動 というひもづけをしたことにしているんだと思います.
MessagePioTask()はmessage.hで定義されています.
PioDebounce(BUTTON_C | BUTTON_D, 2, 20); /* 2 reads and 20ms between them */
ボタンCとボタンDを監視します.
そして、スイッチのチャタリング防止のため、20mSec間隔で2度読みします.
そして、MESSAGE_PIO_CHANGED を発生させます.
結果として、ボタンCDが押される → MESSAGE_PIO_CHANGED → app_handler()起動 となります.
PoiDeBounce()はpio.hで定義されています.
MessageLoop();
イベント処理の永久ループと思われます.
return 0;
どこへリターンするのかは知りません.
}
static void app_handler(Task task, MessageId id, Message message) {
switch (id) {
case MESSAGE_PIO_CHANGED: handle_pio(task, (MessagePioChanged*)message); break;
default: printf("Unhandled message 0x%x\n", id);
}
}
引数taskはhandle_pioへ渡していますが、handle_pioではtaskを使っていません.
引数id = MESSAGE_PIO_CHANGED なら、handle_pioをコールして、ボタンが押されたと表示します.
ちがうイベントだったら、知らないメッセージだと表示します.
static void handle_pio(Task task, MessagePioChanged *pio) {
if (pio->state & BUTTON_C) printf("Button C pressed\n");
if (pio->state & BUTTON_D) printf("Button D pressed\n");
}
ボタンが押されたと表示しているわけですが、MessagePioChangedという構造体がどうなっているのかがわからないと理解できませんねー.
messagePioChangedは、system_message.h の中で定義されています.
typedef struct {
uint16 state; PIO0~PIO15のどれが変化したのかを表すフラグです.
uint32 time; PIOが変化した時刻です.そんな情報が来るとはすごいな.
uint16 state16to31; PIO16~PIO31のどれが変化したのかを表すフラグです.いま使っているBlueToothモジュールはPIO11までなのでこのフラグは無用のフラグです.
} MessagePioChanged;