Lwip+enc28j60无法ping通

发布于 2015-02-05 11:38:30
是这样的,我参照一起来学RTT连载教程,里面有网络套接字实战演练程序,我把里面的DM9000的驱动改为enc28j60,用的是STM32F103ZET6,当然enc28j60的驱动也是拷贝RTT的工程里的,我添加驱动后,将rt_hw_enc28j60_init()函数放在rt_components_init()的#define RT_USING_LWIP处,更改IP地址和我电脑处于一个网段,烧写后,ping不通,enc28j60寄存器里面的值全为0,请问我这样添加和调用底层驱动对吗?是不是还要其他的地方修改,#define RT_LWIP_DHCP需要注释吗?
lwip.png

查看更多

关注者
0
被浏览
4.7k
9 个回答
aozima
aozima 2015-02-05
list_if都没有显示网卡,说明硬件没通。

检查硬件和驱动移植。
bpengj65359
bpengj65359 2015-02-05
那我调试的时候停留在了rt_components_init()里面的
for(fn_ptr = &__rt_init_rti_start;fn_ptr < &__rt_init_rti_board_end; fn_ptr++)
{
(*fn_ptr)();
}

这个地方,往下走不了了?请问这可能是哪里出问题了?谢谢aozima
aozima
aozima 2015-02-05
[新功能] 组件初始化
如果用不好这个功能,请先关闭之。
bpengj65359
bpengj65359 2015-02-05
如果我在rt_init_thread_entry()里面调用rt_hw_enc28j60_init(),list_if()后就会有MAC地址和IP地址等,但是网口的灯不亮了,enc28j60寄存器值也都为0,本地连接断开了;而当我在rt_components_init()里面调用rt_hw_enc28j60_init(),网口小灯亮,但是rt_hw_enc28j60_init()好像没执行,我在里面添加串口打印信息,没有打印出来,无MAC地址等信息,enc28j60寄存器值都为0,这是为什么啊?
microtomato
microtomato 2015-02-06
流程应该是首先初始化所用到的GPIO,然后注册SPI总线,绑定SPI设备,接着调用驱动中的enc28j60_attach就可以了。
给一段我的代码,在我的板上是好用的。enc28j60的驱动是RT-Thread V2.0.0里自带的enc28j60.c,位置:RT_ThreadV2_0_0componentsdriversspi。

enc28j60与STM32F103VET6开发板的接口:
SPI2_MOSI(蓝色)=PB15
SPI2_MISO(紫色)=PB14
SPI2_SCK(绿色)=PB13
VCC(红色)=3.3v
GND(棕色)=0v
RST(橙色)=PC6
INT(灰色)=PA8
CS(黄色)=PB12

以下是初始化代码:

void spi2_init_thread(void *parmeter) {
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
static struct stm32_spi_bus spi2_bus;
static struct rt_spi_device spi20_dev;
static struct stm32_spi_cs enc28j60_cs;

//开启GPIOB的时钟(SPI2和enc28j60的CS都在GPIOB上)
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
//配置SPI2所占用的GPIO
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
//配置SPI 以太网模块(enc28j60)的CS信号(PB12)
enc28j60_cs.GPIOx = GPIOB;
enc28j60_cs.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = enc28j60_cs.GPIO_Pin;
GPIO_Init(enc28j60_cs.GPIOx, &GPIO_InitStructure);
GPIO_SetBits(enc28j60_cs.GPIOx, enc28j60_cs.GPIO_Pin);
//配置以太网芯片(enc28j60)的中断信号(PA8)
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_Init(GPIOA, &GPIO_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource8);
EXTI_Enable(1,8);
//注册SPI2总线
stm32_spi_register(SPI2, &spi2_bus, "spi2");
//绑定设备
rt_spi_bus_attach_device(&spi20_dev, "spi20", "spi2", (void *)&enc28j60_cs);
enc28j60_attach("spi20");
}

以下是中断代码:

void EXTI_Enable(rt_uint32_t enable, rt_uint8_t LineNo)
{
EXTI_InitTypeDef EXTI_InitStructure;

/* Configure EXTI */
switch(LineNo)
{
case 6:
EXTI_InitStructure.EXTI_Line = EXTI_Line6;
break;
case 8:
EXTI_InitStructure.EXTI_Line = EXTI_Line8;
break;
default:
;

}
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //Falling下降沿 Rising上升

if(enable)
{
/* enable */
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
} else
{
/* disable */
EXTI_InitStructure.EXTI_LineCmd = DISABLE;
}

EXTI_Init(&EXTI_InitStructure);
switch(LineNo)
{ case 6:
EXTI_ClearITPendingBit(EXTI_Line6);
break;
case 8:
EXTI_ClearITPendingBit(EXTI_Line8);
break;
default:
;
}
}

void EXTI9_5_IRQHandler(void)
{
//struct rtgui_touch_device *spi_touch = &touch_dev;
/* disable interrupt */
if(EXTI_GetITStatus(EXTI_Line6) != RESET)
{
EXTI_Enable(0,6);

rt_sem_release(sem_touch_calc);

EXTI_ClearITPendingBit(EXTI_Line6);
}

#ifdef RT_USING_LWIP //enc28j60中断使用PA8

if(EXTI_GetITStatus(EXTI_Line8) != RESET)
{
rt_interrupt_enter();
EXTI_ClearITPendingBit(EXTI_Line8);
enc28j60_isr();
rt_interrupt_leave();

}
#endif /* RT_USING_LWIP */
}


你的问题可能是CS信号没处理好,导致同一个SPI总线上的设备发生冲突。如果enc28j60所挂的spi总线有多个设备,那么必须1个个轮流初始化,在初始化前把其他设备的CS拉高,以防冲突。
bpengj65359
bpengj65359 2015-02-06
谢谢您耐心的回答,我用的RT-Thread版本是1.2.0,请问是不是只要用到SPI就需要注册SPI总线?我之前在网上下了一个有关enc28j60+RTT的例子,用的是1.0.4,那个程序里面好像没有注册SPI总线,用的是RTT之前版本的enc28j60驱动,修改了成SPI1后,烧写到我的板子上是可以实现网络通信的,现在1.2.0的多了一个rt_components_init(),和之前的结构不一样了,在1.2.0版本中,不注册SPI总线就没法使用吗?谢谢!
microtomato
microtomato 2015-02-09
要在RT-Thread里使用设备是必须先注册的,即使1.0.4版本也是一样。你下的这个基于1.0.4的示例中spi驱动部分应该也是这么做的。1.0.4官方好像没有自带spi驱动,但1.2.0的源码包自带spi驱动。你可以直接使用1.2.0的spi驱动,位置:RT-Thread_1.2.0\components\drivers\spi,然后下载2.0.0的源码,在rt-thread-2.0.0\components\drivers\spi目录里找到enc28j60.c研究一下就知道怎么用了。

撰写答案

请登录后再发布答案,点击登录

发布
问题

分享
好友