Я продолжаю изучать программирование микроконтроллеров, и в качестве следующей цели выбрал организацию простого web-сервера на AVR.
Я изучил основные моменты инициализации в официальной документации, плюс нашёл в интернете несколько примеров (правда, все они под STM32), но у меня всё равно не получается его инициализировать даже на обычный пинг. Вот как выглядит сам девайс:
Общаюсь я с ним по SPI. В документации сказано, что сначала передаётся старший байт адреса назначения, потом младший, затем контрольная фаза и, на конец, сами данные. Сейчас я приведу небольшой пример, как я всё это реализовываю:
Код
uint8_t opcode = 0; //Переменная для хранения опкода
uint8_t ip[4] = {192,168,1,197}; //ip адрес
//Данные, необходимые для формирования контрольной фазы
#define BSB_COMMON 0x0000 //bsb блок
#define WRITE 1 //бит записи
#define READ 0 //бит чтения
#define OM_FDM0 0x00 //Режим передачи данных переменной длинны
#define SIPR0 0x000F //Адреса регистров w5500, в которых хранится ip адрес
#define SIPR1 0x0010
#define SIPR2 0x0011
#define SIPR3 0x0012
//Провожу инициализацию SPI
void spi_init()
{
DDRB = (1<<PORTB7)|(1<<PORTB5)|(1<<PORTB4); //Clock - 7, MOSI - 5, Chip Select - 4. Всё на выход. MISO (6) - на вход.
SPCR = (1<<MSTR)|(1<<SPE)|(1<<SPR0); //Мастер, SPI включен.
}
//Функция записи данных в чип
void w5500_write(uint16_t addr, uint8_t opcode, uint8_t data) //Функция записи данных в регистр
{
selectW5500(); //Выбрать чип
unsigned char i; //счётчик
uint8_t buf[4]; //буфер для данных
buf[0] = (uint8_t)(addr >> 8); //передаём старшую часть адреса
buf[1] = (uint8_t)(addr); //передаём младшуя часть адреса
buf[2] = opcode; //передаём контрольную фазу
buf[3] = (uint8_t)(data); //передаём данные
for(i=0;i<4;i++) //цикл передачи данных
{
SPDR = buf[i];
while(!(SPSR&(1<<SPIF)));
}
deselectW5500();
}
uint8_t ip[4] = {192,168,1,197}; //ip адрес
//Данные, необходимые для формирования контрольной фазы
#define BSB_COMMON 0x0000 //bsb блок
#define WRITE 1 //бит записи
#define READ 0 //бит чтения
#define OM_FDM0 0x00 //Режим передачи данных переменной длинны
#define SIPR0 0x000F //Адреса регистров w5500, в которых хранится ip адрес
#define SIPR1 0x0010
#define SIPR2 0x0011
#define SIPR3 0x0012
//Провожу инициализацию SPI
void spi_init()
{
DDRB = (1<<PORTB7)|(1<<PORTB5)|(1<<PORTB4); //Clock - 7, MOSI - 5, Chip Select - 4. Всё на выход. MISO (6) - на вход.
SPCR = (1<<MSTR)|(1<<SPE)|(1<<SPR0); //Мастер, SPI включен.
}
//Функция записи данных в чип
void w5500_write(uint16_t addr, uint8_t opcode, uint8_t data) //Функция записи данных в регистр
{
selectW5500(); //Выбрать чип
unsigned char i; //счётчик
uint8_t buf[4]; //буфер для данных
buf[0] = (uint8_t)(addr >> 8); //передаём старшую часть адреса
buf[1] = (uint8_t)(addr); //передаём младшуя часть адреса
buf[2] = opcode; //передаём контрольную фазу
buf[3] = (uint8_t)(data); //передаём данные
for(i=0;i<4;i++) //цикл передачи данных
{
SPDR = buf[i];
while(!(SPSR&(1<<SPIF)));
}
deselectW5500();
}
Не знаю, почему, но мне кажется, что я что-то делаю не так с передачей данных. Я привёл пример записи одного
байта данных в регистр, отвечающий за хранение ip адреса. Формирование контрольной фазы выглядит так:
Код
opcode = (BSB_COMMON<<3)|(WRITE<<2)|OM_FDM0;
Функции выбора чипа в этом посте я писать не стал, так как там происходит просто "притягивание" линии к 0, а потом "отпускание".
Я постарался как можно короче изложить свою проблему, но, тем не менее, указав важные детали. Буду рад
любой помощи или совету.
Заранее спасибо.