Desde hace tres días tengo el problema de que no puedo hablar con mi MCP23S17
SPI I / O Expander de mi ATmega8
.
He comprobado dos veces mi circuito y estoy seguro de que lo hice bien.
Quiero disculparme por adelantado por tanto código, pero ya he revisado todo y espero que alguien vea lo que yo no ..
El problema es que estoy seguro de que mi código también es correcto. Por favor, asuma todos los encabezados necesarios como incluidos (no soy un principiante de C, eso es lo que quiero decir).
Esta es la función principal:
#define PB_SPI_SS_MCP23S17 PB2
#define PB_SPI_MOSI PB3
#define PB_SPI_SCK PB5
// Port C output pins
#define PC_HEARTBEAT PC4
static void delay(double ms)
{
#ifndef SIMULATOR
_delay_ms(ms);
#endif
}
void Spi_InitializeAsMaster(void)
{
SPCR = (1 << SPE) // Enable SPI
| (1 << MSTR) // Set as master
| (1 << CPOL) // Clock polarity (falling edge is leading)
| (1 << SPR0); // SPI clock rate select fck/16
SPSR = SPSR & 0xFE; // Clear "Double SPI Speed" bit
}
void Spi_Send(char cData)
{
// Start transmission
SPDR = cData;
// Wait for transmission complete
while( !(SPSR & (1 << SPIF)) );
}
int main (void)
{
delay(100);
DDRC = (1 << PC_HEARTBEAT);
DDRB = (1 << PB_SPI_SS_MCP23S17) | (1 << PB_SPI_MOSI) | (1 << PB_SPI_SCK);
Spi_InitializeAsMaster();
Mcp23s17 mcp;
Mcp23s17_Initialize(&mcp, (int*)&PORTB, PB_SPI_SS_MCP23S17);
Mcp23s17_SetPortDirection(&mcp, IODIRA, 0xFF);
Mcp23s17_SetPortDirection(&mcp, IODIRB, 0xFF);
while(1)
{
PORTC = ~PORTC;
Mcp23s17_SetOutputPin(&mcp, GPIOA, 0xFF);
Mcp23s17_SetOutputPin(&mcp, GPIOB, 0xFF);
delay(200);
Mcp23s17_SetOutputPin(&mcp, GPIOA, 0x00);
Mcp23s17_SetOutputPin(&mcp, GPIOB, 0x00);
delay(200);
}
}
Aquí está el código para el MCP23S17
:
static void Mcp23s17_Write(Mcp23s17 * self, char address, char data)
{
SPI_SELECT(self->spi)
delay(20);
Spi_Send(self->write_opcode);
Spi_Send(address);
Spi_Send(data);
SPI_UNSELECT(self->spi)
delay(20);
}
void Mcp23s17_Initialize(Mcp23s17 *self, int * sfr_address, int sfr_pin)
{
self->spi.sfr_address = sfr_address;
self->spi.sfr_pin = sfr_pin;
self->write_opcode = 0x40;
self->read_opcode = 0x40 | 1;
SPI_UNSELECT(self->spi)
Mcp23s17_Write(self, IOCON, IOCON_BYTE_MODE | IOCON_HAEN);
}
void Mcp23s17_SetPortDirection(Mcp23s17 * self, Mcp23s17Portdirection port, char direction)
{
Mcp23s17_Write(self, (char)port , direction);
}
¡Estaría muy agradecido por cualquier ayuda! Por favor avíseme si necesita más información. Saludos cordiales.