⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 angle.c

📁 一个串口终端解释程序。用于单片机调试串口的超级终端应用。
💻 C
📖 第 1 页 / 共 3 页
字号:
/*-----------------------------------------------------------------------*
* Copyright (c) 2005,北京四方同创保护与控制设备有限公司稳控事业部
* All rights reserved.
*
* 文件名称:Angle.c
* 摘    要:与内电势角度测量相关的功能函数
*           采用CSS-200/1规约V1.02版
* 当前版本:2.00
* 作    者:胡炯
* 完成日期:2006.12
*-----------------------------------------------------------------------*/

#include "56807.h"
#include "CSFU107.h"

void ECaptureIsr(void);     //E输入捕获中断子程序,TimerA0
void UCaptureIsr(void);     //U输入捕获中断子程序,TimerA2
void TimerC1Isr(void);      //15us定时器中断,Timer C1
void JudgeEStat(void);      //判断E的输入状态是否正确
void JudgeUStat(void);      //判断U的输入状态是否正确
void EnableECapture(void);  //允许捕捉键相脉冲中断
void EnableUCapture(void);  //允许捕捉电压脉冲中断
void CalAngle(void);        //计算内电势绝对角和发电机功角

void AddButtonIsr(void);    //补偿值调节按钮中断子程序,GPIO B0
void SubButtonIsr(void);    //补偿值调节按钮中断子程序,GPIO D0
void ButtonFilter(void);    //对补偿值按钮调节进行去抖处理

/*****E输入捕获中断子程序,TimerA0*****/
#pragma interrupt
void ECaptureIsr(void)
{
    unsigned int TempTA0Counter;
    unsigned int TempTA0Capture;
    unsigned long TempEPeriodBak;
    long TempL;

    /*if (IntFlag & 0x8000) //for test!!!
    {
        IntFlag |= 0x0001;
    }*/

    if (E.ChangeCounter == 0)   //当前未在进行去抖判断
    {
        //if (E.NowState != E_INPUT_STAT) //输入与记录状态不一致,对去除干扰脉冲有好处,但可能引起误判!
        {
            if (++E.OneSecondTrigTimes >= E.OneSecondTrigTimesLimit)    //1秒内启动去抖判断的次数过多
            {
                E.OneSecondTrigTimes = 0;
                E.ErrFlag = TRUE;
                E.BufFullFlag = FALSE;
                E.RisingEdgeWritePtr = &E.RisingEdgeCounterBuf[COUNTER_QUEUE_SIZE-1];
                E.PeriodBufWritePtr = &E.PeriodBuf[COUNTER_QUEUE_SIZE-1];

                *TMRA0_SCR &= 0xfbff;       //关闭TA0中断
                if (U.ChangeCounter == 0)
                {
                    *TMRC1_SCR = 0x0000;    //关闭TC1中断
                }
                return;
            }

            if (E.NowState == 0)    //上升沿到来
            {
                TempTA0Counter = *TMRA0_CNTR;
                E.CurrRisingEdgeCounter = *TMRA1_HOLD;
                E.CurrRisingEdgeCounter <<= 16;
                TempTA0Capture = *TMRA0_CAP;
                E.CurrRisingEdgeCounter += TempTA0Capture;
                if (TempTA0Counter < TempTA0Capture)
                {
                    E.CurrRisingEdgeCounter -= 0x10000;
                }

                if (!E.ErrFlag) //当前E输入处于正常态
                {
                    TempEPeriodBak = E.CurrRisingEdgeCounter - E.LastRisingEdgeCounter;
                    TempL = TempEPeriodBak - LastEPeriod;
                    if ((TempL < ContiguousEPeriodMaxErr) && (TempL > -ContiguousEPeriodMaxErr))
                    //当前E周期与上一个E周期的误差在允许范围内
                    {
                        ECaptureFlag = 1;
                    }
                    else
                    {
                        TempL = TempEPeriodBak / 2 - LastEPeriod;
                        if ((TempL < ContiguousEPeriodMaxErr) && (TempL > -ContiguousEPeriodMaxErr))
                        //当前E周期的1/2与上个E周期的误差在允许范围内,对应出现了1个错误E脉冲的情况
                        {
                            ECaptureFlag = 2;
                        }
                        else
                        {
                            TempL = TempEPeriodBak / 3 - LastEPeriod;
                            if ((TempL < ContiguousEPeriodMaxErr) && (TempL > -ContiguousEPeriodMaxErr))
                            //当前E周期的1/3与上个E周期的误差在允许范围内,对应出现了2个错误E脉冲的情况
                            {
                                ECaptureFlag = 3;
                            }
                            else
                            {
                                TempL = TempEPeriodBak / 4 - LastEPeriod;
                                if ((TempL < ContiguousEPeriodMaxErr) && (TempL > -ContiguousEPeriodMaxErr))
                                //当前E周期的1/4与上个E周期的误差在允许范围内,对应出现了3个错误E脉冲的情况
                                {
                                    ECaptureFlag = 4;
                                }
                                else
                                {
                                    ECaptureFlag = 0;
                                }
                            }
                        }
                    }
                }
                else        //当前E输入处于非正常态
                {
                    ECaptureFlag = 1;
                }

                if (ECaptureFlag > 0)   //上升沿到来时间符合要求
                //进行上升沿判断时,如果当前E输入处于非正常态,则每次去抖判断完成,均认为是真实跳变
                //如果当前E输入处于正常态,则当前E周期与上一个E周期相比变化必须小于0.2%(频率变化不超过0.1Hz),
                //或当前E周期的1/2与上一个E周期相比变化必须小于0.2%(频率变化不超过0.1Hz),才认为是真实上升沿跳变
                {
                    E.ChangeCounter = 4;
                    E.IntTimes = 1;
                    E.FilterLastTime = 0;
                    *TMRC1_SCR |= 0x4000;   //开启TC1中断
                }
                else    //上升沿到来时间不合要求
                {
                    asm(nop);
                }
            }
            else    //下降沿到来
            {
                E.ChangeCounter = 4;
                E.IntTimes = 1;
                E.FilterLastTime = 0;
                *TMRC1_SCR |= 0x4000;   //开启TC1中断
            }
        }
    }
    else    //当前正在进行去抖判断
    {
        if (++E.IntTimes >= E.IntTimesLimit)    //进入中断次数过多,认为E输入存在问题
        {
            E.ChangeCounter = 0;
            E.ErrFlag = TRUE;
            E.BufFullFlag = FALSE;
            E.RisingEdgeWritePtr = &E.RisingEdgeCounterBuf[COUNTER_QUEUE_SIZE-1];
            E.PeriodBufWritePtr = &E.PeriodBuf[COUNTER_QUEUE_SIZE-1];

            *TMRA0_SCR &= 0xfbff;       //关闭TA0中断
            if (U.ChangeCounter == 0)
            {
                *TMRC1_SCR = 0x0000;    //关闭TC1中断
            }
            return;
        }
    }

    *TMRA0_SCR &= 0xf7ff;   //允许再次触发中断
}
/*****end of E输入捕获中断子程序,TimerA0*****/


/*****U输入捕获中断子程序,TimerA2*****/
#pragma interrupt
void UCaptureIsr(void)
{
    unsigned int TempTA2Counter;
    unsigned int TempTA2Capture;

    /*if (IntFlag & 0x8000) //for test!!!
    {
        IntFlag |= 0x0002;
    }*/

    if (U.ChangeCounter == 0)   //当前未在进行去抖判断
    {
        //if (U.NowState != U_INPUT_STAT) //输入与记录状态不一致,对去除窄干扰脉冲有好处,但可能引起误判!
        {
            if (++U.OneSecondTrigTimes >= U.OneSecondTrigTimesLimit)    //1秒内启动去抖判断的次数过多
            {
                U.OneSecondTrigTimes = 0;
                U.ErrFlag = TRUE;
                U.BufFullFlag = FALSE;
                U.RisingEdgeWritePtr = &U.RisingEdgeCounterBuf[COUNTER_QUEUE_SIZE-1];
                U.PeriodBufWritePtr = &U.PeriodBuf[COUNTER_QUEUE_SIZE-1];

                *TMRA2_SCR &= 0xfbff;       //关闭TA2中断
                if (E.ChangeCounter == 0)
                {
                    *TMRC1_SCR = 0x0000;    //关闭TC1中断
                }
                return;
            }

            U.ChangeCounter = 6;
            U.IntTimes = 1;
            U.FilterLastTime = 0;

            if (U.NowState == 0)    //只记录上升沿对应的计数值
            {
                TempTA2Counter = *TMRA2_CNTR;
                U.CurrRisingEdgeCounter = *TMRA3_HOLD;
                U.CurrRisingEdgeCounter <<= 16;
                TempTA2Capture = *TMRA2_CAP;
                U.CurrRisingEdgeCounter += TempTA2Capture;
                if (TempTA2Counter < TempTA2Capture)
                {
                    U.CurrRisingEdgeCounter -= 0x10000;
                }
            }

            *TMRC1_SCR |= 0x4000;   //开启TC1中断
        }
    }
    else    //当前正在进行去抖判断
    {
        if (++U.IntTimes >= U.IntTimesLimit)    //进入中断次数过多,认为U输入存在问题
        {
            U.ChangeCounter = 0;
            U.ErrFlag = TRUE;
            U.BufFullFlag = FALSE;
            U.RisingEdgeWritePtr = &U.RisingEdgeCounterBuf[COUNTER_QUEUE_SIZE-1];
            U.PeriodBufWritePtr = &U.PeriodBuf[COUNTER_QUEUE_SIZE-1];

            *TMRA2_SCR &= 0xfbff;       //关闭TA2中断
            if (E.ChangeCounter == 0)
            {
                *TMRC1_SCR = 0x0000;    //关闭TC1中断
            }
            return;
        }
    }

    *TMRA2_SCR &= 0xf7ff;   //允许再次触发中断
}
/*****end of U输入捕获中断子程序,TimerA2*****/


/*****15us定时器中断,Timer C1*****/
#pragma interrupt
void TimerC1Isr(void)
{
    unsigned int TempFlag;

    /*if (IntFlag & 0x8000) //for test!!!
    {
        IntFlag |= 0x0004;
    }*/

    TempFlag = 0;

    if (E.ChangeCounter)
    {
        if (++E.FilterLastTime >= E.MaxDelayTime)
        {
            E.ChangeCounter = 0;
        }
        else
        {
            if (E.NowState != E_INPUT_STAT)
            {
                if (++E.ChangeCounter >= E.ChangeCounterLimit)  //通过去抖判断
                {
                    E.ChangeCounter = 0;

                    if (E.NowState == 0)    //刚通过上升沿的去抖判断
                    {
                        E.NowState = 0x0100;
                        E.ErrorLastTime = 0;    //收到有效的E数据

                        E.RisingEdgeWritePtr++;
                        E.PeriodBufWritePtr++;
                        if (E.RisingEdgeWritePtr >= &E.RisingEdgeCounterBuf[COUNTER_QUEUE_SIZE])
                        {
                            E.RisingEdgeWritePtr = &E.RisingEdgeCounterBuf[0];
                            E.PeriodBufWritePtr = &E.PeriodBuf[0];
                        }

                        *E.RisingEdgeWritePtr = E.CurrRisingEdgeCounter;
                        if (ECaptureFlag == 2)
                        {
                            LastEPeriod = (E.CurrRisingEdgeCounter - E.LastRisingEdgeCounter) / 2;
                        }
                        else if (ECaptureFlag == 3)
                        {
                            asm (BFSET #0x0300, SR);        //禁用所有可屏蔽中断
                            LastEPeriod = (E.CurrRisingEdgeCounter - E.LastRisingEdgeCounter) / 3;
                            asm (BFCLR #0x0200, SR);        //开启可屏蔽中断
                        }
                        else if (ECaptureFlag == 4)
                        {
                            LastEPeriod = (E.CurrRisingEdgeCounter - E.LastRisingEdgeCounter) / 4;
                        }
                        else
                        {
                            LastEPeriod = E.CurrRisingEdgeCounter - E.LastRisingEdgeCounter;
                        }
                        *E.PeriodBufWritePtr = LastEPeriod;
                        E.LastRisingEdgeCounter = E.CurrRisingEdgeCounter;

                        if (E.RisingEdgeWritePtr == &E.RisingEdgeCounterBuf[COUNTER_QUEUE_SIZE-1])
                        {
                            E.BufFullFlag = TRUE;
                        }
                    }
                    else    //刚通过下降沿的去抖判断
                    {
                        E.NowState = 0;
                    }
                }
            }
            else
            {
                if (E.ChangeCounter > 0)
                {
                    E.ChangeCounter --;
                }
            }
        }
    }

    if (U.ChangeCounter)
    {
        if (++U.FilterLastTime >= U.MaxDelayTime)
        {
            U.ChangeCounter = 0;
        }
        else
        {
            if (U.NowState != U_INPUT_STAT)
            {
                if (++U.ChangeCounter >= U.ChangeCounterLimit)  //通过去抖判断
                {
                    U.ChangeCounter = 0;

                    if (U.NowState == 0)    //刚通过上升沿的去抖判断
                    {
                        U.NowState = 0x0100;
                        U.ErrorLastTime = 0;    //收到有效的U数据

                        U.RisingEdgeWritePtr++;
                        U.PeriodBufWritePtr++;
                        if (U.RisingEdgeWritePtr >= &U.RisingEdgeCounterBuf[COUNTER_QUEUE_SIZE])
                        {
                            U.RisingEdgeWritePtr = &U.RisingEdgeCounterBuf[0];
                            U.PeriodBufWritePtr = &U.PeriodBuf[0];
                        }

                        *U.RisingEdgeWritePtr = U.CurrRisingEdgeCounter;
                        *U.PeriodBufWritePtr = U.CurrRisingEdgeCounter - U.LastRisingEdgeCounter;
                        U.LastRisingEdgeCounter = U.CurrRisingEdgeCounter;

                        if (U.RisingEdgeWritePtr == &U.RisingEdgeCounterBuf[COUNTER_QUEUE_SIZE-1])
                        {
                            U.BufFullFlag = TRUE;
                        }

                    }
                    else    //刚通过下降沿的去抖判断
                    {
                        U.NowState = 0;
                    }
                }
            }
            else
            {
                if (U.ChangeCounter > 0)
                {
                    U.ChangeCounter --;
                }
            }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -