搜索
bottom↓
回复: 13

mega 128一次捕获中断竟然引发两次捕获~实在匪夷所思

[复制链接]

出0入0汤圆

发表于 2013-12-3 17:21:12 | 显示全部楼层 |阅读模式
定时器T1捕获电机的码盘脉冲,发现发生捕获后,进入捕获中断两次,实在是想不通,其中PD4是定时器的捕获引脚
简单点说就是一次下降沿导致了两个捕获中断,好郁闷

求大神救命


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

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

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

 楼主| 发表于 2013-12-3 17:35:34 | 显示全部楼层
migrant 发表于 2013-12-3 17:29
通常是配置错误造成的

/************************************************
文件:main.c
用途:
注意:内部8M晶振
************************************************/
//#include "config.h"
#include <iom128v.h>                //包含型号头文件
#include <macros.h>                        //包含"位"操作头文件
#include <stdio.h>                        //标准输入输出头文件
#include <AVRdef.h>
#define uchar unsigned char
#define uint unsigned int
#pragma interrupt_handler timer1_capture: 12  //指定定时器捕获中断函数
#pragma interrupt_handler timer1_over: 15 //指定定时器溢出中断函数
//#pragma interrupt_handler EXT_INT3: 5 //外部中断INT3
//unsigned int fault = 0;
uint freq=0,i = 1,j = 0,flag = 0,a = 0,b = 0,flag_open = 0;

void Init_IO()//io初始化
{
         DDRA |= BIT(0);//继电器控制端IO口初始化
         PORTA &= ~BIT(0);
}
void timer1_capture()
{
          freq++;
        delay_nms(100);
        if(freq == 63355)
        {
                 freq = 0;
        }
        //flag_open = 1;//间接判断电机是否打开,排除大循环电机一直运动
}

void timer1_over()//200MS产生中断一次
{
        TCNT1= 0XC2F7;//1S 0X85ED; 200mS
        i = freq;
        flag++;
        switch(flag)
        {
                case 1:
                        a = freq;
                        break;
                case 2:
                        b = freq;
                        break;
                case 3:
                        b = 1;
                        break;
                default:
                        flag = 0;
                        break;
                       
        }
        //判断两次0.5s的freq(电机转动计数标志)是否相等
        if((a == b)&(a != 0)&(b != 1))
        {
                flag_open = 1;
                flag = 0;
                a = 1;
                b = 1;
        }
        else
                flag_open = 0;
        //TCNT1= 0X85ED;//1S 0X85ED; 200mS
}

/*void EXT_INT3(void)
{
         up_to_down = 1;
         j++;
         if(j = 1)
         {
                
         }
}
*/
void Init_TIMER1(void)
{
         TIMSK |= BIT(5)|BIT(2);//开启溢出中断和捕获中断
         TCCR1A = 0X00;//TCCR1A Bit 76543210   COM1A1 COM1A0 COM1B1 COM1B0 COM1C1 胀ǘ丝诓僮鳎?COM1C0 WGM11 WGM10 芆CnA/OCnB/OCnC未连接,普通模式
         TCCR1B |= BIT(2)|BIT(7);//clkI/O/1 ( 256预分频),使能噪声抑制器,下降沿捕获
         TCCR1B &= ~BIT(6);
         TCCR1C = 0X00;//无强制转换
         TCNT1= 0XC2F7;//1S 0X85ED; 200mS;//0XE795定时200ms 0X85ed;// 定时1s,TCNT1 = 0X00;//设置计数器初始值 TCNT1H = 0X00;TNCT1L = 0X00;
         /*
         500ms定时器时间计算
         65536-(8M/256)*0.5=49911(0XC2F7)
         */
         DDRD &= ~BIT(4);//计数捕获IO口初始化
         PORTD |= BIT(4);
}

void main(void)
{
        Init_IO();
        Init_TIMER1();
       
        EICRA |= BIT(7);//INT3下降沿产生异步中断
        EIMSK |= BIT(3);//INT3外部中断使能
        SREG |= BIT(7);//SREG=0x80;    //开全局中断数据手册的8页
       
        while(1)
        {
                //a = TCNT1;
                if(flag_open == 1)
                {
                       
                       
                        SREG &= ~BIT(7);//SREG=0x80;    //关全局中断
                        flag_open = 0;
                        freq = 0;//freq重新赋值
                       
                       
                        //a = TCNT1;
                        delay_nms(500);//延时1.5s机械爪加紧
                        //a = TCNT1;
                        DDRA |= BIT(0);
                        PORTA |= BIT(0);//继电器动作断开电源
                        delay_ns(3);       
                        //a = TCNT1;
                        PORTA &= ~BIT(0);//继电器动作接通电源
                        //a = TCNT1;
                       
                        TCNT1= 0XC2F7;
                        TIFR |= BIT(2);//
/************************************************
Bit 2 – TOV1:T/C1溢出标志
该位的设置与T/C1的工作方式有关。工作于普通模式和CTC模式时,T/C1溢出时TOV1
置位。对工作在其它模式下的TOV1标志位置位,见P 122Table 61 。
执行溢出中断服务程序时OCF1A自动清零。也可以对其写入逻辑"1”来清除该标志位。
************************************************/
                        SREG |= BIT(7);
                }
        }
}

程序写的比较丑,我感觉没有配置错,捕获和定时都按时发生,就是捕获的时候,发生了两次中断,很郁闷,

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2013-12-3 17:50:21 | 显示全部楼层
luguobing 发表于 2013-12-3 17:45
MEGA169P  碰到类似问题过,进中断后     禁用中断    处理完后     主函数再启用中断 ...

这样就解决了?我是在进入if条件语句中先关闭中断,执行完成后,打开总中断,打开中断后,马上进入了捕获中断,连续发生两次,但是电机根本就没有动

出0入0汤圆

发表于 2013-12-3 17:21:50 | 显示全部楼层
在中断中进行延时或者在硬件上加电容防抖。

出0入0汤圆

 楼主| 发表于 2013-12-3 17:25:08 | 显示全部楼层
fsclub 发表于 2013-12-3 17:21
在中断中进行延时或者在硬件上加电容防抖。

我试下在捕获中断里延时20ms

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2013-12-3 17:29:05 | 显示全部楼层
通常是配置错误造成的

出0入0汤圆

 楼主| 发表于 2013-12-3 17:29:52 | 显示全部楼层
fsclub 发表于 2013-12-3 17:21
在中断中进行延时或者在硬件上加电容防抖。

延时了20ms和100ms都不行,加电容我觉等不要把,因为42码的电机变化很快的,我就是要捕捉着些 脉冲

出0入0汤圆

发表于 2013-12-3 17:30:30 | 显示全部楼层
如果是毛刺导致,可以通过忽略特别短时间的那个值。

出0入0汤圆

 楼主| 发表于 2013-12-3 17:36:02 | 显示全部楼层
migrant 发表于 2013-12-3 17:30
如果是毛刺导致,可以通过忽略特别短时间的那个值。

不是毛刺导致的

出0入0汤圆

 楼主| 发表于 2013-12-3 17:40:59 | 显示全部楼层
进入大循环的if语句后,执行完后,就立马进入到捕获中断,连续发生两次捕获中断

出0入0汤圆

发表于 2013-12-3 17:45:24 | 显示全部楼层
MEGA169P  碰到类似问题过,进中断后     禁用中断    处理完后     主函数再启用中断

出0入0汤圆

发表于 2013-12-3 17:53:13 | 显示全部楼层
看下编码器输出的频率多高, 如果两次中断间隔太近,就丢弃一个中断。

出0入42汤圆

发表于 2013-12-3 21:37:14 | 显示全部楼层
既然坚定地认为不是毛刺, 只好告诉你一个更不好的猜测, 中断太慢了...

出0入0汤圆

发表于 2013-12-4 08:25:26 | 显示全部楼层
远离代码 发表于 2013-12-3 17:29
延时了20ms和100ms都不行,加电容我觉等不要把,因为42码的电机变化很快的,我就是要捕捉着些 脉冲 ...

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

本版积分规则

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

GMT+8, 2024-7-23 22:13

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

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