操控SBC上的IO接口

From BananaPro/Pi
Revision as of 14:19, 14 August 2016 by FuzzyBot (Talk | contribs) (Updating to match new version of source page)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search
Other languages:
English • ‎中文(简体)‎

Description

Most LeMaker SBCs boards (Banana Pi/Pro, LeMaker Guitar Base Board Rev.B) has some IO ports on the boards, including GPIO, PWM, SPI, I2C, UART, etc.. In fact, the 40 Pins on Banana Pro (BananaPro/Pi:Pin definition) and LeMaker Guitar Base Board Rev.B (LeMaker_Guitar:Pin_Definition_on_Base_Board) are fully compatible with almost the same Pin definitions. Via the basic way, we can control the digital IO ports input or output from the sys user space. But if we want to use more complex interface such as SPI or I2C, it is not that easy to achieve. Thus we have provided two GPIO libraries to use: WiringLMK and LMK.GPIO, offering various API to easily control the IO on the SBC boards. Currently, both the WiringLMK C library and the LMK.GPIO Python library support Banana Pro and LeMaker Guitar. In the following, we will introduce you how to use these libraries with different numbering scheme. Note, WiringLMK and LMK.GPIO has its own different numbering scheme for the Pin definitions (#Appendix: 40 Pins GPIO Mapping Table for Banana Pro and LeMaker Guitar).

在开始所有的工作之前,当核对管脚表时,我们最好清楚的知道Banana Pro和LeMaker Guitar板上的物理引脚的物理编号表。当我们调用WiringLMK库中的wiringPiSetupPhys()函数,或使用LMK.GPIO中LMK.GPIO.BOARD的定义,例如定义PIN = 8将返回板上的物理管脚8sys定义表示每个板子的sys用户空间访问方法。当我们使用WiringLMK库中的wiringPiSetupGpio()wiringPiSetupSys()函数,或LMK.GPIO中LMK.GPIO.BCM定义,它们将会返回BCM Chip Serial Number表,例如,定义PIN = 8,将会返回板子的物理管脚24。WiringLMK也有它自己的定义,当我使用WiringLMK中的wiringPiSetup()函数,例如定义PIN = 8,将会返回板子的物理管脚3

安装

WiringLMK,请参考:https://github.com/LeMaker/WiringLMK
LMK.GPIO,请参考:https://github.com/LeMaker/LMK.GPIO


编译

WiringLMK C 库

在使用WiringLMK GPIO前, 你需要在程序中包含这个头文件: #include <wiringPi.h>。你也需要根据你使用的不同模块添加更多的#include行。 使用WiringLMK库编译程序, 必须添加库路径

 -I/usr/local/include -L/usr/local/lib -lwiringPi

编译程序依赖于运行的环境,一般的需要这三个动态链接库:-lwiringPi, -lwiringPiDev, or -lpthread

LMK.GPIO Python库

Python语言不需要编译,但是需要在程序的开头添加 import LMK.GPIO

IO输入输出

使用sysfs用户空间

利用sysfs可以从用户空间访问GPIO引脚

GPIO A: GPIOA*NUMBER* = 0 + *NUMBER*, for example, GPIOA27 = 0+27 = 27
GPIO B: GPIOB*NUMBER* = 32 + *NUMBER*, for example, GPIOB31 = 32+31 = 63
GPIO C: GPIOC*NUMBER* = 64 + *NUMBER*, for example, GPIOC0 = 64+0 = 64
GPIO D: GPIOD*NUMBER* = 96 + *NUMBER*, for example, GPIOD3 = 96+3 = 99
GPIO E: GPIOE*NUMBER* = 128 + *NUMBER*, for example, GPIOE22 = 128+22 = 150

你可查看#附录:Banana Pro和LeMaker Guitar 40 Pins GPIO映射表取得sys引脚编号。
访问 GPIO引脚,如 GPIOB19 (32+19 = 51),你首先需要使用下面命令export

$ echo XX > /sys/class/gpio/export

XX是引脚的编号索引,这里XX = 51。如果操作成功,你可以查看sys文件系统节点信息。

$ ls
#! /sys/class/gpio/gpioXX is generated

使用下面的命令,设置GPIO的方向为输出。

$ echo out > /sys/class/gpio/gpioXX/direction

使用下面的命令,设置GPIO的方向为输入

$ echo in > /sys/class/gpio/gpioXX/direction


使用下面的命令,读取GPIO的值 /sys/class/gpio/gpioXX/value

$ cat /sys/class/gpio/gpioXX/value

当方向设置为输出, 你可写入10到GPIO引脚 /sys/class/gpio/gpioXX/value

$ echo 1 /sys/class/gpio/gpioXX/value

使用WiringLMK C语言

第一步总是初始化wiringLMK,并且假设程序将要使用wiringLMK管脚表,这里的物理管脚模式是通过使用该函数指定。

int wiringPiSetupPhys (void)

这意味着调用程序使用板上的引脚为其物理编号表。 设置GPIO引脚输入/输出,你必须使用函数改变引脚的模式。

void pinMode (int pin, int mode);

int mode可以设置为INPUTOUTPUTPWM_OUTPUTGPIO_CLOCK。 你可以使用函数读取通过他的物理编号索引int pin读取GPIO的值

int digitalRead (int pin) ;

当GPIO的方向设置为输出,你可以通过用调用函数配置HIGHLOW (10)来修改GPIO的值。

void digitalWrite (int pin, int value) ;

当GPIO的方向设置为输入,你可以使用下面的函数设置它为拉低或拉高寄存器模式

void pullUpDnControl (int pin, int pud) ;

根据程序的实际需要,配置int pudPUD_OFF(非拉低/高),PUD_UP(拉高到VCC 3.3V)或PUD_DOWN(拉低到GND)。

一个“Hello World”例子,演示LED闪烁:

#include <wiringPi.h>
int main (void)
{
  wiringPiSetupPhys () ;
  pinMode (11, OUTPUT) ;
  for (;;)
  {
    digitalWrite (11, HIGH) ; delay (500) ;
    digitalWrite (11,  LOW) ; delay (500) ;
  }
  return 0 ;
}

使用LMK.GPIO Python语言

类似地,你也必须设置SBC IO库的引脚模式;对应LMK.GPIO,使用下面函数定义引脚编号表

GPIO.setmode(GPIO.BOARD)

这意味着调用程序使用板上的引脚作为其物理编号表。 使用下面函数,设置GPIO的引脚输入输出方向

GPIO.setup(int pin, int mode)

其中,int mode可以被设置为GPIO.INGPIO.OUT. 你可以使用下面的函数通过物理编号索引读取GPIO的值

GPIO.input(int pin)

当GPIO的方向设置为输出,你可以使用下面的函数设置int valueGPIO.HIGHGPIO.LOW (10TrueFalse)来修改GPIO的值。

GPIO.output(int pin, int value)

你可通过指定第三个参数int pud来设置引脚的拉高/拉低寄存器模式。

GPIO.setup(int pin, GPIO.IN, int pud)

GPIO.PUD_OFF(非拉高/低),code>GPIO.PUD_UP</code>(拉高到 VCC 3.3V),或 GPIO.PUD_DOWN(拉低到GND)。
一个“Hello World”例子,演示怎样使LED闪烁。

#!/usr/bin/env python
import LMK.GPIO as GPIO
import time
#LED Mode BOARD
PIN_NUM = 7
GPIO.setmode(GPIO.BOARD)
while True:
	try:
		GPIO.setup(PIN_NUM, GPIO.OUT)
	except:
		print("Failed to setup GPIO %d", PIN_NUM)
GPIO.output(PIN_NUM, True)
	time.sleep(0.5)
	GPIO.output(PIN_NUM, False)
        time.sleep(0.5)


中断

使用WiringLMK C语言

在设置中断引脚之前,你必须先设置拉高或拉低寄存器的模式。

void pullUpDnControl (int pin, int pud) ;

通过下面的函数指定终端函数

int wiringPiISR (int pin, int edge, void (*function)(void)) ;

int edge 可以被设置为INT_EDGE_RISING, INT_EDGE_FALLING,或INT_EDGE_BOTH</codehe third。第三个参数是中断处理函数,下面的例子展示中断是如何工作的。

#include <stdio.h>
#include <wiringPi.h>
void myInterrupt (void) { printf("The Physical Pin 16 is detected...\n"); }
 
int main(int argc, char **argv)
{
	wiringPiSetupPhys();
	pullUpDnControl(16, 1);
	wiringPiISR (16, INT_EDGE_FALLING, &myInterrupt) ;	
 
	while(1)
	{
		delay (100) ;		//mS
	}
}

使用LMK.GPIO Python语言

中断被当作是事件,第二个参数可以是:<code> GPIO.RISINGGPIO.FALLINGGPIO.BOTH

GPIO.add_event_detect(unsigned int pin, unsigned int edge,callback = void (*func_my_callback), unsigned int bouncetime)

第三个参数是中断回调函数,下面的例子展示中断时如何工作的。

#!/usr/bin/env python
import LMK.GPIO as GPIO
import time
PIN_NUM = 24
GPIO.setmode(GPIO.BOARD)
GPIO.setup(PIN_NUM,GPIO.IN,GPIO.PUD_UP)
def my_callback(channel):
	print "The value of Pin %d is %d" %(PIN_NUM,GPIO.input(PIN_NUM))
	print "Callback trigger %d" %channel
	print "Now value of the Pin is %d" %(GPIO.input(PIN_NUM))
GPIO.add_event_detect(PIN_NUM,GPIO.RISING,callback = my_callback,bouncetime = 200)
try:
    while True:
	time.sleep(0.1)
except KeyboardInterrupt:
    GPIO.remove_event_detect(PIN_NUM)
GPIO.cleanup()


PWM

WiringLMK C语言

WiringLMK包含了一个可以在任何GPIO引脚产生PWM信号的软件驱动PWM处理程序。这里没有测试过最小的脉宽信号,但是对应控制灯和LED是非常容易的。程序代码添加头文件#include <softPwm.h>和其他的头文件,还有编译时需要的链接库-lwiringPi -lpthread。 下面函数创建一个软件控制PWM引脚,建配置下面函数的第二个参数int pwmRange为100。

int softPwmCreate (int pin, int initialValue, int pwmRange) ;

使用下面的函数,更新已初始化的软PWM引脚的值

void softPwmWrite (int pin, int value) ;

以下是一个软PWM如何工作的例子

#include <stdio.h>
#include <wiringPi.h>
#include <softPwm.h>
#define RANGE		100
#define PIN		3
int main ()
{
	wiringPiSetupPhys()  ;
softPwmCreate (PIN, 0, RANGE) ;
	printf ("GPIOE3, %3d, %3d\n", 0, RANGE) ;
	softPwmWrite (PIN, 50) ;
	while(1);
}

使用LMK.GPIO Python语言

LMK.GPIO也支持软件驱动PWM功能并且能够十分简单的设置引脚。创建一个软件控制引脚,使用下面的函数设置第二个参数int frequency的值为100。

p = GPIO.PWM(int pin, int frequency)

.start(int initialValue)指定软PWM的值, 使用.stop()函数停止。使用.ChangeDutyCycle(int dutyCycle)函数设置占空比。 以下是一个使用LMK.GPIO软件PWM的例子。

#/usr/bin/env python
import LMK.GPIO as GPIO
import time
PIN_NUM = 11
frequency = 50
GPIO.setmode(GPIO.BOARD)
GPIO.setup(PIN_NUM,GPIO.OUT)
p = GPIO.PWM(PIN_NUM,frequency)
p.start(0)
raw_input("Press Enter to stop:")
p.stop()
GPIO.cleanup()


I2C总线

使用WiringLMK C语言

WiringLMK包含了访问I2C的函数。Banana Pro和LeMaker Guitar都会默认加载I2C驱动程序。使用I2函数,需要添加 头文件:

#include <wiringPiI2C.h>

程序编译过程中,需要链接库文件-lwiringPi。我们可以用标准的系统命令检查I2C设备,例如i2cdetect

i2cdetect -y 2 # Banana Pro and LeMaker Guitar

检测I2C在总线上的地址,简单的读写操作,不需要任何寄存器转换,然而其它的操作需要使用下面的函数设置寄存器。

int wiringPiI2CSetup (int devID) ;

使用下面的函数初始化I2C总线上的设备。

int wiringPiI2CRead (int fd) ; 
int wiringPiI2CReadReg8 (int fd, int reg) ;
int wiringPiI2CReadReg16 (int fd, int reg) ;
int wiringPiI2CWrite (int fd, int data) ;
int wiringPiI2CWriteReg8 (int fd, int reg, int data) ;
int wiringPiI2CWriteReg16 (int fd, int reg, int data) ;

例子1:控制MCP23017

MCP23017扩展板上有许多的接口,这使得它更方便使用。源程序中要包含#include <mcp23017.h>头文件,以下是设置MCP23017的函数。

int mcp23017Setup (int pinBase, int i2cAddress) ;

int pinBase可以任何大于64的数字,i2cAddress是I2C总线设备的地址。用不同的int pinBase,这个函数可以被调用多次。可以使用i2cdetect命令检测I2C总线设备来获取设备的地址。下面是一个demo程序。

#include <stdio.h>
#include <wiringPi.h>
#include <mcp23017.h>
#define	LED		1
#define	pinBASE	100
int main (void)
{
  wiringPiSetup () ; // Enable the on-goard GPIO
  mcp23017Setup (pinBASE, 0x24) ; // 初始化mcp23017
  pinMode (LED, OUTPUT) ;
  pinMode (pinBASE + 0, OUTPUT) ; // 闪烁板上的LED灯和mcp23017上的LED灯
for (;;)
  {
    digitalWrite (LED,          HIGH) ;
    digitalWrite (pinBASE + 0, HIGH) ;
    delay (500) ;
    digitalWrite (LED,          LOW) ;
    digitalWrite (pinBASE + 0, LOW) ;
    delay (500) ;
  }
  return 0 ;
}

例子2:控制PCF8591(模拟)

另一个被支持的扩展模块是PCF8591模拟IO扩展IC。PCF8591有一个4通道,8位 模拟输入接口和一个单通道模拟输出接口。PCF8591有一个3位地址选择接口,它允许做多有PCF8591链接到SBC上。源程序中要包含头文件#include <pcf8591.h>。下面是设置 PCF8591的函数。

int pcf8591Setup (int pinBase, int i2cAddress) ;

int pinBase也可以是任何大于64的数字,i2cAddress是I2C总线傻瓜的设备的地址。用不同的int pinBase,这个函数可以被调用多次。 可以使用i2cdetect获取正确的设备地址。下面是一个demo程序。

#include <stdio.h>
#include <wiringPi.h>
#include <pcf8591.h>
#define	LED		1
#define pinBASE       120
int main (void)
{
  int value, pin ;
  wiringPiSetup () ; //使能板上的GPIO
  pinMode (LED, OUTPUT) ; //板上LED
  pcf8591Setup (pinBASE, 0x48) ; // 初始化pcf8591
for (;;)
  {
    for (pin = 0 ; pin < 4 ; ++pin)
    {
      value = analogRead  (pinBASE + pin) ;
      printf ("  %5.2f  ", (double)value * 3.3 / 255.0) ;
    }
    printf ("\r") ; fflush (stdout) ;
delay (100) ;
    digitalWrite (LED, !digitalRead (LED)) ; // 闪烁LED灯
  }
  return 0 ;
}

Use Python语言

LMK.GPIO没有SPI或I2C接口函数,因此需要安装另外一个Python 库smbus

$ sudo apt-get install smbus

在程序开始位置就输入这个python库

import smbus
Bus = smbus.SMBus(2) # smbus 2 for Banana Pro and LeMaker Guitar
Bus.write_byte_data(Address, Reg, Value) # I2C总线地址
Value = Bus.read_byte_data(Address, Reg) # 操作寄存器

例子:控制MCP23017

更多寄存器配置和用法,请参考MCP23017 datasheet。以下是一个简单的配置LN_USB_HUB扩展板的demo。

import smbus
Bus = smbus.SMBus(2) # smbus 2 for Banana Pro and LeMaker Guitar
try:
        Bus.write_byte_data(0x24, 0x00, 0xFF)
        Bus.write_byte_data(0x24, 0x01, 0xFF)
        Bus.write_byte_data(0x24, 0x12, 0x55)
        Bus.write_byte_data(0x24, 0x12, 0x00)
Bus.write_byte_data(0x26, 0x00, 0xFF)
        Bus.write_byte_data(0x26, 0x01, 0xFF)
        Bus.write_byte_data(0x26, 0x12, 0x55)
        Bus.write_byte_data(0x26, 0x12, 0x00)
except:
        print("I2C error")
Address = [0x24, 0x26]
for Addr in Address:
        try:
            Bus.write_byte_data(Addr, 0x00, 0x00)
            Bus.write_byte_data(Addr, 0x01, 0x00)
            Bus.write_byte_data(Addr, 0x0A, 0x00)
        except:
            print (str(Addr) + " not availible.")
Addr = "24"
Bank = "A"
Binary = "01010101"
Binary = int(Binary, 2)
if Bank.upper() == "A":
        Bus.write_byte_data(int("0x"+Addr, 16), 0x12, Binary)
        Bus.write_byte_data(int("0x"+Addr, 16), 0x09, Binary)
elif Bank.upper() == "B":
        Bus.write_byte_data(int("0x"+Addr, 16), 0x13, Binary)
        Bus.write_byte_data(int("0x"+Addr, 16), 0x19, Binary)
else:
        print("Incorrect Bank.")


SPI总线

使用WiringLMK C语言

WiringLMK提供来了访问SPI接口的函数,Banana Pro默认不加载SPI驱动到内核,但是LeMaker Guitar得SPI是可用的。Banana Pro要使用SPI接口,必须加载spi-sun7ispidev驱动模块到/etc/modules中

$ sudo nano /etc/modules

添加SPI接口头文件

#include <mcp23s17.h>

打开SPI设备,设置的通道的函数如下:

int wiringPiSPISetup (int channel, int speed) ;

初始化SPI设备的函数如下:

int wiringPiSPIDataRW (int channel, unsigned char *data, int len) ;

同过SPI总线可以全双工读写数据块。

例子1: 控制MCP23s17

WiringLMK库有MCP23s17的接口函数,源程序中要添加头文件:#include <mcp23s17.h> 。下面是设置MCP23s17的函数:

int mcp23s17Setup (int pinBase, int spiPort, int devID) ;

类似地,int pinBase的值可以是任何大于64的数,且根据需要打开的SPI接口int spiPort 应该是 01注意,Banana Pro 上有两个API接口,而LeMaker Guitar仅有一个SPI接口 int spiPort = 0,下面是一个demo。

#include <stdio.h>
#include <wiringPi.h>
#include <mcp23s17.h>
#define BASE    150
int main (void)
{
  int i;
wiringPiSetup () ;
  mcp23s17Setup (BASE, 0, 0) ;
for (i = 0 ; i < 8 ; ++i)
    pinMode (BASE + i, OUTPUT) ;
for (;;)
  {
      for (i = 0 ; i < 8; ++i)
      {
        digitalWrite (BASE + i, HIGH) ;
        delay (500) ;
        digitalWrite (BASE + i, LOW) ;
        delay (500) ;
      }
  }
  return 0 ;
}

例子2: 控制AT45DBXX Data Flash

AT45DB041B是一个兼容串行传输的Flash存储器。通过片选引脚(CS)使能芯片,且通过串行输入(SI)、串行输出(SO)和串行时钟(SCK)3根线被访问。没有专门访问AT45DBXX DataFlash的函数,但是使用WiringLMK是可以的。更多的读写AT45DBXX DataFlash操作,请查阅datasheet。

#include <stdio.h>
#include <stdlib.h>
#include <wiringPi.h>
void at45BufWrite(unsigned char val)
{
	int ret;
	unsigned char wBuf[5] = {0x84, 0xff, 0x00, 0x02,0xff}; // write data to buffer
 
 
wBuf[4] = val;
 
	printf("SPI: write data: 0x%02x\n", wBuf[4]);
 
	ret = wiringPiSPIDataRW(0, wBuf, sizeof(wBuf));
	if(ret < 0)
	{
		printf("Write data to the AT45DB041D failed!\n");
		return;
	}
}
 
unsigned char at45BufRead(void)
{
	int ret;
        unsigned char rBuf[6] = {0xD4, 0xff, 0x00, 0x02, 0xff, 0xff}; // read data from buffer
ret = wiringPiSPIDataRW(0, rBuf, sizeof(rBuf));
	if(ret < 0)
	{
		printf("Read data from the AT45DB041D failed!\n");
		return;
	}
	return rBuf[5];
}
 
void SpiTest()
{
	int fd;
	unsigned char wData = 0x65; // write value
	unsigned char retv;
 
 
fd = wiringPiSPISetup(0, 5000000); // channel:0  5M
if(fd < 0)
	{
		printf("Open the SPI device failed!\n");
		return;
	}
        at45BufWrite(wData);
	delay(100); // delay 100ms
retv = at45BufRead();
	printf("SPI: read  data: 0x%02x\n", retv);
if(wData == retv)
	{
		printf("SPI: the spi interface is working!\n");
	}
	else
	{
		printf("SPI: the spi interface is not working! Please check out!\n");
	}
	close(fd);
}
 
int main(int argc, char **argv)
{
	wiringPiSetup();
	while(1)
	{
	    SpiTest();
	}
    	return 0;	
}

使用Python语言

LMK.GPIO没有SPI和I2C接口的函数,所以通过LMK.GPIO的 GPIO.inputGPIO.output操作模拟SPI接口操作。SPIsend(opcode, addr, data)函数发送数据, SPIread(opcode, addr)函数读取数据。

def SPIsendValue(value):
    GPIO.setup(SPI_MOSI, GPIO.OUT)
    GPIO.setup(SPI_SCLK, GPIO.OUT)
    for i in range(8):
        if (value & 0x80):
            GPIO.output(SPI_MOSI, GPIO.HIGH)
        else:
            GPIO.output(SPI_MOSI, GPIO.LOW)
        GPIO.output(SPI_SCLK, GPIO.HIGH)
        GPIO.output(SPI_SCLK, GPIO.LOW)
        value <<= 1
def SPIsend(opcode, addr, data):
    GPIO.setup(SPI_CS0, GPIO.OUT)
    GPIO.output(SPI_CS0, GPIO.LOW)
    SPIsendValue(opcode | SPI_SLAVE_WRITE)
    SPIsendValue(addr)
    SPIsendValue(data)
    GPIO.output(SPI_CS0, GPIO.HIGH)
def SPIread(opcode, addr):
    GPIO.setup(SPI_MISO, GPIO.IN)
    GPIO.output(SPI_CS0, GPIO.LOW)
    SPIsendValue(opcode | SPI_SLAVE_READ)
    SPIsendValue(addr)
    value = 0
    for i in range(8):
        value <<= 1
        if(GPIO.input(SPI_MISO)):
            value |= 0x01
        GPIO.output(SPI_SCLK, GPIO.HIGH)
        GPIO.output(SPI_SCLK, GPIO.LOW)
    GPIO.output(SPI_CS0, GPIO.HIGH)
    return value

例子: 控制MCP23s17

更多详细的寄存器配置和使用方法,请下载MCP23s17 datasheet。下面是一个配置LN_Digital扩展板的简单的例子。

import LMK.GPIO as GPIO
# LNdigital
LNdigital = False
# MCP23S17
SPI_SLAVE_ADDR = 0x40
SPI_IODIRA = 0x00
SPI_IODIRB = 0x01
SPI_GPIOA = 0x12
SPI_GPIOB = 0x13
SPI_IOCONA =0x0A
SPI_IOCONB =0x0B
SPI_OLATA =0x14
SPI_OLATB =0x15
SPI_INTENA = 0x04
SPI_INTENB = 0x05
SPI_DEFVALA = 0x06
SPI_DEFVALB = 0x07
SPI_INTCONA = 0x08
SPI_INTCONB = 0x09
SPI_GPPUA = 0x0C
SPI_GPPUB = 0x0D
SPI_SLAVE_WRITE = 0x00
SPI_SLAVE_READ = 0x01
# MCP23S17-Pins
SPI_SCLK = 11 # Serial-Clock
SPI_MOSI = 10 # Master-Out-Slave-In
SPI_MISO = 9  # Master-In-Slave-Out
SPI_CS0 = 8   # Chip-Select
SPIsend(SPI_SLAVE_ADDR, SPI_IOCONA, 0x00)
SPIsend(SPI_SLAVE_ADDR, SPI_IOCONB, 0x00)
SPIsend(SPI_SLAVE_ADDR, SPI_GPIOA, 0x00)
def LNdigital():
    try:
        GPIO.setup(SPI_SCLK, GPIO.OUT)
        GPIO.setup(SPI_MOSI, GPIO.OUT)
        GPIO.setup(SPI_MISO, GPIO.IN)
        GPIO.setup(SPI_CS0, GPIO.OUT)
GPIO.output(SPI_CS0, GPIO.HIGH)       
        GPIO.output(SPI_SCLK, GPIO.LOW)
SPIsend(SPI_SLAVE_ADDR, SPI_IODIRA, 0x00)#outputs
        SPIsend(SPI_SLAVE_ADDR, SPI_IODIRB, 0xFF)#inputs
        SPIsend(SPI_SLAVE_ADDR, SPI_GPIOA, 0x00)
        SPIsend(SPI_SLAVE_ADDR, SPI_GPIOB, 0xFF)
        Test = SPIread(SPI_SLAVE_ADDR, SPI_GPIOA)
        if Test == 0x00:
            LNdigital = True
        else:
            LNdigital = False
    except:
        LNdigital = False
if __name__ == '__main__':
LNdigital()
    SPIsend(SPI_SLAVE_ADDR, SPI_IOCONA, 0x0A)
    SPIsend(SPI_SLAVE_ADDR, SPI_IOCONB, 0x0A)
    SPIsend(SPI_SLAVE_ADDR, SPI_IODIRA, 0x00)
    SPIsend(SPI_SLAVE_ADDR, SPI_IODIRB, 0xFF)
    SPIsend(SPI_SLAVE_ADDR, SPI_GPPUA, 0x00)
    SPIsend(SPI_SLAVE_ADDR, SPI_GPPUB, 0xFF)
    SPIsend(SPI_SLAVE_ADDR, SPI_INTCONA, 0x00)
    SPIsend(SPI_SLAVE_ADDR, SPI_INTCONB, 0xFF)
    SPIsend(SPI_SLAVE_ADDR, SPI_DEFVALA, 0x00)
    SPIsend(SPI_SLAVE_ADDR, SPI_DEFVALB, 0xFF)
    SPIsend(SPI_SLAVE_ADDR, SPI_GPIOA, 0x00)
    SPIsend(SPI_SLAVE_ADDR, SPI_GPIOB, 0x00)
    SPIsend(SPI_SLAVE_ADDR, SPI_INTENA, 0x00)
    SPIsend(SPI_SLAVE_ADDR, SPI_INTENB, 0x00)
    SPIsend(SPI_SLAVE_ADDR, SPI_OLATA, 0x00)
    SPIsend(SPI_SLAVE_ADDR, SPI_OLATB, 0xFF)
Chip = 0
    Bank = "A"
    Bin = "01010101"
Addr = "0x" + str((Chip * 2) + 40)
    if Chip == 5:
        Addr = "0x4A"
    elif Chip == 6:
        Addr = "0x4C"
    elif Chip == 7:
        Addr = "0x4E"
if Bank.upper() == "A":
        Bank = 0x12
    elif Bank.upper() == "B":
        Bank = 0x13
    else:
        Bank = 0x00
Bin = "0b" + Bin
SPIsend(int(Addr, 16), Bank, int(Bin, 2))


另请参阅


附录:Banana Pro和LeMaker Guitar 40 Pins GPIO映射表

Banana Pro和LeMaker Guitar 40 Pins GPIO 映射表
物理编号表 Banana Pro LeMaker Guitar (底板B型) WiringLMK设置函数 LMK.GPIO 树莓派
wiringPiSetupPhys() LMK.GPIO.BOARD A20芯片序列号 sys S500芯片序列号 sys wiringPiSetup() wiringPiSetupGpio() wiringPiSetupSys() LMK.GPIO.BCM BCM芯片序列号
1 3.3V -- 3.3V -- -- -- -- -- 3.3V
2 5V -- 5V -- -- -- -- -- 5V
3 53/PB21 2 131/GPIOE03 131 8 2 2 2 2/GPIO02
4 5V -- 5V -- -- -- -- -- 5V
5 52/PB20 3 130/GPIOE02 130 9 3 3 3 3GPIO03
6 GND -- GND -- -- -- -- -- GND
7 226/PH02 4 50/GPIOB18 50 7 4 4 4 4/GPIO04
8 228/PH04 14 91/GPIOC27 91 15 14 14 14 14/GPIO14
9 GND -- GND -- -- -- -- -- GND
10 229/PH05 15 90/GPIOC26 90 16 15 15 15 15/GPIO15
11 275/PI19 17 64/GPIOC00 64 0 17 17 17 17/GPIO17
12 259/PI03 18 40/GPIOB08 40 1 18 18 18 18/GPIO18
13 274/PI18 27 65/GPIOC01 65 2 27 27 27 27/GPIO27
14 GND -- GND -- -- -- -- -- GND
15 273/PI17 22 68/GPIOC04 68 3 22 22 22 22/GPIO22
16 244/PH20 23 25/GPIOA25 25 4 23 23 23 23/GPIO23
17 3.3V -- 3.3V -- -- -- -- -- 3.3V
18 245/PH21 24 70/GPIOC06 70 5 24 24 24 24/GPIO24
19 268/PI12 10 89/GPIOC25 89 12 10 10 10 10/GPIO10
20 GND -- GND -- -- -- -- -- GND
21 269/PI13 9 88/GPIOC24 88 13 9 9 9 9/GPIO09
22 272/PI16 25 69/GPIOC05 69 6 25 25 25 25/GPIO25
23 267/PI11 11 86/GPIOC22 86 14 11 11 11 11/GPIO11
24 266/PI10 8 87/GPIOC23 87 10 8 8 8 8/GPIO8
25 GND -- GND -- -- -- -- -- GND
26 270/PI14 7 51/GPIOB19 51 11 7 7 7 7/GPIO07
27 257/PI01 0 48/GPIOB16 48 30 0 0 0 0/GPIO00
28 256/PI00 1 46/GPIOB14 46 31 1 1 1 1/GPIO01
29 35/PB03 5 47/GPIOB15 47 21 5 5 5 5/GPIO05
30 GND -- GND -- -- -- -- -- GND
31 277/PI21 6 42/GPIOB10 42 22 6 6 6 6/GPIO06
32 276/PI20 12 45/GPIOB13 45 26 12 12 12 12/GPIO12
33 45/PB13 13 32/GPIOB00 32 23 13 13 13 13/GPIO13
34 GND -- GND -- -- -- -- -- GND
35 39/PB07 19 33/GPIOB01 33 24 19 19 19 19/GPIO19
36 38/PB06 16 28/GPIOA28 28 27 16 16 16 16/GPIO16
37 37/PB05 26 34/GPIOB02 34 25 26 26 26 26/GPIO26
38 44/PB12 20 31/GPIOA31 31 28 20 20 20 20/GPIO20
39 GND -- GND -- -- -- -- -- GND
40 40/PB08 21 27/GPIOA27 27 29 21 21 21 21/GPIO21