搜索
bottom↓
回复: 5

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

[复制链接]

出0入0汤圆

发表于 2014-12-21 16:44:54 | 显示全部楼层 |阅读模式
网上关于接收数据包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不通了都

有没有好的处理办法的?

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

 楼主| 发表于 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通,不过还是不稳定

出0入0汤圆

发表于 2015-1-5 13:27:45 | 显示全部楼层
用过这个芯片,有时候也会出现这个问题

出0入0汤圆

发表于 2015-12-4 15:42:09 | 显示全部楼层
这么经典的问题 居然没有人回答!

出0入0汤圆

 楼主| 发表于 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);//看手册是啥寄存器吧,时间久了不大记得了,应该是清除或者是重开之类的
}

出0入0汤圆

发表于 2016-3-8 20:10:46 | 显示全部楼层
mark一下
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-27 10:40

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表