Есть задача связать вместе микроконтроллер STM8S207CB и контроллером W5100.
Управление по SPI и, как мне кажеться, в SPI я и накосячил, что делаю:
Спойлер
Код: Выделить всё
void SPI_Init(void){
//SPI_init
SPI_CR1_bit.BR=0x07; //fMASTER/256
SPI_CR1_bit.CPHA=0; //The first clock transition is the first data capture edge
SPI_CR1_bit.CPOL=0; //SCK to 0 when idle
SPI_CR2_bit.SSM=1; //Software slave management enabled
SPI_CR2_bit.SSI=1; //Master mode
SPI_CR1_bit.MSTR=1; //Master configuration
SPI_CR1_bit.SPE=1; //SPI enable
}
void SPI_Write(unsigned int addr,byte data)
{
byte buf;
// Activate the CS pin
ETH_CS_LO;
// Wait for transmission complete
while (!SPI_SR_bit.TXE);
// Start Wiznet W5100 Write OpCode transmission
SPI_DR = WIZNET_WRITE_OPCODE;
// Wait for transmission complete
while (!SPI_SR_bit.RXNE);
buf=SPI_DR; //получили ответ на 1-ю посылку
// Wait for transmission complete
while (!SPI_SR_bit.TXE);
// Start Wiznet W5100 Address High Bytes transmission
SPI_DR = (addr & 0xFF00) >> 8;
// Wait for transmission complete
while (!SPI_SR_bit.RXNE);
buf=SPI_DR; //получили ответ на 2-ю посылку
// Wait for transmission complete
while (!SPI_SR_bit.TXE);
// Start Wiznet W5100 Address Low Bytes transmission
SPI_DR = addr & 0x00FF;
// Wait for transmission complete
while (!SPI_SR_bit.RXNE);
buf=SPI_DR; //получили ответ на 3-ю посылку
// Wait for transmission complete
while (!SPI_SR_bit.TXE);
// Start Data transmission
SPI_DR = data;
// Wait for transmission complete
while (!SPI_SR_bit.RXNE);
buf=SPI_DR; //получили ответ на 4-ю посылку
if(buf==3){/*ST_LED_EN*/} //чтобы компилятор не ругался на неиспользованную переменную, на время проверки можно светить светодиодом
// CS pin is not active
ETH_CS_HI;
}
byte SPI_Read(unsigned int addr)
{
byte buf;
// Activate the CS pin
ETH_CS_LO;
// Wait for transmission complete
while (!SPI_SR_bit.TXE);
// Start Wiznet W5100 Write OpCode transmission
SPI_DR = WIZNET_READ_OPCODE;
// Wait for transmission complete
while (!SPI_SR_bit.RXNE);
buf=SPI_DR; //получили ответ на 1-ю посылку
// Wait for transmission complete
while (!SPI_SR_bit.TXE);
// Start Wiznet W5100 Address High Bytes transmission
SPI_DR = (addr & 0xFF00) >> 8;
// Wait for transmission complete
while (!SPI_SR_bit.RXNE);
buf=SPI_DR; //получили ответ на 2-ю посылку
// Wait for transmission complete
while (!SPI_SR_bit.TXE);
// Start Wiznet W5100 Address Low Bytes transmission
SPI_DR = addr & 0x00FF;
// Wait for transmission complete
while (!SPI_SR_bit.RXNE);
buf=SPI_DR; //получили ответ на 3-ю посылку
// Wait for transmission complete
while (!SPI_SR_bit.TXE);
// Send Dummy transmission for reading the data
SPI_DR = 0;
// Wait for transmission complete
while (!SPI_SR_bit.RXNE);
buf=SPI_DR; //получили ответ на 4-ю посылку
// CS pin is not active
ETH_CS_HI;
return(buf);
}
Тут я либо не правильно инициализировал SPI, либо не правильно пишу. Ниже код инициализации для пинга
Спойлер
Код: Выделить всё
void W5100_Init(void)
{
// Ethernet Setup
unsigned char mac_addr[] = {0x00,0x16,0x36,0xDE,0x58,0xF6};
unsigned char ip_addr[] = {192,168,0,111};
unsigned char sub_mask[] = {255,255,255,0};
unsigned char gtw_addr[] = {192,168,0,1};
//Hardware reset
W5100_RST_LO;
delay(ms,100);
W5100_RST_HI;
delay(ms,100);
// Setting the Wiznet W5100 Mode Register: 0x0000
SPI_Write(MR,0x80); // MR = 0b10000000;
delay(ms,1);
// Setting the Wiznet W5100 Gateway Address (GAR): 0x0001 to 0x0004
SPI_Write(GAR + 0,gtw_addr[0]);
SPI_Write(GAR + 1,gtw_addr[1]);
SPI_Write(GAR + 2,gtw_addr[2]);
SPI_Write(GAR + 3,gtw_addr[3]);
delay(ms,1);
// Setting the Wiznet W5100 Source Address Register (SAR): 0x0009 to 0x000E
SPI_Write(SAR + 0,mac_addr[0]);
SPI_Write(SAR + 1,mac_addr[1]);
SPI_Write(SAR + 2,mac_addr[2]);
SPI_Write(SAR + 3,mac_addr[3]);
SPI_Write(SAR + 4,mac_addr[4]);
SPI_Write(SAR + 5,mac_addr[5]);
delay(ms,1);
// Setting the Wiznet W5100 Sub Mask Address (SUBR): 0x0005 to 0x0008
SPI_Write(SUBR + 0,sub_mask[0]);
SPI_Write(SUBR + 1,sub_mask[1]);
SPI_Write(SUBR + 2,sub_mask[2]);
SPI_Write(SUBR + 3,sub_mask[3]);
delay(ms,1);
// Setting the Wiznet W5100 IP Address (SIPR): 0x000F to 0x0012
SPI_Write(SIPR + 0,ip_addr[0]);
SPI_Write(SIPR + 1,ip_addr[1]);
SPI_Write(SIPR + 2,ip_addr[2]);
SPI_Write(SIPR + 3,ip_addr[3]);
delay(ms,1);
// Setting the Wiznet W5100 RX and TX Memory Size, we use 2KB for Rx/Tx 4 channels
SPI_Write(RMSR,0x55);
SPI_Write(TMSR,0x55);
}Настройка ГПИО
Спойлер
Код: Выделить всё
//E~RESET
PD_DDR_bit.DDR3=1; //PD3 - на вывод.
PD_CR1_bit.C13=1; //PD3 - PP
PD_CR2_bit.C23=0; //PD3 - ограничение скорости отключено.
//~CS_ETH
PC_DDR_bit.DDR3=1; //PC3 - на вывод.
PC_CR1_bit.C13=1; //PC3- PP
PC_CR2_bit.C23=0; //PC3 - ограничение скорости отключено.
//SPI_SCLK
PC_DDR_bit.DDR5=1; //PC5 - на вывод.
PC_CR1_bit.C15=1; //PC5- PP
PC_CR2_bit.C25=0; //PC5 - ограничение скорости отключено.
//SPI_MOSI
PC_DDR_bit.DDR6=1; //PC6 - на вывод.
PC_CR1_bit.C16=1; //PC6- PP
PC_CR2_bit.C26=0; //PC6 - ограничение скорости отключено.
//SPI_MISO
PC_DDR_bit.DDR7=0; //PC7 - на вход.
PC_CR1_bit.C17=1; //PC7- Pull-up without interrupt
PC_CR2_bit.C27=0; 

