飞思卡尔定时中断程序3.docx

上传人:b****1 文档编号:661007 上传时间:2023-04-29 格式:DOCX 页数:21 大小:19.74KB
下载 相关 举报
飞思卡尔定时中断程序3.docx_第1页
第1页 / 共21页
飞思卡尔定时中断程序3.docx_第2页
第2页 / 共21页
飞思卡尔定时中断程序3.docx_第3页
第3页 / 共21页
飞思卡尔定时中断程序3.docx_第4页
第4页 / 共21页
飞思卡尔定时中断程序3.docx_第5页
第5页 / 共21页
飞思卡尔定时中断程序3.docx_第6页
第6页 / 共21页
飞思卡尔定时中断程序3.docx_第7页
第7页 / 共21页
飞思卡尔定时中断程序3.docx_第8页
第8页 / 共21页
飞思卡尔定时中断程序3.docx_第9页
第9页 / 共21页
飞思卡尔定时中断程序3.docx_第10页
第10页 / 共21页
飞思卡尔定时中断程序3.docx_第11页
第11页 / 共21页
飞思卡尔定时中断程序3.docx_第12页
第12页 / 共21页
飞思卡尔定时中断程序3.docx_第13页
第13页 / 共21页
飞思卡尔定时中断程序3.docx_第14页
第14页 / 共21页
飞思卡尔定时中断程序3.docx_第15页
第15页 / 共21页
飞思卡尔定时中断程序3.docx_第16页
第16页 / 共21页
飞思卡尔定时中断程序3.docx_第17页
第17页 / 共21页
飞思卡尔定时中断程序3.docx_第18页
第18页 / 共21页
飞思卡尔定时中断程序3.docx_第19页
第19页 / 共21页
飞思卡尔定时中断程序3.docx_第20页
第20页 / 共21页
亲,该文档总共21页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

飞思卡尔定时中断程序3.docx

《飞思卡尔定时中断程序3.docx》由会员分享,可在线阅读,更多相关《飞思卡尔定时中断程序3.docx(21页珍藏版)》请在冰点文库上搜索。

飞思卡尔定时中断程序3.docx

飞思卡尔定时中断程序3

2D64定时器中断和频率捕捉中断冲突问题

    一、首先大致功能:

    1:

四路频率捕捉中断,要求可同时输入四路,也可任意输入一路、两路或者三路(10~2.5KHz)。

    2、将捕捉到的频率通过四路PWM依次输出,要求实时、稳定、输入多少输出就为多少(误差:

千分之二)。

    3:

定时器中断,1毫秒中断一次。

利用定时器屏蔽10Hz(100ms)以下的频率或者无频率输入时,置为0,屏蔽输出。

    二、调试过程 

    1、开始使用定时器中断和频率捕捉中断,频率捕捉中断开通方法:

初始化四路全部开通, 进入第一路捕捉中断,开通第二路捕捉中断,关闭第一路捕捉中断 

          进入第二路捕捉中断,开通第三路捕捉中断,关闭第二路捕捉中断 

          进入第三路捕捉中断,开通第四路捕捉中断,关闭第三路捕捉中断 

          进入第四路捕捉中断,开通第一路捕捉中断,关闭第二路捕捉中断形成一个环状,只有当频率全部有输入时才能采集正常,有任意一路没有输入时都将停止中断的执行。

 

    存在问题,当四路频率全部输入时,捕捉正常,但当只有一路或者两路或者三路输入时,能进入中断的那几路也只能响应一次中断。

程序如下:

#pragma CODE_SEG __NEAR_SEG NON_BANKED

interrupt void    MDC_ISR()     //定时器1ms中断一次

{

    CpuCounter++;       //工作指示灯计数器,500ms翻转一次

    if(ptflag0==1)    //10Hz以下或者无输入时计数,进入捕捉中断标志和计数清零,中断结束时打开标志

    {      

        ptcount0++;

    }

    if(ptflag1==1) 

    {     

        ptcount1++;

    }

    if(ptflag2==1) 

    {     

        ptcount2++;

    }

    if(ptflag3==1) 

    {     

        ptcount3++;

    } 

    if(ptcount0>100)  //10Hz以下或者无输入时不允许输出

    {

        ptcount0=0;     //计数清零

        flagECT0=0;     //标志清零

        fin1=0;         //频率置为0

        PTH_PTH7=0;     //指示灯熄灭

        PWME=PWME&0xfc; //不允许输出

    }

    if(ptcount1>100) 

    {

        ptcount1=0;

        flagECT1=0; 

        fin2=0;

        PTH_PTH6=0; 

        PWME=PWME&0xf3;

    }

    if(ptcount2>100) 

    {

        ptcount2=0;

        flagECT2=0; 

        fin3=0;

        PTH_PTH5=0; 

        PWME=PWME&0xcf;

    }

    if(ptcount3>100) 

    {

        ptcount3=0;

        flagECT3=0; 

        fin4=0;

        PTH_PTH4=0; 

        PWME=PWME&0x3f;

    } 

        

    if(CpuCounter>=500)  //处理器工作指示灯

    {       

        cpuflag=1;

        CpuCounter=0;

    }

    MCFLG_MCZF=1;  

}

interrupt void PT3_isr() 

    DisableInterrupts;  //总中断关闭

    ptflag3=0;          //清除无输入或者10Hz以下频率标志

    ptcount3=0;         //清除无输入或者10Hz以下频率计数器

    TIE_C0I = 1;   //开放ECT0局部中断    

    TFLG1_C3F=1;      //中断标志寄存器对C3F清零

    //newcount3=TC3; //读一次TCx

    if(TC3>TC3H)

    {

        count3=TC3-TC3H;

    } 

    else

    {              

        count3=65535-TC3H+TC3;

    } 

    if((count3>148)&&(count3<37450))  //10~2.5KHz有效,其余无效   

    {

        flagECT3=1;   //输出标志置一

        PWME=PWME|0xc0;   //允许输出

    } 

    else    //无效不允许输出

    {

        flagECT3=0;    //输出标志清零

        fin4=0;

        PTH_PTH4=0; 

        PWME=PWME&0x3f;   //不允许输出

    }

    ptflag3=1;      //打开无输入或者10Hz以下频率标志

    ptcount3=0;     //清除无输入或者10Hz以下频率计数器

    EnableInterrupts;  //总中断开启

    TIE_C3I = 0;    //关闭ECT3局部中断    

}

interrupt void PT2_isr() 

{

    DisableInterrupts; 

    ptflag2=0;

    ptcount2=0;

    TIE_C3I = 1;    //开放ECT3局部中断    

    TFLG1_C2F=1;    //中断标志寄存器对C2F清零

    //newcount2=TC2;

    if(TC2>TC2H)

    {

        count2=TC2-TC2H;

    } 

    else

    {

        count2=65535-TC2H+TC2;

    }  

    if((count2>148)&&(count2<37450))  //570  ->7hz   

    {

        flagECT2=1;

        PWME=PWME|0x30;

    } 

    else

    {

        flagECT2=0; 

        fin3=0;

        PTH_PTH5=0; 

        PWME=PWME&0xcf;

    }

    ptflag2=1;    

    ptcount2=0;

    EnableInterrupts;  

    TIE_C2I = 0;  //关闭ECT2局部中断

}

interrupt void PT1_isr() 

    DisableInterrupts; 

    ptflag1=0;

    ptcount1=0;

    TIE_C2I = 1;  //开放ECT2局部中断    

    TFLG1_C1F=1;     //中断标志寄存器对C1F清零

    //newcount1=TC1;

    if(TC1>TC1H)

    {

        count1=TC1-TC1H;

    } 

    else

    {

        count1=65535-TC1H+TC1;

    } 

    if((count1>148)&&(count1<37450))  //570  ->7hz   

    {

        flagECT1=1;

        PWME=PWME|0x0c; 

    } 

    else

    {

        flagECT1=0; 

        fin2=0;

        PTH_PTH6=0; 

        PWME=PWME&0xf3;

    }

    ptflag1=1;    

    ptcount1=0;

    EnableInterrupts;  

    TIE_C1I = 0;  //关闭ECT1局部中断

}

interrupt void PT0_isr() 

{

    DisableInterrupts; 

    ptflag0=0;

    ptcount0=0;

    TIE_C1I = 1;  //开放ECT1局部中断    

    TFLG1_C0F=1;     //中断标志寄存器对C0F清零

    //newcount0=TC0;

    if(TC0>TC0H)

    {

        count0=TC0-TC0H;

    } 

    else

    {

        count0=65535-TC0H+TC0;//溢出

    } 

    if((count0>148)&&(count0<37450))  //570  ->7hz    

    {

        flagECT0=1;

        PWME=PWME|0x03;

    } 

    else

    {

        flagECT0=0; 

        fin1=0;

        PTH_PTH7=0; 

        PWME=PWME&0xfc;

    }

    ptflag0=1;  //

    ptcount0=0;

    EnableInterrupts;  

    TIE_C0I = 0;  //关闭ECT0局部中断

#pragma CODE_SEG DEFAULT

void main(void) 

{

    InitPort();

    InitECT();

    InitPWM(); 

    InitMDC();   

    EnableInterrupts;     

    for(;;)

    {        

        if(cpuflag==1) 

        {

            PORTK_BIT1=~PORTK_BIT1;

            cpuflag=0;

        }   

        siout(); //PWM输出

show(); //显示函数      

    } 

}

//    

void  InitMDC(void)

{

    MCCTL=0xEF;

    MCCNT=750;      //定时1ms=750*16/(24/2)

//初始化ECT

void InitECT()

{

    TIOS=0;               //0:

设置为输入捕捉  1:

设置为输出比较

    TFLG1=0xff;           //定时器中断寄存器1  ,写1清零。

    TSCR1=0x80;           //10000000定时器允许位,允许定时器工工作

    TSCR2=0x05;           //0.375m定时器控制寄存器2,32分频

    TCTL4=0x55;           //设置为单上升沿捕捉 

    ICOVW=0x00;  //输入控制修改寄存器,=0,当新值被所存时,

                           //自动用新值覆盖对应寄存器~~

    ICSYS=0x02;           //启动输入捕捉和脉冲累加器保持器寄存器

    TIE=0x0f;             //0.1.2.3允许中断

}

//初始化PWM

void InitPWM()

{

    PWMCAE=0xaa;         //pwm居中对齐允许寄存器,10101010,1为居中对齐,0为左对齐

    PWMCTL=0xf0;         //pwm控制寄存器;01,23,45,67联合为四个16为pwm通道,PFRZ=1,冻结模式时pwm计数停止,=0冻结模式时

依然计数

    PWMPOL=0x00;         //pwm极性寄存器  8个通道:

1首先输出高电频,占空比计数器完毕后变低电频

    PWMCLK=0x00;         //pwm时钟选择寄存器

    PWMPRCLK=0x44;       //pwm预分频时钟选择寄存器, 01000100:

clka和clkb都是总线的16分频

    PWME=0xaa;           //pwm允许寄存器,允许或禁止各个通道输出

    2、着手解决只有三路或者三路一下的问题,利用定时器1毫秒中断一次,第一毫秒开通第一通道中断捕捉,第二毫秒开通第二通道中断捕捉,第三毫秒开通第三通道中断捕捉,第四毫秒开通第四通道中断捕捉,依次循环……,在捕捉中断中屏蔽掉ECT局部中断的开和关。

    存在问题:

捕捉到的频率正确,但在低频率150Hz以下某些频率段(125,112.5,100,50,25等,还挺有规律)输出不允许,造成输出跳跃,原因:

在这某些频率段执行了10Hz以下或者无输入时不允许输出的限制程序,不加限制的话ptcount0~ptcount3计数能够计到九千多,差不多是10秒的时间,所以输出跳变也正常。

但是不知为何在这某些频率段会计数计到那么大。

程序如下:

#pragma CODE_SEG __NEAR_SEG NON_BANKED

interrupt void    MDC_ISR()     //定时器1ms中断一次

{

    CpuCounter++;       //工作指示灯计数器,500ms翻转一次

    ptcounter++;      //1ms中断一次

    if(ptcounter==1)    //第一毫秒开通第一路

    {

        TIE_C0I = 1;  //开放ECT1局部中断

        TIE_C1I = 0;  //关闭ECT1局部中断

        TIE_C2I = 0;  //关闭ECT1局部中断

        TIE_C3I = 0;  //关闭ECT1局部中断    

    }

    if(ptcounter==2)    //第二毫秒开通第二路

    {

        TIE_C0I = 0;  //关闭ECT1局部中断

        TIE_C1I = 1;  //开放ECT1局部中断

        TIE_C2I = 0;  //关闭ECT1局部中断

        TIE_C3I = 0;  //关闭ECT1局部中断  

    }    

    if(ptcounter==3)    //第三毫秒开通第三路

    {

        TIE_C0I = 0;  //关闭ECT1局部中断

        TIE_C1I = 0;  //关闭ECT1局部中断

        TIE_C2I = 1;  //开放ECT2局部中断

        TIE_C3I = 0;  //关闭ECT1局部中断   

    }    

    if(ptcounter==4)    //第四毫秒开通第四路,依次循环开通

    {

        TIE_C0I = 0;  //关闭ECT1局部中断

        TIE_C1I = 0;  //关闭ECT1局部中断

        TIE_C2I = 0;  //关闭ECT1局部中断

        TIE_C3I = 1;  //开放ECT3局部中断 

        ptcounter=0;    

    } 

    

    if(ptflag0==1)    //10Hz以下或者无输入时计数,进入捕捉中断标志和计数清零,中断结束打开标志

    {      

        ptcount0++;

    }

    if(ptflag1==1) 

    {     

        ptcount1++;

    }

    if(ptflag2==1) 

    {     

        ptcount2++;

    }

    if(ptflag3==1) 

    {     

        ptcount3++;

    } 

    if(ptcount0>100)  //10Hz以下或者无输入时不允许输出,在某些频率段执行了此程序,造成输出跳变

    {

        ptcount0=0;     //计数清零

        flagECT0=0;     //标志清零

        fin1=0;         //频率置为0

        PTH_PTH7=0;     //指示灯熄灭

        PWME=PWME&0xfc; //不允许输出

    }

    if(ptcount1>100) 

    {

        ptcount1=0;

        flagECT1=0; 

        fin2=0;

        PTH_PTH6=0; 

        PWME=PWME&0xf3;

    }

    if(ptcount2>100) 

    {

        ptcount2=0;

        flagECT2=0; 

        fin3=0;

        PTH_PTH5=0; 

        PWME=PWME&0xcf;

    }

    if(ptcount3>100) 

    {

        ptcount3=0;

        flagECT3=0; 

        fin4=0;

        PTH_PTH4=0; 

        PWME=PWME&0x3f;

    } 

        

    if(CpuCounter>=500)  //处理器工作指示灯

    {       

        cpuflag=1;

        CpuCounter=0;

    }

    MCFLG_MCZF=1;  

}

interrupt void PT3_isr() 

    DisableInterrupts;  //总中断关闭

    ptflag3=0;          //清除无输入或者10Hz以下频率标志

    ptcount3=0;         //清除无输入或者10Hz以下频率计数器

    //TIE_C0I = 1;   //开放ECT0局部中断    

    TFLG1_C3F=1;      //中断标志寄存器对C3F清零

    //newcount3=TC3;

    if(TC3>TC3H)

    {

        count3=TC3-TC3H;

    } 

    else

    {              

        count3=65535-TC3H+TC3;

    } 

    if((count3>148)&&(count3<37450))  //10~2.5KHz有效,其余无效   

    {

        flagECT3=1;   //输出标志置一

        PWME=PWME|0xc0;   //允许输出

    } 

    else    //无效不允许输出

    {

        flagECT3=0;    //输出标志清零

        fin4=0;

        PTH_PTH4=0; 

        PWME=PWME&0x3f;   //不允许输出

    }

    ptflag3=1;      //打开无输入或者10Hz以下频率标志

    ptcount3=0;     //清除无输入或者10Hz以下频率计数器

    EnableInterrupts;  //总中断开启

    //TIE_C3I = 0;    //关闭ECT3局部中断    

}

#pragma CODE_SEG DEFAULT

    3、想另外的方法实现只有三路或者三路一下的问题,在网上找资料好不容易搜到这样一篇帖子《请教MC9S12DG128B的中断优先问题》,跟我先前遇到的问题一样。

我按照此方法改了程序,但是这个方法光是输入捕捉倒是没有问题,但是如果要用到定时器中断的时候,程序一直执行的是定时器中断程序和捕捉中断,进不了主程序,工作指示灯是定时器定时的,但却是在主程序循环里面控制指示灯的闪烁的,这个问题怎么解决?

程序如下:

#pragma CODE_SEG __NEAR_SEG NON_BANKED

interrupt void    MDC_ISR()     //定时器1ms中断一次

{

    CpuCounter++;       //工作指示灯计数器,500ms翻转一次 

    if(ptflag0==1)    //10Hz以下或者无输入时计数,进入捕捉中断标志和计数清零,中断结束打开标志

    {      

        ptcount0++;

    }

    if(ptflag1==1) 

    {     

        ptcount1++;

    }

    if(ptflag2==1) 

    {     

       

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 党团工作 > 思想汇报心得体会

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2