Библиотека esp32 spi, как читать регистр mcp23s08

спасибо за любую помощь Мне нужно прочитать расширитель gpio mcp23s08, установленный как 8-битный вход. мой код правильно пишет (я считаю) регистр настройки с использованием библиотеки SPI, с измененным приложенным примером. Но я не понимаю, как прочитать регистр gpio (0x09) код (с неправильной процедурой считывания:

#define GPIO_SEL_pin 14                         // D14 = MCP23S08 Вывод выбора GPIO SPI
#define SCLK 18                                 // D18 SPI SCLK
#define MISO 19                                 // D19 SPI MISO
#define MOSI 23                                 // D23 SPI MOSI

#include <SPI.h>

uint8_t keyboard;

static const int spiClk = 1000000; // 1 МГц

//неинициализированные указатели на объекты SPI
SPIClass * mcp23s08 = NULL;

void setup() {
  Serial.begin(115200);
  pinMode(GPIO_SEL_pin, OUTPUT);                     //MCP23S08 Вывод выбора SPI
  digitalWrite(GPIO_SEL_pin, HIGH);                  //поднимите ss на высокий уровень, чтобы отключить передачу данных
  mcp23s08 = new SPIClass(VSPI);
  mcp23s08->begin(SCLK, MISO, MOSI, GPIO_SEL_pin);   //SCLK, МИСО, МОСИ, СС
  mcp23s08SetUp();
  delay(1);

}

void loop() {
  keyboard = mcp23s08Read();
  Serial.println (keyboard);
  delay(100);
}

// ================================= подпрограммы ============= ====================
void mcp23s08SetUp( void ) {
  uint8_t dev_adr  = 0x40;                          // MCP23S08 адрес 0; Чтение/Запись = запись
  uint8_t reg_adr  = 0x00;                          // Регистр MCP23S08 IODIR
  uint8_t reg_data = 0xFF;                          // контакт настроен как вход

  digitalWrite(GPIO_SEL_pin, LOW);                 //медленно тяните SS, чтобы подготовить другой конец к передаче
// ============================ Вывод MCP3S08 как вход =============== ===============
  mcp23s08->beginTransaction(SPISettings(spiClk, MSBFIRST, SPI_MODE0));
  mcp23s08->transfer(dev_adr);  
  mcp23s08->transfer(reg_adr);  
  mcp23s08->transfer(reg_data);  
  mcp23s08->endTransaction();

  reg_adr  = 0x01;                                 // Регистр IPOL MCP23S08
  reg_data = 0xFF;                                 // инвертируем входную полярность
// ============================ MCP3S08 инвертирует вход ================ ==============
  mcp23s08->beginTransaction(SPISettings(spiClk, MSBFIRST, SPI_MODE0));
  mcp23s08->transfer(dev_adr);  
  mcp23s08->transfer(reg_adr);  
  mcp23s08->transfer(reg_data);  
  mcp23s08->endTransaction();

  reg_adr  = 0x06;                                 // Регистр подтягивания GPPU MCP23S08
  reg_data = 0xFF;                                 // устанавливаем подтягивающий регистр
// ============================ Подтягивающий резистор MCP3S08 ================ ==============
  mcp23s08->beginTransaction(SPISettings(spiClk, MSBFIRST, SPI_MODE0));
  mcp23s08->transfer(dev_adr);  
  mcp23s08->transfer(reg_adr);  
  mcp23s08->transfer(reg_data);  
  mcp23s08->endTransaction();

  digitalWrite(GPIO_SEL_pin, HIGH);                //поднимите ss на высокий уровень, чтобы обозначить окончание передачи данных
}

uint8_t mcp23s08Read ( void ) {
  uint8_t dev_adr  = 0x41;                          // MCP23S08 адрес 0; Чтение/Запись = чтение
  uint8_t reg_adr  = 0x09;                          // Регистр MCP23S08 GPIO
  uint8_t reg_data;                                 // регистр GPIO
  mcp23s08->beginTransaction(SPISettings(spiClk, MSBFIRST, SPI_MODE0));
  mcp23s08->transfer(dev_adr);  
  mcp23s08->transfer(reg_adr);  
  reg_data = mcp23s08->transfer(0x00);  
  mcp23s08->endTransaction(); 
  return reg_data; 
}

, 👍-1

Обсуждение

Почему вы переключаете SS внутри функции mcp23s08SetUp(), а НЕ внутри mcp23s08Read()? Я не помню, управляется ли вывод SS библиотекой SPI Arduino, но вы можете попробовать., @leoc7

Да, ты прав. Просто забыл переключить пин ss., @Angelo Gilin Maggiora

Привет @Angelo Gilin Maggiora, если этот ответ решил ваш вопрос, пожалуйста, примите его, нажав галочку. Это покажет широкому сообществу, что вы нашли решение, и повысит репутацию как отвечающего, так и вас самих. Нет никаких обязательств это делать., @leoc7

Большое спасибо за вашу помощь. @leoc7, не могли бы вы сказать мне, где находится кнопка с галочкой? На странице не нашел. Извините, я новичок, @Angelo Gilin Maggiora

Прочтите ответ на этот вопрос, чтобы знать, как принять ответ. :) https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work, @leoc7

Я, надеюсь, сделал это. Не так ли?, @Angelo Gilin Maggiora

Я бы предоставил полный рабочий пример настройки и считывания расширителя GPIO MCP23S08 с использованием esp32 и шины SPI., @Angelo Gilin Maggiora


1 ответ


Лучший ответ:

0

Вы забыли переключить вывод SS в функции mcp23s08Read().

 uint8_t mcp23s08Read ( void ) {
      ----> digitalWrite(GPIO_SEL_pin, LOW);                 //медленно тяните SS, чтобы подготовить другой конец к передаче
      uint8_t dev_adr  = 0x41;                          // MCP23S08 адрес 0; Чтение/Запись = чтение
      uint8_t reg_adr  = 0x09;                          // Регистр MCP23S08 GPIO
      uint8_t reg_data;                                 // регистр GPIO
      mcp23s08->beginTransaction(SPISettings(spiClk, MSBFIRST, SPI_MODE0));
      mcp23s08->transfer(dev_adr);  
      mcp23s08->transfer(reg_adr);  
      reg_data = mcp23s08->transfer(0x00);  
      mcp23s08->endTransaction(); 
      ----> digitalWrite(GPIO_SEL_pin, HIGH);                //поднимите ss на высокий уровень, чтобы обозначить окончание передачи данных
      return reg_data; 
    }
,