5220|18

64

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

版主,请教一个外口断的问题。 [复制链接]

我用的是(STM32F103R8) PC12作下降沿触发,外部输入的时序如下图:
exit.JPG
现在出现一个情况,搞了好长时间也没查出问题。
此帖出自stm32/stm8论坛

最新回复

                                 按照我说的做法,应该已经可以屏蔽掉7us和12us下降沿的中断了,不知楼主是否已经实现了?  详情 回复 发表于 2010-12-5 19:05
点赞 关注
 

回复
举报

68

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
void CpuIoInit(void)
{
       
        ///////(PA8)用于MCO输出/////
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;//
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;                //复用推挽输出
        GPIO_Init(GPIOA,&GPIO_InitStructure);
        ///////(PA12)用于对DSP的复位控制输出/////
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;//
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;                //开漏输出
        GPIO_Init(GPIOA,&GPIO_InitStructure);
        ///###########################  配置GPIOB  ################################################################
        //////(PB8)用于前面报警灯控制输出//////
        GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_8);//
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                //开漏输出
        GPIO_Init(GPIOB,&GPIO_InitStructure);
        //////(PC12)用于CPU读取DSP中断线的状态//////
        GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_12);
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;                //输入浮空
        GPIO_Init(GPIOC,&GPIO_InitStructure);
        /////////////////////////////////////////////////////////
}
void NVIC_Configuration(void)
{
        NVIC_InitTypeDef NVIC_InitStructure;


        #ifdef  VECT_TAB_RAM   
                NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);                // Set the Vector Table base location at 0x20000000
        #else  // VECT_TAB_FLASH  
                NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);        // Set the Vector Table base location at 0x08000000
        #endif
        /* Configure the NVIC Preemption Priority Bits */  
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);                //设置为16级抢占式优先级
        ////////////////////////////////
        NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQChannel;        //PC12
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;        //EX0,最高优先级(与DSP的通讯)
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
}
void CpuExitInterrupetInit(void)
{
        EXTI_InitTypeDef EXTI_InitStructure;

//        NVIC_StructInit(EXTI_InitStructure);        //把NVIC_InitStruct中的每一个参数按缺省值填入
        GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource12);                //dsp
        EXTI_InitStructure.EXTI_Line = DSP_EXTI_INTERRUPT;
        EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
        EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;                        //外部下降沿中断
        EXTI_InitStructure.EXTI_LineCmd = ENABLE;
        EXTI_Init(&EXTI_InitStructure);
        ///////外中断NVIC设置/////
}
void sysInit(void)
{
        delay(3000);
        sysClockInit();                        //必须放在外设初始化的前面,因为APB1,APB2,AFIO时钟的原因
        RCC_MCOConfig(RCC_MCO_HSE);        //MCO输出时钟,给外面的DSP用。
        NVIC_Configuration();                //中断初始化
        CpuIoInit();                                //IO口初始化
        //DSP_RST_CLR;                                //复位DSP接低
        //RS485RXD_ON;
        //DisplayInit();                                //
        //Uart1Init();                                //程序调试时用
        //        Uart2Init();                        //
        //Uart3Init();                                //KFT接收外部的控制。
        //E24c02Init();                                //
        //TIM2Init();                                //用TIM2作为系统时钟
        CpuExitInterrupetInit();        //CPU外中断初始化       
        ////////////////////////
}
void main(void)
{

        sysInit();
        while(1)
        {
                LED_OFF;        //
        }
}


//////////////中断处理////////////////////////
#define DSP_EXTI12_PIN                (GPIOC->IDR & 0x1000)                //DSP外中断管脚为PC12
void EXTI15_10_IRQHandler(void)
{
        LED_ON;
        //////////////////////////////////////////
        while(DSP_EXTI12_PIN==0){NOP;}//1               
        while(DSP_EXTI12_PIN){NOP;}        //2
        while(DSP_EXTI12_PIN==0){NOP;}//3
        while(DSP_EXTI12_PIN){NOP;}        //4
        while(DSP_EXTI12_PIN==0){NOP;}//5
        //////////////////////////////////////////////

    EXTI->PR = EXTI_Line12;                        //退出时必须清中断
}
此帖出自stm32/stm8论坛
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
最上面是外部输入的周期波形。
上面是我的程序,main循环里关LED,在中断里开LED,
我要实现的功能是,在PC12的第一个下降沿产生中断,进入中断后我就扫描PC12上的几个电平变化(与其它的CPU交换数据),
但现在出现了这个情况,我如果把EXTI15_10_IRQHandler()里面的几个while(DSP_EXTI12_PIN)去掉后工作是对了,包括中断的次数也是对的(通过LED脚与中断输入脚对比,用示波器测得),但如里加了中断函数里那几个while后就不对了,全速度执行就跟本退不出中断,单步还可以退出,
请问这是什么原因啊?查了两天也找不出原因了。
谢谢!
此帖出自stm32/stm8论坛
 
 

回复

69

帖子

0

TA的资源

一粒金砂(初级)

4
 
                                 在里面死循环了
此帖出自stm32/stm8论坛
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(中级)

5
 
                                 没有死循环,我单步可以出来的,再说我的中断输入是不停的有的,我扫描的顺序是跟输入波形对应的呀。5个扫描完了就刚好退出啊,我在想是不是在中断里面不能接收多个中断输入的扫描啊。
此帖出自stm32/stm8论坛
 
 
 

回复

59

帖子

0

TA的资源

一粒金砂(初级)

6
 
我还发现一个问题噢,如果是只加一个while的话,则退出的时候只加一条EXTI->PR = EXTI_Line12; 在退出的时候是可以的,
void EXTI15_10_IRQHandler(void)
{
        LED_ON;
        //////////////////////////////////////////
        while(DSP_EXTI12_PIN==0){NOP;}//1               
        //////////////////////////////////////////////

    EXTI->PR = EXTI_Line12;                        //退出时必须清中断
}
但如果是加2个while就话,则要在退出的时候加2条EXTI->PR = EXTI_Line12; 如下:
void EXTI15_10_IRQHandler(void)
{
        LED_ON;
        //////////////////////////////////////////
        while(DSP_EXTI12_PIN==0){NOP;}//1               
        while(DSP_EXTI12_PIN){NOP;}//2               
        //////////////////////////////////////////////

    EXTI->PR = EXTI_Line12;                        //退出时必须清中断
    EXTI->PR = EXTI_Line12;                        //退出时必须清中断
}
上面这样就可以完全退出,要不然main主循环跟本就执行不到。

版主主帮我分析一下啊,我在想是不是不能在中断里面等待下一个中断再来啊,这样的话我就麻烦了。
此帖出自stm32/stm8论坛
 
 
 

回复

79

帖子

0

TA的资源

一粒金砂(初级)

7
 
                                1) 为什么要加这个没有必要的while?2) 进while之前先清中断标志。
此帖出自stm32/stm8论坛
 
 
 

回复

68

帖子

0

TA的资源

一粒金砂(初级)

8
 
void EXTI2_IRQHandler(void) //EXTI15_10_IRQHandler   
{
if(rsFlag)
{
  rsFlag = OFF;
  RS485_CTR_SET;
}
else
{
  rsFlag = ON;
  RS485_CTR_CLR;
}
WARN_LED_Q_ON;
    EXTI->PR = DSP_EXTI2_INTERRUPT;   //退出时必须清中断
while(DSP_EXTI12_PIN==0){NOP;}//1
    EXTI->PR = DSP_EXTI2_INTERRUPT;   //退出时必须清中断
while(DSP_EXTI12_PIN){NOP;} //2
    EXTI->PR = DSP_EXTI2_INTERRUPT;   //退出时必须清中断
while(DSP_EXTI12_PIN==0){NOP;}//3
    EXTI->PR = DSP_EXTI2_INTERRUPT;   //退出时必须清中断
while(DSP_EXTI12_PIN){NOP;} //4
    EXTI->PR = DSP_EXTI2_INTERRUPT;   //退出时必须清中断
while(DSP_EXTI12_PIN==0){NOP;}//5
// WARN_LED_Q_OFF;
    EXTI->PR = DSP_EXTI2_INTERRUPT;   //退出时必须清中断
}
这样也不行,
因为我要与DSP交换数据,从第一次下降中断开始之后每次跳变交换1字节数据,这样速度更快,
这样的话STM32F103RBT6这颗料能不能做到(现在我感觉除非这颗料坏了,要不然我真有点怀疑好像不能这样做,我现在的感觉好像是产生中断后必须得退出来,不能等在里面)
DSP发送的中断信号如下:
DSCF3813.JPG
此帖出自stm32/stm8论坛
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

9
 
另外我还发现一个问题,我如果用PC12作中断输入,并且在中断里while((GPIOC->IDR & 0x1000)==0){NOP;},这条指令可以通过,当我用PD2作中断输入时,它可以产生中断,但中断后((GPIOD->IDR & 0x0004)==0){NOP;},它会死在这里,就是说外部变成高电平后,这里死终读取为0,(刚好两个脚挨在一起,我就把它们焊接在一起了),当然void EXTI2_IRQHandler(void)与void EXTI15_10_IRQHandler(void)我都是每次只用一个,
另外我将PC12与PD2都设置为“//输入浮空”
//////(PC12)用于CPU读取DSP中断线的状态//////
GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_12);
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  //输入浮空
GPIO_Init(GPIOC,&GPIO_InitStructure);
/////////////////////////////////////////////////////////
//////(PD2)用于CPU读取DSP中断线的状态//////
GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_2);
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  //输入浮空
GPIO_Init(GPIOD,&GPIO_InitStructure);
此帖出自stm32/stm8论坛
 
 
 

回复

60

帖子

0

TA的资源

一粒金砂(初级)

10
 
void EXTI2_IRQHandler(void)        //EXTI15_10_IRQHandler          
{
        WARN_LED_Q_ON;
//        delay(800);                //延迟88us
        while(DSP_EXTI12_PIN==0){NOP;NOP;NOP;NOP;NOP;NOP;}  //1
        while(DSP_EXTI12_PIN){NOP;NOP;NOP;NOP;NOP;NOP;NOP;} //2
        while(DSP_EXTI12_PIN==0){NOP;NOP;NOP;NOP;NOP;NOP;}  //3
        while(DSP_EXTI12_PIN){NOP;NOP;NOP;NOP;NOP;NOP;NOP;} //4
        while(DSP_EXTI12_PIN==0){NOP;NOP;NOP;NOP;NOP;NOP;}  //5
        WARN_LED_Q_OFF;
        /////////////////////////////////////
        EXTI_ClearITPendingBit(DSP_EXTI2_INTERRUPT);
}
还发现一个问题,我如果用delay(800)(延迟88us),代替下面的5个while这样就没有问题,但为什么我一直读取IO就会有问题呢?
此帖出自stm32/stm8论坛
 
 
 

回复

74

帖子

0

TA的资源

一粒金砂(初级)

11
 
                                 不是你的中断没有退出,而是在中断里面又产生了中断信号,硬件会记住新产生的中断,在此次中断退出之后马上又重新进入中断
此帖出自stm32/stm8论坛
 
 
 

回复

84

帖子

0

TA的资源

一粒金砂(初级)

12
 
                                 而后一次进入的中断是在你图上标识的7us的下降沿那个脉冲产生的中断,而实际上当前的信号处于115us高电平中间那一段,这时候在中断里面当然读不到正确的脉冲序列
此帖出自stm32/stm8论坛
 
 
 

回复

67

帖子

0

TA的资源

一粒金砂(初级)

13
 
                                 按照楼主想法,正确的做法应该是,在21us的下降沿进入中断之后,先关闭此中断通道,在完成脉冲序列的读取之后,退出中断之前除了 需要“EXTI->PR = EXTI_Line12;  //退出时必须清中断”还需要清除NVIC通道里面的挂起位,对应的库函数为NVIC_ClearIRQChannelPendingBit(EXTI15_10_IRQChannel);然后在开启此通道的中断,最后退出中断,这样应该可以了
此帖出自stm32/stm8论坛
 
 
 

回复

81

帖子

0

TA的资源

一粒金砂(初级)

14
 
后来又仔细想了想,其实中断也不必关闭的,只需要退出中断之前调用:
EXTI->PR = EXTI_Line12;
NVIC_ClearIRQChannelPendingBit(EXTI15_10_IRQChannel);
就可以了,这样就不会进入不该进入的中断了
此帖出自stm32/stm8论坛
 
 
 

回复

61

帖子

0

TA的资源

一粒金砂(初级)

15
 
                                 谢谢了,再试试,第三天了,有点头大。
此帖出自stm32/stm8论坛
 
 
 

回复

80

帖子

0

TA的资源

一粒金砂(初级)

16
 
                                 LZ搞了2天也没有告诉我“为什么要加这个没有必要的while?”
此帖出自stm32/stm8论坛
 
 
 

回复

68

帖子

0

TA的资源

一粒金砂(初级)

17
 
不好意思,真的是我错了,while()惹的货,看来在5颗树上掉死也有问题,DSP他MD发的脉冲不一定我是从第一个开始中断,所以产生了移位,在while里加个计数器就好了,
但是,我现在也没有搞定,我用PD2作中断,在外中断产生后扫描PD2为什么一直是0,而他的邻居PC12却可以,我两个口都设置为付空输入啊,所以现在我就把两个脚焊接在一下,用PD2作中断,扫描PC12,
(我用的是STM32F103RBT6,刚好PC12与PD2是邻居)。
此帖出自stm32/stm8论坛
 
 
 

回复

56

帖子

0

TA的资源

一粒金砂(初级)

18
 
楼主不要纠结PD2 上的问题,先把PC12上的功能实现了再说吧。另外你说“在while里加个计数器”不知是何意思?按照你在3楼的说法就是在脉冲序列的第一个下降沿产生中断之后再中断里面在去查询这个脉冲序列是否就是你需要的你在用这些
while(DSP_EXTI12_PIN==0){NOP;NOP;NOP;NOP;NOP;NOP;}  //1
        while(DSP_EXTI12_PIN){NOP;NOP;NOP;NOP;NOP;NOP;NOP;} //2
        while(DSP_EXTI12_PIN==0){NOP;NOP;NOP;NOP;NOP;NOP;}  //3
        while(DSP_EXTI12_PIN){NOP;NOP;NOP;NOP;NOP;NOP;NOP;} //4
        while(DSP_EXTI12_PIN==0){NOP;NOP;NOP;NOP;NOP;NOP;}  //5
去查询的时候为什么还要加个NOP呢;等你的六个NOP出来有可能下一个你要查询的脉冲都已经过去了,如果你非要在中断里面用while的话建议把循环里面的NOP全部去掉
此帖出自stm32/stm8论坛
 
 
 

回复

66

帖子

0

TA的资源

一粒金砂(初级)

19
 
                                 按照我说的做法,应该已经可以屏蔽掉7us和12us下降沿的中断了,不知楼主是否已经实现了?
此帖出自stm32/stm8论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表