打印
[国产单片机]

STC单片机PCA中断测低电平时间乱跑的问题

[复制链接]
2315|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
xiao20041128|  楼主 | 2013-7-18 10:54 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
三个通道测低电平时间,方法是开PCA边沿中断,上下降沿时间互减,但测试中一个方波进来,上升沿中断22次,下降沿中断居然有600多次
到底什么问题,搞了几天都不行!!!!
还有设置PCA中断优先级会导致中断时死机,真是无语了!
只开了PCA中断,其他中断全关

PCA初始化程序如下:
//PCA中断  相关功能中文手册316页
CCON = 0;                       //Initial PCA control register
    CR = 0;
CF = 0;                                //PCA timer stop running
    CCF0 = 0;                                //Clear CF flag
    CCF1 = 0;                                //Clear all module interrupt flag
CCF2 = 0;
    CL = 0;                         //Reset PCA base timer
    CH = 0;
    CMOD = 0x01;                    //Set PCA timer clock source as Fosc/12
//    CMOD = 0x00;                                //Enable PCA timer overflow interrupt
    CCAPM0 = 0x31;                  //PCA module-0 capture by a negative tigger on CEX0(P3.7) and enable PCA interrupt
CCAPM1 = 0x31;                  //PCA1
CCAPM2 = 0x31;                  //PCA2  跳变边沿中断

EPCAI = 1;      //PCA MODEL INT EN
// IP  |= 0x00;    //中断优先级设置会引起死机!!!!!
// IPH |= 0x40;   
   
// IP  = 0x40;
// IPH = 0x40;         //PCA中断最高优先级
// Delay( 10 );
CR = 1;                         //PCA timer start run  

EA  = 1;      //总中断


PCA中断程序:
void PCA_isr() interrupt 6 using 1
{
        unsigned int buf;

        if( CF )
        {       
                CF = 0;
        //        CL = 0;
        //        CH = 0;
                if( Timing[0] )
                        PCACount[0]++;
                if( Timing[1] )
                        PCACount[1]++;
                if( Timing[2] )
                        PCACount[2]++;         
        }

    //测量方式,下降沿记录一次定时器值,溢出中断检查计数中的的Count加1                      
       
        if( CCF0 )                                                         //PCA0中断
        {       
                CCF0 = 0;                           
                buf = CCAP0H;
                buf <<= 8;
                buf += CCAP0L;                
        //        CCAPM0 = 0x31;
                if( PCA0 )                                                 //上升沿
                {                       
                //        TimeCount[0] = (65536*PCACount[0] + buf-BufTimer[0])/100;
                        TimeCount[0]++;                                                                          
                        Timing[0]         = 0;
                        PCACount[0] = 0;
                        CCAPM0 = 0x11;
                }
                else if( !PCA0 )                                                           //下降沿
                {
                        TimeCount[1]++;                        Timing[0] = 1;
                        BufTimer[0] = buf;       
                        CCAPM0 = 0x21; //开启上升沿中断
                }       
        }
       
        if( CCF1 )
        {       
                CCF1 = 0;                        
                buf = CCAP1H;
                buf <<= 8;
                buf += CCAP1L;
        //        CCAPM1 = 0x31;
                if( PCA1 )                                                 //上升沿
                {                       
                //        TimeCount[1] = (65536*PCACount[1] + buf-BufTimer[1])/100;
                        Timing[1]         = 0;
                        PCACount[1] = 0;
                        CCAPM1 = 0x11;
                }
                else if( !PCA1 )                                                          //下降沿
                {
                        TimeCount[1]++;
                        Timing[1] = 1;
                        BufTimer[1] = buf;
                        CCAPM1 = 0x21;
                }                           
        }
       
        if( CCF2 )
        {       
                CCF2 = 0;         //Clear interrupt flag
                buf = CCAP2H;
                buf <<= 8;
                buf += CCAP2L;
        //        CCAPM2 = 0x31;                               
                if( PCA2 )                                                 //上升沿
                {       
                        TimeCount[2] = (65536*PCACount[2] + buf-BufTimer[2])/100;
                        Timing[2]         = 0;
                        PCACount[2] = 0;
                        CCAPM2 = 0x11;
                }
                else if( !PCA2 )                                                          //下降沿
                {
                        Timing[2] = 1;
                        BufTimer[2] = buf;
                        CCAPM2 = 0x21;
                }
        }               
               
}

测试中TimeCount[1]次数是TimeCount[0]的30多倍,按照正常方波进来不可能的。10Hz方波进来TimeCount[0]的值是对的!

相关帖子

沙发
xiao20041128|  楼主 | 2013-7-18 10:55 | 只看该作者
端口的头文件
sbit PCA0      =   P3^7;  
sbit PCA1      =   P3^5;  
sbit PCA2      =   P2^0;

使用特权

评论回复
板凳
ayb_ice| | 2013-7-18 11:37 | 只看该作者
TimeCount[2] = (65536*PCACount[2] + buf-BufTimer[2])/100;

你这中断处理时间过长,
但不一定是问题所在地

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
xiao20041128 + 1 问题已经解决,就不鄙视国产了.
地板
ayb_ice| | 2013-7-18 11:37 | 只看该作者
强烈建议中断只记录数据,处理放在主循环中

使用特权

评论回复
5
ayb_ice| | 2013-7-18 11:39 | 只看该作者
TimeCount[2] = (65536*PCACount[2] + buf-BufTimer[2])/100;

这个算式可能溢出的风险

使用特权

评论回复
6
xiao20041128|  楼主 | 2013-7-19 08:49 | 只看该作者
测试的时候只加了CCF1的中断,其他两个没有加信号,所有时间应该不是问题!

使用特权

评论回复
7
xiao20041128|  楼主 | 2013-7-19 08:50 | 只看该作者
STC只是垃圾货,一堆BUG的芯片,技术支持还装B,说没时间

使用特权

评论回复
8
xiao20041128|  楼主 | 2013-7-19 08:56 | 只看该作者
如此国货如何才能做好?

使用特权

评论回复
9
gx_huang| | 2013-7-19 09:30 | 只看该作者
先检查自己的程序问题吧。
99.9%是你自己的问题。

使用特权

评论回复
10
xiao20041128|  楼主 | 2013-12-22 14:58 | 只看该作者
确实是单片机有问题,不过可以在中断中再加个软件处理,过滤掉不必要的中断
由于乱进中断,所以测试结果有一点误差,不大

使用特权

评论回复
11
McuPlayer| | 2013-12-22 16:11 | 只看该作者
你测试用的低电平宽度是多少?用示波器抓一下看看

使用特权

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

本版积分规则

21

主题

69

帖子

0

粉丝