Windows IoT CoreのSPI通信APIでLチカ
How to use MCP23S08(SPI-GPIO expander) for Windows IoT Core
前回は
I2C方式のIOエキスパンダーのWindows IoT Coreプログラミングを紹介しましたが、今回はSPI方式のIOエキスパンダー(MCP23S08)の使用例を紹介したいと思います。
ブレッドボードによる配線図と、写真によるイメージはこちらの通りです。Raspberry PiのSPI0ピンから出力される信号によって、上半分の右8ピンで入出力を拡張することができます。
続いてプログラミング。Windows IoT CoreにはSPI通信のためのAPIも用意されているので、これを使ってみます。このICではGPIO出力は3バイト単位で信号を送信することで操作が行えます。はじめの1バイトは操作コード(書き込みモードなら0x40、読み込みモードなら0x41。いずれもハードウェア操作の信号はなし)、次のバイトはレジスタアドレス(GPIOなら0x09)、最後のバイトはオン・オフのビット配列となります。今回は単純なGPIO操作なので、はじめに「0x40, 0x00, 0x00」の信号を送信することで、すべてのピンを出力モードとして初期化しています。
以上を踏まえたソースコードがこちらになります。今回も同様にバックグラウンドで動作し、4つのLEDがランダムで点灯します。
spiapi.cs
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using Windows.ApplicationModel.Background;
using Windows.Devices.Enumeration;
using Windows.Devices.Spi;
namespace SpiApiTest
{
public sealed class StartupTask : IBackgroundTask
{
private BackgroundTaskDeferral deferral;
private SpiDevice SPIAccel;
private byte[] sendbytes = new byte[] { 0x40, 0x09, 0x00 };
private void SendGpio(byte bits)
{
sendbytes[2] = bits;
SPIAccel.Write(sendbytes);
}
private void SendCommand(params byte[] args)
{
SPIAccel.Write(args);
}
private async void Start()
{
try {
var settings = new SpiConnectionSettings(0);
settings.ClockFrequency = 5000000;
settings.Mode = SpiMode.Mode0;
string aqs = SpiDevice.GetDeviceSelector("SPI0");
var dis = await DeviceInformation.FindAllAsync(aqs);
SPIAccel = await SpiDevice.FromIdAsync(dis[0].Id, settings);
if (SPIAccel == null) {
Debug.WriteLine(string.Format(
"SPI Controller {0} is currently in use by " +
"another application. Please ensure that no other applications are using SPI.",
dis[0].Id));
return;
}
SendCommand(0x40, 0x00, 0x00);
Random r = new Random();
while (true) {
byte bits = 0x0;
for (int i = 0; i < 4; i++) {
if (r.Next(0, 2) == 1) bits |= (byte)(1 << i);
}
SendGpio(bits);
await Task.Delay(500);
}
} catch (Exception ex) {
Debug.WriteLine("SPI Initialization failed. Exception: " + ex.Message);
}
}
public void Run(IBackgroundTaskInstance taskInstance)
{
deferral = taskInstance.GetDeferral();
Start();
}
}
}
2016/10/06