Урок 68
Часть 3
LAN. ENC28J60
В предыдущей части нашего урока мы добавили несколько макросов и функций по работе с микросхемой ENC28J60, а также немного поработали над изучением технической документации.
Произведём «мягкий» сброс в функции инициализации и проверим, что всё перезагрузилось
LD_OFF;
enc28j60_writeOp(ENC28J60_SOFT_RESET,0,ENC28J60_SOFT_RESET);
HAL_Delay(2);
//проверим, что всё перезагрузилось
while(!enc28j60_readOp(ENC28J60_READ_CTRL_REG,ESTAT)&ESTAT_CLKRDY)
;
При операции чтения мы читаем регистр ESTAT на предмет установки бита CLKRDY.
Напишем функцию чтения буфера (см. таблицу 4.1 выше)
//--------------------------------------------------
static void enc28j60_readBuf(uint16_t len,uint8_t* data)
{
SS_SELECT();
SPI_SendByte(ENC28J60_READ_BUF_MEM);
while(len--){
*data++=SPIx_WriteRead(0x00);
}
SS_DESELECT();
}
//--------------------------------------------------
Создадим переменную для хранения номера текущего банка
//--------------------------------------------------
static uint8_t Enc28j60Bank;
А теперь напишем функцию установки текущего банка
//--------------------------------------------------
static void enc28j60_SetBank(uint8_t addres)
{
if ((addres&BANK_MASK)!=Enc28j60Bank)
{
enc28j60_writeOp(ENC28J60_BIT_FIELD_CLR,ECON1,ECON1_BSEL1|ECON1_BSEL0);
Enc28j60Bank = addres&BANK_MASK;
enc28j60_writeOp(ENC28J60_BIT_FIELD_SET,ECON1,Enc28j60Bank>>5);
}
}
//--------------------------------------------------
Попробуем разобраться в том, что здесь происходит.
Ну, во первых, если у нас уже текущий банк равен тому, который мы хотим установить, то мы ничего не делаем и уходим
А затем мы в регистре ECON1 очищаем биты BSEL1 и BSEL0, отвечающие за банк, затем заносим в переменную наш банк из адреса, сдвигаем полученное значение вправо на 5 пунктов для того, чтобы нужные биты оказались в младших, и устанавливаем соответствующие биты в том же регистре

Затем напишем универсальные функции для чтения и записи обычных регистров управления
//--------------------------------------------------
static void enc28j60_writeRegByte(uint8_t addres,uint8_t data)
{
enc28j60_SetBank(addres);
enc28j60_writeOp(ENC28J60_WRITE_CTRL_REG,addres,data);
}
//--------------------------------------------------
static uint8_t enc28j60_readRegByte(uint8_t addres)
{
enc28j60_SetBank(addres);
return enc28j60_readOp(ENC28J60_READ_CTRL_REG,addres);
}
//--------------------------------------------------
Буфер, работающий и на чтение и на запись, необходимо настроить также с помощью регистров

Так как все указатели у нас двухбайтовые, то создадим ещё функцию для записи данных в такие регистры
//--------------------------------------------------
static void enc28j60_writeReg(uint8_t addres,uint16_t data)
{
enc28j60_writeRegByte(addres, data);
enc28j60_writeRegByte(addres+1, data>>8);
}
//--------------------------------------------------
Настроим буферы в функции инициализации
//настроим буферы
enc28j60_writeReg(ERXST,RXSTART_INIT);
enc28j60_writeReg(ERXRDPT,RXSTART_INIT);
enc28j60_writeReg(ERXND,RXSTOP_INIT);
enc28j60_writeReg(ETXST,TXSTART_INIT);
enc28j60_writeReg(ETXND,TXSTOP_INIT);
В следующей части нашего урока мы закончим функцию инициализации микросхемы, а также напишем функцию приёма сетевых пакетов.
Предыдущая часть Программирование МК STM32 Следующая часть
Техническая документация:
Документация на микросхему ENC28J60
Перечень ошибок ENC28J60 (Errata)
Отладочную плату STM32F103C8T6 можно приобрести здесь STM32F103C8T6
Программатор недорогой можно купить здесь ST-Link V2
Ethernet LAN Сетевой Модуль можно купить здесь ENC28J60 Ethernet LAN Сетевой Модуль.
Переходник USB to TTL можно приобрести здесь ftdi ft232rl
Смотреть ВИДЕОУРОК в RuTube (нажмите на картинку)
Смотреть ВИДЕОУРОК в YouTube (нажмите на картинку)



enc28j60_writeReg(ETXST,TXSTART_INIT);
enc28j60_writeReg(ETXND,TXSTOP_INIT);
Вот эти строки при инициализации вредны.
Писал программу, которая слушает пакеты. Регулярно появлялся статус «ошибка передачи».
Когда убрал эти строки — ошибки ушли.
Внимательно прочел даташит — сделал вывод, что запись этих регистров нужна только при желании отправить пакет.
Добрый день! А почему мы с Вами выбрали именно такой размер буфера приёма и передачи? А Почему бы не инициализировать буфер целиком?