KSMFYT 发表于 2014-12-21 16:44:54

关于ENC28J60 中断接收的问题,STM32F103+ENC28J60+uC/OS+LwIP

网上关于接收数据包enc28j60 的例程几乎清一色用的是轮询查看的方法,都说可以用中断来实现。我也想着用中断的方法看看,中断确实也可以实现数据包的接收,具体的代码(stm32库函数开发)如下:
1.配置一个stm32的外部中断输入引脚(连enc28j60 的int脚),下降沿触发方式
static void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//选择中断分组
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;//选择中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//相应优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void EXTI_PC5_Config(void)
{
        EXTI_InitTypeDef EXTI_InitStructure;
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO,ENABLE);                                                                                       
        NVIC_Configuration();
GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource5);
EXTI_InitStructure.EXTI_Line = EXTI_Line5;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿中断
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
}
2.中断程序
void EXTI9_5_IRQHandler(void)
{
         EXTI_ClearITPendingBit(EXTI_Line5); //stm32清中断标志
      //enc28j60Write(ECON2,ECON2_PKTDEC);
        OSIntNesting++;       
        ethernetif_input(&enc28j60);//收数据包
        if(OSIntNesting>0){           //退出中断,减少嵌套层数,允许任务切换
                   OSIntNesting--;
                }   
}
在实际情况中这样的方法可以调通但是存在一些问题:(同时观察Int脚的电平变化)
1.在程序下到板子中后,插上网线到电脑,如果是首次与电脑建立连接,Int脚电平会从原来的1(高电平)到0(低电平),之后稳定在0,这是在他们建立网络的过程中发生的,这样网络可以建立起来,但是Int脚一直是低电平,不能产生一个下降沿触发stm32接收中断,此时ping不通
2.在1的网络建立的基础上,再给板子下次刚才的程序,此时没有重新和电脑建立网络的过程,Int脚的电平会稳定在1,此时ping板子是正常的,enc28j60的int脚能正常的产生下降沿触发中断。
我试了很多次就是这样的,我就在想是不是建立连接的过程中3次握手对enc28j60有影响还是在这个过程中进入到中断后只是对stm32的中断标志清除,没有对enc28j60的ERP_PKTIF(接收数据包待处理中断标志位)进行清零,但是在2中又可以拼通,而且在中断中添加enc28j60Write(ECON2,ECON2_PKTDEC);(数据手册中说对PKTDEC置1时可以对PKTIF清0)反而ping不通了都

有没有好的处理办法的?

KSMFYT 发表于 2014-12-21 21:22:14

继续弄了一晚上,发现在2的情况下按下复位键后int脚电平会恢复为高,可以ping通。在ethernetif_input(&enc28j60);后添加 enc28j60Write(EIE,EIE_PKTIE); enc28j60Write(EIE,EIE_INTIE|EIE_PKTIE);貌似会比较经虐些,向1那样的做法不会使int脚拉低,连上网线ping通后再拔掉插上还可以接着ping通,不过还是不稳定

tangbo_designer 发表于 2015-1-5 13:27:45

用过这个芯片,有时候也会出现这个问题

漩涡鸣人 发表于 2015-12-4 15:42:09

这么经典的问题 居然没有人回答!

KSMFYT 发表于 2015-12-4 16:31:03

中断这样写的比较稳定一点,有需要的同学可以参考一下
void EXTI9_5_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line5) != RESET)
{
   EXTI_ClearITPendingBit(EXTI_Line5);
   p1 = low_level_input(&enc28j60);
   OSSemPost(EncSem);//释放一个信号量
   GPIO_WriteBit(GPIOC,GPIO_Pin_6,(BitAction)(1 - GPIO_ReadOutputDataBit(GPIOC,GPIO_Pin_6))); //LED1闪烁
   enc28j60WriteOp(ENC28J60_BIT_FIELD_SET,ECON2,ECON2_PKTDEC);
   enc28j60WriteOp(ENC28J60_BIT_FIELD_SET,EIE,EIE_INTIE|EIE_PKTIE);//看手册是啥寄存器吧,时间久了不大记得了,应该是清除或者是重开之类的
}

lotoohe 发表于 2016-3-8 20:10:46

mark一下
页: [1]
查看完整版本: 关于ENC28J60 中断接收的问题,STM32F103+ENC28J60+uC/OS+LwIP