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

📄 sci.c

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

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

void Sci0RecInt(void);              //SCI0接收中断(接收RCM3200报文)
void Sci1RecInt(void);              //SCI1接收中断(接收GPS串口报文)
void CalSoc(void);                  //利用接收的串口报文计算SOC
void SendDataToRcm3200(void);       //向RCM3200发送报文
void WriteRcm3200DataRpt(void);     //填写内电势测量数据报文缓冲区
void WriteRcm3200PatrolRpt(void);   //填写RCM3200串口巡检报文缓冲区
void SendDataToMeter(void);         //向数显表发送报文
void WriteMeterBuf(unsigned int sign, unsigned int dot);    //填写数显表报文缓冲区,sign:0-不带负号,1-带负号;dot:0-不带小数点,1-带小数点

extern void InitSci0RecVariable(void);  //初始化与SCIO接收相关的变量(与RCM3200通信)
extern void InitSci1RecVariable(void);  //初始化与SCI1接收相关的变量(接收GPS时钟信号)
extern void InitSci1Trans(void);        //初始化SCI1的发送(向数据表发送数据)
extern void InitSci1Rec(void);          //初始化SCI1的接收(接收GPS时钟信号)

/*****SCI0接收中断(接收RCM3200报文)*****/
#pragma interrupt
void Sci0RecInt(void)
{
    unsigned int i;
    unsigned int CheckSum;
    int TempI;

    if (*SCI0_SCISR & 0x0f00)   //FE置位
    {
        *SCI0_SCISR &= 0xf0ff;
    }
    Sci0Data = *SCI0_SCIDR;

    /*for test!
    *Sci0RecBufPtr = Sci0Data;
    if (++Sci0RecBufPtr >= &Sci0RecBuf[50])
    {
        Sci0RecBufPtr = &Sci0RecBuf[0];
    }
    //end of for test!*/

    if (RecSci0Flag == 0)
    {
        if (((Sci0Data == 0x51) && (LastSci0Data == 0x37))
        || ((Sci0Data == 0xaa) && (LastSci0Data == 0x40)))
        {
            RecSci0Flag = 1;
            *RecRcm3200BufPtr++ = LastSci0Data;
            *RecRcm3200BufPtr++ = Sci0Data;
        }
        LastSci0Data = Sci0Data;
    }
    else if (RecSci0Flag == 1)
    {
        *RecRcm3200BufPtr++ = Sci0Data;
        if (Sci0Data == 0x42)
        {
            *IPR = 0x0200;      //只允许6级中断(PLR设置为7)
            asm (BFCLR #$0200,SR);  //允许可屏蔽中断

            RecRcm3200DataSize = RecRcm3200BufPtr - &RecRcm3200Buf[0];
            switch (RecRcm3200Buf[0])
            {
                case 0x37:      //下发内电势参数报文
                {
                    if (RecRcm3200DataSize == (REC_RCM3200_BUF_SIZE-1)) //报文接收结束
                    //可能报文中数据恰好是0x42,并不是报文结束标志,则继续数据接收
                    {
                        RecRcm3200BufPtr = &RecRcm3200Buf[1];
                        CheckSum = 0;
                        for (i=0; i<(REC_RCM3200_BUF_SIZE-4); i++)
                        {
                            CheckSum ^= *RecRcm3200BufPtr++;
                        }
                        if (CheckSum == *RecRcm3200BufPtr)  //校验通过
                        {
                            if (RecRcm3200Buf[2] == 0x1E)   //下发内电势补偿角
                            {
                                TempI = (int)((RecRcm3200Buf[4]<<8) + RecRcm3200Buf[3]);
                                if ((TempI >= -1800) && (TempI <= 1800))
                                {
                                    E.CompensateValue = TempI;      //更新内电势补偿角
                                    WriteFlashStartFlag = TRUE;     //要求将参数写入FLASH
                                    Sci0ResponsionFlag = TRUE;      //返回应答报文
                                }
                            }
                            else if (RecRcm3200Buf[2] == 0x2D)  //下发机端电压补偿角
                            {
                                TempI = (int)((RecRcm3200Buf[4]<<8) + RecRcm3200Buf[3]);
                                if ((TempI >= -1800) && (TempI <= 1800))
                                {
                                    U.CompensateValue = TempI;      //更新机端电压补偿角
                                    WriteFlashStartFlag = TRUE;     //要求将参数写入FLASH
                                    Sci0ResponsionFlag = TRUE;      //返回应答报文
                                }
                            }
                            else if (RecRcm3200Buf[2] == 0x3C)  //设定装置工作模式
                            {
                                RunStat = (RecRcm3200Buf[4]<<8) + RecRcm3200Buf[3];
                                WriteFlashStartFlag = TRUE;     //要求将参数写入FLASH
                                Sci0ResponsionFlag = TRUE;      //返回应答报文
                            }
                            /*else if (RecRcm3200Buf[2] == 0x4B)    //下发内电势绝对角(预留)
                            {
                            }
                            else if (RecRcm3200Buf[2] == 0x5A)  //下发发电机功角(预留)
                            {
                            }
                            else if (RecRcm3200Buf[2] == 0x69)  //下发输出模拟量值(预留)
                            {
                            } */

                            if (Sci0ResponsionFlag) //填写应答报文缓冲区
                            {
                                Sci0ResponsionFlag = FALSE;
                                if ((WriteSendRcm3200QueuePtr->DataLength != 0) && (WriteSendRcm3200QueuePtr == ReadSendRcm3200QueuePtr))
                                //当前正在发送此帧报文,错开队列写入位置
                                {
                                    if (++WriteSendRcm3200QueuePtr >= &SendRcm3200Queue[SEND_RCM3200_QUEUE_DEPTH])
                                    {
                                        WriteSendRcm3200QueuePtr = &SendRcm3200Queue[0];
                                    }
                                }
                                WriteSendRcm3200QueuePtr->Data[0] = 0x38;
                                WriteSendRcm3200QueuePtr->Data[1] = 0xaa;
                                WriteSendRcm3200QueuePtr->Data[2] = 0x42;
                                WriteSendRcm3200QueuePtr->DataLength = 3;
                                if (++WriteSendRcm3200QueuePtr >= &SendRcm3200Queue[SEND_RCM3200_QUEUE_DEPTH])
                                {
                                    WriteSendRcm3200QueuePtr = &SendRcm3200Queue[0];
                                }
                            }
                        }
                        InitSci0RecVariable();
                    }
                    break;
                }

                case 0x40:  //串口通信巡检应答报文
                {
                    if (RecRcm3200DataSize == 3)
                    {
                        Sci0RecErrCounter = 0;
                    }
                    InitSci0RecVariable();
                    break;
                }
            }
        }
    }

    if (RecRcm3200BufPtr > &RecRcm3200Buf[REC_RCM3200_BUF_SIZE-1])
    {
        InitSci0RecVariable();
    }

    asm (BFSET #0x0300, SR);    //禁用所有可屏蔽中断
    *IPR  = 0xfe00;  //允许0-6级中断
}
/*****end of SCI0接收中断(接收RCM3200报文)*****/


/*****SCI1接收中断服务程序(接收GPS串口报文)*****/
#pragma interrupt
void Sci1RecInt(void)
{
    unsigned int TempUI;
   	unsigned long TempUL;

    if (*SCI1_SCISR & 0x0f00)   //FE置位
    {
        *SCI1_SCISR &= 0xf0ff;
    }

    Sci1Data = *SCI1_SCIDR;

    /*for test!
    *Sci1RecBufPtr = Sci1Data;
    if (++Sci1RecBufPtr >= &Sci1RecBuf[100])
    {
        Sci1RecBufPtr = &Sci1RecBuf[0];
    }
    //end of for test!*/

    //for test
    DEBUG2_LED_TURN_ON;
    //end for test

    if (CalSocFlag) //如果此时主循环尚未完成SOC计算,暂不接收新的数据
    {
        return;
    }

    switch (RecSci1Flag)
    {
        case 0:
        {
            if ( Sci1Data == '$')
            {
                RecSci1BufPtr = 0;
                RecSci1Flag = 1;
                RecSci1Buf[RecSci1BufPtr++] = Sci1Data;
                Sci1SumFlag = TRUE;
                Sci1CheckSum = 0;
            }
            break;
        }

        case 1:
        {
            RecSci1Buf[RecSci1BufPtr++] = Sci1Data;
            
            if (RecSci1BufPtr == 6)
		    {
		    	if (!((RecSci1Buf[1] == 'P') && (RecSci1Buf[2] == 'G') && (RecSci1Buf[3] == 'R')
                && (RecSci1Buf[4] == 'M') && (RecSci1Buf[5] == 'F'))) 
                {
                	InitSci1RecVariable();
                	return;
                }
		    }
            
            if (RecSci1BufPtr >= 84)
            {
                InitSci1RecVariable();
                Sci1RecErrFlag = 1;
                return;
            }

            if (Sci1Data == '*')
            {
                Sci1SumFlag = 0;
                return;
            }
            if (Sci1SumFlag)
            {
                Sci1CheckSum = Sci1CheckSum^Sci1Data;
            }
            else
            {
                if (Sci1Data == 10)  //recieve LF
                {
                    CalSocFlag = TRUE;

                    if (!PpsOutputFlag)
                    {   //还未开始输出虚拟PPS时,计算GPS串口报文结束字符到来时刻落后PPS上升沿的时间
                        TempUI = *TMRD0_CNTR;
                        TempUL = *TMRD1_HOLD;
                        TempUL <<= 16;
                        TempUL += TempUI;
                        GpsReportReachTimeCounter = TempUL - CurrInputPpsCounter;
                    }
                    else
                    {   //开始输出虚拟PPS后,直接读取当前秒内的TD3中断次数
                        GpsReportReachTime = CurrTD3IntCounter;

                        /*for test!!!
                        if (GpsReportReachTime > GpsReportMaxReachTime)
                        {
                            GpsReportMaxReachTime = GpsReportReachTime;
                        }
                        if (GpsReportReachTime < GpsReportMinReachTime)
                        {
                            GpsReportMinReachTime = GpsReportReachTime;
                        }

                        GpsReachTime.ReachTime[GpsReachTimeWritePtr] = GpsReportReachTime;

                        if ((GpsReportReachTime > 980) || (GpsReportReachTime < 20))
                        {
                            if (++GpsReachTimeErrorCnt >= 2)

⌨️ 快捷键说明

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