I/O разширител за
RASPBERRY PI

Въпреки, че Raspberry-то има доста входно изходни линии много често те се оказват недостатъчни.

Един бърз и лесен начин за добавяне на входно изходни линии е използването на I/O разширителя на Microchip MCP23S17.

Комуникацията с този чип се осъществява по I2C (MCP23017) или SPI (MCP23S17) шина.

За щастие в линукс кърнела има драйвер и за двата вида комуникация.

Ако искаме да използваме SPI шина трябва да направим следното:

1. Променя се файла "arch/arm/mach-bcm2708/bcm2708.c" от сорсовете на кърнела. Като частта

#ifdef CONFIG_SPI
static struct spi_board_info bcm2708_spi_devices[] = {
 {
  .modalias = "spidev",
  .max_speed_hz = 500000,
  .bus_num = 0,
  .chip_select = 0,
  .mode = SPI_MODE_0,
 }, {
  .modalias = "spidev",
  .max_speed_hz = 500000,
  .bus_num = 0,
  .chip_select = 1,
  .mode = SPI_MODE_0,
 }
};
#endif

придобива следният вид:

#ifdef CONFIG_SPI
#include <linux/spi/mcp23s08.h>
static const struct mcp23s08_platform_data mcp23017_data = {
 .chip[0] = {
  .is_present = true,
  .pullups = 0x00ff,
 },
 .base = 0x37,
};
static struct spi_board_info bcm2708_spi_devices[] = {
 {
  .modalias = "spidev",
  .max_speed_hz = 500000,
  .bus_num = 0,
  .chip_select = 0,
  .mode = SPI_MODE_0,
 }, {
  .modalias = "mcp23s17",
  .max_speed_hz = 8000000,
  .bus_num = 0,
  .chip_select = 1,
  .platform_data = &mcp23017_data,
  .mode = SPI_MODE_0,
 }
};
#endif

В случая MCP23S17 чипа е свързан към CS1 на SPI шината.

2. Кърнела се прекомпилира по подобие на инструкциите описани тук

3. Във файла /etc/modprobe.d/raspi-blacklist.conf се коментира реда blacklist spi-bcm2708

4. След рестарт при успешно зареждане на модулите се появява следната директория /sys/class/gpio/gpiochip55

Простичък тест на работоспособноста на разширителя може да се направи, като се изпълнят следните команди

echo 55 > /sys/class/gpio/export
echo in > /sys/class/gpio/gpio55/direction

cat /sys/class/gpio/gpio55/value

Последната команда показва състоянието на входа GPA0 на MCP23S17

Ако искаме да изпоззваме GPA0 като изход

echo 55 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio55/direction

echo 1 > /sys/class/gpio/gpio55/value
или
echo 0 > /sys/class/gpio/gpio55/value

Простичка програмка за, която сменя състоянието на GPA0 през 250ms:

/*
* 23s17.c
*/
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <poll.h>
#include <sys/time.h>
#include <stdio.h>

int main(int argc, char **argv) {
 int i=0;
 FILE *fd;
 struct pollfd pfd;
 char buf[128];

 fd = fopen ("/sys/class/gpio/export", "wb" );

 fprintf(fd,"55");
 fflush(fd);
 fclose(fd); 

 fd = fopen ("/sys/class/gpio/gpio55/direction", "wb" );
 fprintf(fd,"out");
 fflush(fd);
 fclose(fd); 
 pfd.fd = open("/sys/class/gpio/gpio55/value", O_RDWR );

 while (1){
  if (i==1){
   buf[0]='0';
   write(pfd.fd, buf, 1);
   i=0;
  }else{
   buf[0]='1';
   write(pfd.fd, buf, 1);
   i=1;
  }
  usleep(250000);
 }
 return 0;
}

компилира се по следният начин gcc 23s17.c -o 23s17

и се стартира посредством ./23с17

Коментари:

Нов коментар

Вашето име: