打印
[STM32F1]

外部中断异常,求助

[复制链接]
2386|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
打算做一个增量式编码器位移量读取电路,

想用STM32外部中断来对脉冲进行计数.

选择了PB12,PB13,PB14这三个IO口,分别对应编码器的A,B,Z相.

PB12和PB13需要在上升沿和下降沿都对脉冲计数,就是四倍频计数.PB14需要在上升沿时对脉冲数量进行修正.

我用的是300线的编码器,正常情况下四倍频以后编码器转一圈应该是1200个脉冲数量,实际仿真的时候这个脉冲数量远远不对.

后来我把中断服务函数里只留下PB12.也就是只对A相这一个外部中断进行计数,仿真结果编码器转一圈脉冲计数的数量是对的,300线2倍频,600个脉冲.

经过反复测试发现,无论是中断服务函数里单独留下A或B相进行计数,脉冲数量都是对的,如果两相同时参与计数,那么脉冲数量就远远的不对了.

还有就是使用A或B相单独进行脉冲计数时,加入Z相中断判断(只做判断,然后清中断标志位,不做其它事情),也会影响计数的准确性.

以下是部分功能代码
void EXTI_Configuration(void)//配置外部中断
{
      EXTI_InitTypeDef EXTI_InitStructure;//EXTI初始化结构定义
   
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);   //复用时钟

    EXTI_ClearITPendingBit(EXTI_Line12);//清除中断标志
    EXTI_ClearITPendingBit(EXTI_Line13);
    EXTI_ClearITPendingBit(EXTI_Line14);
   
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource12);//选择GPIO管脚用作外部中断线
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource13);
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14);
   
    EXTI_InitStructure.EXTI_Line=EXTI_Line12 | EXTI_Line13;//外部中断线路选择
    EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt; //触发方式  中断触发
    EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Rising_Falling;//上升沿下降沿都触发           
    EXTI_InitStructure.EXTI_LineCmd=ENABLE;//使能

    EXTI_Init(&EXTI_InitStructure);//初始化
   
    EXTI_InitStructure.EXTI_Line=EXTI_Line14;//外部中断线路选择
    EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt; //触发方式  中断触发
    EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Rising;//上升沿触发           
    EXTI_InitStructure.EXTI_LineCmd=ENABLE;//使能
   
    EXTI_Init(&EXTI_InitStructure);//初始化
}

void EXTI15_10_IRQHandler(void)//中断服务程序
{         
    if(EXTI_GetITStatus(EXTI_Line12)==SET)//A相产生中断
    {
        
        dat = GPIOB->IDR & 0x3000;
        switch(dat)//读取AB状态
        {
            case 0x3000://A=1 B=1 理论反
            case 0x0000://A=0 B=0
                jishu += 1;
               
                break;
            case 0x1000://A=1 B=0 理论正
            case 0x2000://A=0 B=1
                jishu -= 1;
               
                break;   
        }
        EXTI_ClearFlag(EXTI_Line12);
        EXTI_ClearITPendingBit(EXTI_Line12);//清除中断请求标志
    }
   
//     else if(EXTI_GetITStatus(EXTI_Line13)==SET)//B相产生中断
//     {
//           
//         dat = GPIOB->IDR & 0x3000;
//         switch(dat)//读取AB状态
//         {
//             case 0x3000://B=1 A=1 理论正
//             case 0x0000://B=0 A=0
//                 jishu -= 1;
//                 
//                 break;
//             case 0x1000://B=0 A=1 理论反
//             case 0x2000://B=1 A=0
//                 jishu += 1;
//                 
//                 break;   
//         }
//         EXTI_ClearFlag(EXTI_Line13);
//         EXTI_ClearITPendingBit(EXTI_Line13);//清除中断请求标志
//     }


以下是仿真时外设的配置情况








求帮助...感激不尽...
沙发
mmuuss586| | 2014-7-3 11:24 | 只看该作者
为啥不用STM32的编码器接口

使用特权

评论回复
板凳
liang_ke|  楼主 | 2014-7-3 12:05 | 只看该作者
mmuuss586 发表于 2014-7-3 11:24
为啥不用STM32的编码器接口

STM32这一功能没注意到,我去试试.希望比外部中断好用.上边提到 的外部中断问题,一直困扰着我,也希望您能一并帮我分析一下,期待并感谢您的回复.

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

8

主题

33

帖子

0

粉丝