Raspberry Pi Picoでプログラミング ⑰ gpioファンクション MASK
gpioファンクションの中にmask関連があります。どういう機能なのか確認しました。
●MASK関連gpioファンクション
ファンクション | 要約 |
---|---|
void gpio_set_outover (uint gpio, uint value) |
GPIO出力イネーブル・オーバライドを選択。 gpio_overrideの情報の記載はない |
void gpio_set_inover (uint gpio, uint value) |
GPIO入力オーバライドを選択。 gpio_overrideの情報の記載はない |
void gpio_set_oeover (uint gpio, uint value) |
GPIO出力イネーブル・オーバライドを選択。 gpio_overrideの情報の記載はない |
void gpio_init_mask (uint gpio_mask) | 指定した複数のgpio番号を初期化(I/Oを有効にし、funcをGPIO_FUNC_SIOに設定)。出力イネーブルをクリア(入力に設定)、すべての出力値をクリア |
static void gpio_set_mask (uint32_t mask) | マスク(0~29)に現れるすべてのGPIOをHighにドライブ |
static void gpio_clr_mask (uint32_t mask) | マスク(0~29)をクリア(Low)する |
static void gpio_xor_mask (uint32_t mask) | マスクに表示されるすべてのGPIOを切り替え。ビットマスクをマスクする |
static void gpio_put_masked (uint32_t mask, uint32_t value) | マスクされたビットをHigh/Lowで駆動する |
static void gpio_set_dir_out_masked (uint32_t mask) | 「マスク」内のすべてのGPIOを出力に切り替える。ビット0〜29として、出力に設定するGPIOのビットをマスクする |
static void gpio_set_dir_in_masked (uint32_t mask) | ビット0〜29として、入力に設定するGPIOのビットをマスクする |
static void gpio_set_dir_masked (uint32_t mask, uint32_t value) |
複数のGPIO方向を設定する。マスクされた以外のビットは不変。 例;gpio_set_dir_masked(0x3, 0x2); |
Raspberry Pi Pico C/C++ SDKにあるサンプルのhello_7segment.cの中から、MASK部分をピックアップしました。
●セグメント・データの準備
int bits[10] = { 0x3f, // 0 0b00111111 0x06, // 1 0b00000110 0x5b, // 2 0b01011011 0x4f, // 3 0x66, // 4 0x6d, // 5 0x7d, // 6 0x07, // 7 0x7f, // 8 0x67 // 9 }; |
数字の1は、bとcのセグメントが光ります。上記のデータに当てはめると、
dot g f e d c b a
というデータの並びであることがわかります。
この後、データを加工しています。
// Our bitmap above has a bit set where we need an LED on, BUT, we are pulling low to light
// 上記のビットマップには、LEDをONにする必要があるビット・セットだが、実際はLowに引き下げると光る
// so invert our output
// だから出力を反転する(ここは1ビットずつの処理部分)
gpio_set_outover(gpio, GPIO_OVERRIDE_INVERT);
したがって、'1' 0b00000110は、0b11111001に変換されました。
マスクを使うところです。
FIRST_GPIOはGP2です。GP2が'a'セグメントに配線されているので、データを2だけシフトさせます。
// We are starting with GPIO 2, our bitmap starts at bit 0 so shift to start at 2
// GPIO 2から始める。ビットマップはビット0から始まるので、シフトして2から始める
// (FIRST_GPIOはGP2ピンで、セグメントaに配線されている)
// (valは表示する数値の数字)
int32_t mask = bits[val] << FIRST_GPIO;
// Set all our GPIO's in one go!
// すべてのGPIOを一度に設定する
// If something else is using GPIO, we might want to use gpio_put_masked()
// ほかの何かがGPIOを使用している場合は、gpio_put_masked()を使用することを勧める
gpio_set_mask(mask); // マスクのビットを全部Highにする
sleep_ms(250);
gpio_clr_mask(mask); // マスクのビットを全部Lowにする
8ビットのデータを一気に出力できることがわかりました。
●実験回路
GP2に赤色LED、GP3に緑色LED、GP4に青色LEDを抵抗を介してつなげます。それぞれの端子をHighにすれば、LEDが点灯します。
回路図です。
プログラムです。マスクは32ビット整数です。GP0がLSBになります。ここでは8ビットだけを指定しています。
maskRGB =0b00101100; 右端がGP0なので、GP2、GP3、GP5を'1'にしたマスクを作ります。gpio_init_mask(maskRGB);で初期化し、 gpio_set_dir_out_masked(maskRGB); 3本まとめて出力に指定します。
ループの最初で、GP2=赤色LEDだけを'1'にしたマスクを作り、gpio_set_mask(maskRGB);で'1'が立っているところをHighにします。したがって、赤色LEDだけが点灯します。250ms後に消灯します。
したがって、赤色、緑色、青色、と順に点灯をします。
このように、MASKは、すべてのGPIOを同時にON/OFFできる機能だといえます。
#include "pico/stdlib.h"
#include <stdio.h>
int main() {
stdio_init_all();
printf("Hello, RGB LED\n");
int32_t maskRGB =0b00101100; // GP7 GP6 GP5 GP4 GP3 GP2 GP1 GP0
gpio_init_mask(maskRGB);
gpio_set_dir_out_masked(maskRGB);
while(1){
maskRGB =0b00000100;
gpio_set_mask(maskRGB);
sleep_ms(250);
gpio_clr_mask(maskRGB);
sleep_ms(250);
maskRGB =0b00001000;
gpio_set_mask(maskRGB);
sleep_ms(250);
gpio_clr_mask(maskRGB);
sleep_ms(250);
maskRGB =0b00100000;
gpio_set_mask(maskRGB);
sleep_ms(250);
gpio_clr_mask(maskRGB);
sleep_ms(250);
}
return 0;
}
gpio_set_dir_maskedは、入出力を任意のタイミングで一気に変更できるので、ハードの設計をしっかりとしないと、大きな電流を流し、トラブルの原因になります。