为什么我在 MCP23S17 的输出引脚上没有变高?

Why don't I get HIGH on output pins of MCP23S17?

我使用 STM32 通过 SPI 连接到 MCP23S17 16 位 I/O 端口扩展器。

我想将所有 16 个 I/0 引脚设置为输出,并将它们全部设置为低电平或高电平。

我用示波器检查 SPI 是否正确传输信号,确实如此。 唯一的问题是 I/O 引脚上的电压约为 0.4V。不是 5V。

有时我得到 1.4V 的值但它消失了,很奇怪...

有人可以检查我的代码并告诉我我的错误在哪里吗?我很确定我在某处做错了代码。

MCP23S17.h:

#ifndef INC_MCP23S17_H_
#define INC_MCP23S17_H_

#include "stm32f1xx_hal_conf.h"

extern SPI_HandleTypeDef hspi2;

void MCP23S17_SPI_Write(uint8_t reg_addr, uint8_t data);
uint8_t MCP23S17_SPI_Read(uint8_t data);

#define CS_HIGH() HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_RESET);
#define CS_LOW() HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_SET);




#define MCP23S17_AAA        ((uint8_t)0x0E)
#define MCP23S17_ADDRESS    ((uint8_t)0x40)

#define MCP23S17_W          ((uint8_t)0x00)
#define MCP23S17_R          ((uint8_t)0x01)

#define MCP23S17_IODIRA     ((uint8_t)0x00)
#define MCP23S17_IPOLA      ((uint8_t)0x02)
#define MCP23S17_GPINTENA   ((uint8_t)0x04)
#define MCP23S17_DEFVALA    ((uint8_t)0x06)
#define MCP23S17_INTCONA    ((uint8_t)0x08)
#define MCP23S17_IOCONA     ((uint8_t)0x0A)
#define MCP23S17_GPPUA      ((uint8_t)0x0C)
#define MCP23S17_INTFA      ((uint8_t)0x0E)
#define MCP23S17_INTCAPA    ((uint8_t)0x10)
#define MCP23S17_GPIOA      ((uint8_t)0x12)
#define MCP23S17_OLATA      ((uint8_t)0x14)


#define MCP23S17_IODIRB     ((uint8_t)0x01)
#define MCP23S17_IPOLB      ((uint8_t)0x03)
#define MCP23S17_GPINTENB   ((uint8_t)0x05)
#define MCP23S17_DEFVALB    ((uint8_t)0x07)
#define MCP23S17_INTCONB    ((uint8_t)0x09)
//#define MCP23S17_IOCONB   ((uint8_t)0x0B)
#define MCP23S17_GPPUB      ((uint8_t)0x0D)
#define MCP23S17_INTFB      ((uint8_t)0x0F)
#define MCP23S17_INTCAPB    ((uint8_t)0x11)
#define MCP23S17_GPIOB      ((uint8_t)0x13)
#define MCP23S17_OLATB      ((uint8_t)0x15)




//#define MCP23S17_INT_ERR  ((uint8_t)255)

//#define BANK              ((uint8_t)0x80) //bit 7  of IOCON
//#define MIRROR                ((uint8_t)0x40) //bit 6  of IOCON
//#define SEQOP                 ((uint8_t)0x20) //bit 5  of IOCON
//#define DISSLW                ((uint8_t)0x10) //bit 4  of IOCON
//#define HAEN              ((uint8_t)0x08) //bit 3  of IOCON
//#define ODR                   ((uint8_t)0x04) //bit 2  of IOCON
//#define INTPOL                ((uint8_t)0x02) //bit 1  of IOCON
//#define unused                ((uint8_t)0x00) //bit 0  of IOCON


//-----------------------

#define MCP23S17_MODERA_W(x) MCP23S17_SPI_Write(MCP23S17_IODIRA, ((uint8_t)x))
#define MCP23S17_MODERA_R() MCP23S17_SPI_Read(MCP23S17_IODIRA)

#define MCP23S17_IPOLA_W(x) MCP23S17_SPI_Write(MCP23S17_IPOLA, ((uint8_t)x))


#define MCP23S17_ODRA_W(x) MCP23S17_SPI_Write(MCP23S17_OLATA, ((uint8_t)x))
#define MCP23S17_ODRA_R() MCP23S17_SPI_Read(MCP23S17_OLATA)

#define MCP23S17_IDRA_R() MCP23S17_SPI_Read(MCP23S17_GPIOA)     // Reflect the value of the port A

#define MCP23S17_PUDA_W(x) MCP23S17_SPI_Write(MCP23S17_GPPUA, ((uint8_t)x))
#define MCP23S17_PUDA_R() MCP23S17_SPI_Read(MCP23S17_GPPUA)

#define MCP23S17_SETUP_W(x) MCP23S17_SPI_Write(MCP23S17_IOCONA, ((uint8_t)x))
#define MCP23S17_SETUP_R() MCP23S17_SPI_Read(MCP23S17_IOCONA))

#define MCP23S17_MODERB_W(x) MCP23S17_SPI_Write(MCP23S17_IODIRB, ((uint8_t)x))
#define MCP23S17_MODERB_R() MCP23S17_SPI_Read(MCP23S17_IODIRB)

#define MCP23S17_IPOLB_W(x) MCP23S17_SPI_Write(MCP23S17_IPOLB, ((uint8_t)x))


#define MCP23S17_ODRB_W(x) MCP23S17_SPI_Write(MCP23S17_OLATB, ((uint8_t)x))
#define MCP23S17_ODRB_R() MCP23S17_SPI_Read(MCP23S17_OLATB)

#define MCP23S17_IDRB_R() MCP23S17_SPI_Read(MCP23S17_GPIOB)     // Reflect the value of the port B

#define MCP23S17_PUDB_W(x) MCP23S17_SPI_Write(MCP23S17_GPPUB, ((uint8_t)x))
#define MCP23S17_PUDB_R() MCP23S17_SPI_Read(MCP23S17_GPPUB)

//-----------------------

void GPIO_Write_Pins(uint16_t);
void GPIO_Expander_Init();
void MCP23S17_SPI_Write(uint8_t reg_addr, uint8_t data);
#endif /* INC_MCP23S17_H_ */

MCP23S17.c

#include "main.h"
#include "MCP23S17.h"

void MCP23S17_SPI_Write(uint8_t reg_addr, uint8_t data)
{
    uint8_t pBuff[3];
    pBuff[0] = MCP23S17_ADDRESS|MCP23S17_AAA|MCP23S17_W;    //optocode that contain 0100 + 111 + 0 (read command)
    pBuff[1] = reg_addr;  // register address
    pBuff[2] = data;      // the value that is modified on the register, check datasheet

    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);

    HAL_SPI_Transmit_IT(&hspi2, pBuff, 3);  //transmit on the spi2 the optocode, register adress and the value for the register
    for(uint32_t i = 0; i < 85; i++)    //delay
        {}

    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET);
}
void GPIO_Expander_Init()
{
    MCP23S17_SETUP_W(0x00);
    MCP23S17_MODERA_W(0x00);
    MCP23S17_MODERB_W(0x00);
    MCP23S17_PUDA_W(0x00);
    MCP23S17_PUDB_W(0x00);
    //MCP23S17_IPOLA_W(0x00);
    //MCP23S17_IPOLB_W(0x00);

}
void GPIO_Write_Pins(uint16_t dataspi)
{
    //16 to 8 and 8
    uint8_t data_half[2];

    data_half[0]=*((uint8_t*)&(dataspi)+1);     //split the first half of the data
    data_half[1]=*((uint8_t*)&(dataspi)+0);     //split the second half of the data

    MCP23S17_ODRA_W(data_half[0]);  //first half
    MCP23S17_ODRB_W(data_half[1]);  //second half

}

并在 main.c

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET);


  GPIO_Expander_Init();

  GPIO_Write_Pins(0xFFFF);
  while(1)
  {

  }

The only thing is that on the I/O pins I get around 0.4V

这可能是因为 GPIO 未初始化。

您还有一个不同的问题需要处理。

for(uint32_t i = 0; i < 85; i++)    //delay
{}

这个循环很可能被编译器优化掉。这是因为,它什么都不做。

有更复杂的方法可以在微控制器中产生延迟。最好的解决方案是使用定时器模块。

所以回来解决方案,代码很好,我尝试的第一个gpio扩展器2个纯粹被烧毁了。对于更短的工作代码,只需在此处评论以请求它。感谢大家的建议,因为我在最终形式的代码中考虑了他们。