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

📄 serial.c

📁 一个分选系统的软件:用SmallRtos操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void TaskReceive(void)
{
    uint8 code  head[4] = {0xEB,0x90,0xEB,0x90};
    OSQCreate(SerialInData,130);                 /* 建立所需要的消息队列 */
    OSQCreate(SerialOutData,200);
    while (1)
    {
        uint8 xdata state=0;
        while (1)//识别报文头
        {
            if(head[state] == GetCharWithoutCheck())
                state++;
            else
                state=0;
            if(state==4)
                break;
        }//while (1)//识别报文头
        rtn=RIGHT;                               /* 返回码置初值         */
        inchk = 0xeb^0x90^0xeb^0x90;             /* 初始化校验和         */
        if(Address == GetCharWithCheck())       /* 如果地址正确则继续   */
        {
            uint8 data i;
            uint8 xdata length;
            cid = GetCharWithCheck();
            length = GetCharWithCheck();
            if (length>100)
            {
                length=100;
            }
            for (i=0;i<length;i++)                    // 接收数据区数据       
            {
                buf[i]=GetCharWithCheck();
            }
            i = GetCharWithoutCheck();
            if (inchk != i && i!=0x55)       // 判断校验和 0x55 为不校验
            {
                rtn = CHKSUM_ERROR;
            }
            if (0x0d != GetCharWithoutCheck())        // 判断报文尾           
            {
                rtn = TYPE_ERROR;
            }
            EN_485 = 0;
            OSWait(K_TMO,(5*OS_TICKS_PER_SEC)/1000);  //delay15ms
            if(rtn==1)//如果报文的校验和,类型正确
            {
                CommCounter = 0;
                switch (cid)
                {
                    case 0:                               // 握手命令             
                    {
                        CommSendInfo();
                    }break;
                    case 1:                               // 取电池数据信息
                    {
                        CommSendCellDataInfo();
                    }break;
                    case 2:                               // 工步设置
                    {
                        if(CurrentWorkStep ==0)//如果当前为停止状态则可以修改工步
                        {
                            SumWorkStep = buf[0];
                            if(SumWorkStep>12)
                                SumWorkStep=12;
                            for(i=1;i<=SumWorkStep;i++)
                            {
                                WorkStep[i].type  = buf[(i-1)*9+2];
        
                                WorkStep[i].i     = buf[(i-1)*9+3];
                                WorkStep[i].i     = WorkStep[i].i <<8 ;
                                WorkStep[i].i     = WorkStep[i].i | buf[(i-1)*9+4];
                                WorkStep[i].i    *=10;
        
                                WorkStep[i].limit = buf[(i-1)*9+5];
                                WorkStep[i].limit = WorkStep[i].limit <<8 ;
                                WorkStep[i].limit = WorkStep[i].limit | buf[(i-1)*9+6];
                                WorkStep[i].limit *=10;
        
                                WorkStep[i].t     = buf[(i-1)*9+7];
                                WorkStep[i].t     = WorkStep[i].t <<8 ;
                                WorkStep[i].t     = WorkStep[i].t | buf[(i-1)*9+8];
                                WorkStep[i].t    *= 60;//换算成秒

                                WorkStep[i].u     = buf[(i-1)*9+9];
                                WorkStep[i].u     = WorkStep[i].u <<8 ;
                                WorkStep[i].u     = WorkStep[i].u | buf[(i-1)*9+10];
                                WorkStep[i].u    *= 10;

                            }
                            if( WorkStepCheck()==0 )//如果工步无效
                            {
                                rtn = DATA_ERROR;
                            }
                            CommSendInfo();
                            OSSemPend(IICSem,0);
                            EepromWriteByte(SumWorkStepIICBase,SumWorkStep);
                            for(i=1;i<=SumWorkStep;i++)
                            {
                                EepromWriteByte(WorkStepIICBase + i*9 + 0,WorkStep[i].type );
                                EepromWriteWord(WorkStepIICBase + i*9 + 1,WorkStep[i].i    );
                                EepromWriteWord(WorkStepIICBase + i*9 + 3,WorkStep[i].limit);
                                EepromWriteWord(WorkStepIICBase + i*9 + 5,WorkStep[i].t    );
                                EepromWriteWord(WorkStepIICBase + i*9 + 7,WorkStep[i].u    );
                            }
                            OSSemPost(IICSem);
                        }
                        else//if(CurrentWorkStep ==0)//如果当前为停止状态则可以修改工步
                        {
                            rtn = LOGIC_ERROR;
                            CommSendInfo();
                        }
                    }break;
                    case 3:// 模块停止
                    {
                        CellCheckFlag = 0;
                        if(CurrentWorkStep>0)//CurrentWorkStep==0则系统众目停止
                        {
                            OSSemPost(StopWorkStepSem);
                        }
                        else
                        {
                            rtn = LOGIC_ERROR;
                        }
                        CommSendInfo();
                    }break;
                    case 4:// 分容
                    {
                        if(length==3)
                        {
                            if(CurrentWorkStep == 0)
                            {
                                i=buf[0];
                                if((bit)(i&1)) P4|=0x01; else P4&=0xFE; i=i>>1;
                                if((bit)(i&1)) P4|=0x02; else P4&=0xFD; i=i>>1;
                                if((bit)(i&1)) P4|=0x04; else P4&=0xFB; i=i>>1;
                                if((bit)(i&1)) P4|=0x08; else P4&=0xF7; i=i>>1;
                                if((bit)(i&1)) P4|=0x10; else P4&=0xEF; i=i>>1;
                                if((bit)(i&1)) P4|=0x20; else P4&=0xDF; i=i>>1;
                                if((bit)(i&1)) P4|=0x40; else P4&=0xBF; i=i>>1;
                                if((bit)(i&1)) P4|=0x80; else P4&=0x7F; i=i>>1;
                                i=buf[1];
                                if((bit)(i&1)) P5|=0x01; else P5&=0xFE; i=i>>1;
                                if((bit)(i&1)) P5|=0x02; else P5&=0xFD; i=i>>1;
                                if((bit)(i&1)) P5|=0x04; else P5&=0xFB; i=i>>1;
                                if((bit)(i&1)) P5|=0x08; else P5&=0xF7; i=i>>1;
                                if((bit)(i&1)) P2|=0x10; else P2&=0xEF; i=i>>1;
                                if((bit)(i&1)) P2|=0x20; else P2&=0xDF; i=i>>1;
                                if((bit)(i&1)) P2|=0x40; else P2&=0xBF; i=i>>1;
                                if((bit)(i&1)) P2|=0x80; else P2&=0x7F; i=i>>1;
                                i=buf[2];
                                if((bit)(i&1)) P1|=0x01; else P1&=0xFE; i=i>>1;
                                if((bit)(i&1)) P1|=0x02; else P1&=0xFD; i=i>>1;
                                if((bit)(i&1)) P1|=0x04; else P1&=0xFB; i=i>>1;
                                if((bit)(i&1)) P1|=0x08; else P1&=0xF7; i=i>>1;
                                if((bit)(i&1)) P1|=0x10; else P1&=0xEF; i=i>>1;
                                if((bit)(i&1)) P1|=0x20; else P1&=0xDF; i=i>>1;
                                if((bit)(i&1)) P1|=0x40; else P1&=0xBF; i=i>>1;
                                if((bit)(i&1)) P1|=0x80; else P1&=0x7F; i=i>>1;
                            }//if(CurrentWorkStep == 0)
                            else
                            {
                                rtn = LOGIC_ERROR;
                            }
                        }//if(length==3)
                        else
                        {
                            rtn = LENGTH_ERROR;
                        }
                        CommSendInfo();
                    }break;//case 4:// 分容
                    case 5:// 取分容信息命令
                    {
                        uint16 data temp;
                        temp = buf[0];
                        temp = temp<<8;
                        temp = temp | buf[1];
                        if(temp%100 == 0 && temp<=3800 && temp>=2600)
                        {
                            if(CurrentWorkStep == 0)//如果当前为停止
                            {
                                CommSendFenRongInfo(temp);
                            }
                            else
                            {
                                rtn = LOGIC_ERROR;
                                CommSendInfo();
                            }
                        }//if(temp%100 == 0)
                        else
                        {
                            rtn = DATA_ERROR;
                            CommSendInfo();
                        }//if(temp%100 == 0)
                    }break;
                    case 6:// 模块启动
                    {
                        if(CurrentWorkStep==0)
                        {
                            CurrentWorkStep    = 1;
                            CurrentWorkStepMax = 1;
                            Reset              = 0;
                            CellCheckFlag      = 0;
                            OSSemPost(StartWorkStepSem);//发送同步工步执行信号量
                        }
                        else
                        {
                            rtn = LOGIC_ERROR;
                        }
                        CommSendInfo();
                    }break;
                    case 7:// 工步续接
                    {
                        CommSendInfo();
                    }break;
                    case 8:// 电池对点
                    {
                        if(CurrentWorkStep==0)
                        {
                            CellCheckUHigh = buf[0];
                            CellCheckUHigh = CellCheckUHigh<<8;
                            CellCheckUHigh|= buf[1];

                            CellCheckULow  = buf[2];
                            CellCheckULow  = CellCheckULow<<8;
                            CellCheckULow |= buf[3];
                            if((CellCheckUHigh < 5000) && (CellCheckUHigh > 500) && 
                               (CellCheckULow  < 5000) && (CellCheckULow  > 500) &&
                               (CellCheckUHigh > CellCheckULow))
                            {
                                CellCheckULow *= 10; 
                                CellCheckUHigh*= 10;         //为了能和单片机内电池数据比较
                                CellCheckFlag  = 1;
                            }
                            else
                            {
                                CellCheckULow  = 0; 
                                CellCheckUHigh = 0;
                                CellCheckFlag  = 0;
                                rtn = DATA_ERROR;
                            }
                        }
                        else
                        {
                            rtn = LOGIC_ERROR;
                        }
                        CommSendInfo();
                    }break;
                    case 0xC0:// 设模块参数
                    {
                        if(length == 3)
                        {
                            uint16 data temp;
                            temp = buf[1];
                            temp = temp<<8;
                            temp = temp | buf[2];
                            if(temp < PARAMETER_MAX && temp >PARAMETER_MIN)//保证所写参数在一定数值范围内
                            {
                                if(OSSemPend(IICSem,10)==OS_SEM_OK)
                                {
                                    EepromWriteByteA(CellParaIICBase+buf[0]*2,buf[1]);
                                    EepromWriteByteA(CellParaIICBase+buf[0]*2+1,buf[2]);
                                    OSSemPost(IICSem);
                                }
                                if(buf[0]%8 == 0 || buf[0]%8 == 2 )
                                    AdParaChanged = 1;
                                if(buf[0]%8 == 4 || buf[0]%8 == 6 )
                                    DaParaChanged = 1;
                            }
                            else
                            {
                                rtn = DATA_ERROR;
                            }
                        }
                        else
                        {
                            rtn = LENGTH_ERROR;
                        }
                        CommSendInfo();
                    }break;
                    case 0xC1:// 取模块参数
                    {
                        CommSendParaInfo();
                    }break;
                    default:
                    {
                        rtn = CID_ERROR;
                        CommSendInfo(); 
                    }
                }//switch (cid)
            }//if(rtn==1)//如果报文的校验和,类型正确]
            else//如果校验和或类型不正确
            {
                CommSendInfo();
            }
        }//if (Address == GetCharWithCheck())
    }//while (1)
}//void TaskReceive(void)
/*********************************************************************************************************
** 函数名称: comm
** 功能描述: 串口中断处理程序
** 输 入: 无
** 输 出: 无
** 全局变量: 无
** 调用模块: 无
**
** 作 者: 刘宝贵
** 日 期: 2004年4月20日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#if EN_OS_INT_ENTER >0 
#pragma disable                                        /* 除非最高优先级中断,否则,必须加上这一句                 */
#endif
		void comm(void) interrupt 4
{
    uint8 data temp;
    if(EN_485 == 1)//EN_485==1:通信处于接收状态
    {
    	if (RI0 == 1)
    	{
#if EN_OS_INT_ENTER >0
            OS_INT_ENTER();
#endif
    		RI0 = 0;
            OSQIntPost(SerialInData,SBUF0);
            OSIntExit();
    		return;
    	}
    }
    else
    {
        RI0 = 0;
    }
	if (TI0 == 1)
	{
		TI0 = 0;
		if (OSQAccept(&temp,SerialOutData) == OS_Q_OK)
		{
		    SBUF0 = temp;
		}
		else
		{
		    SerialCanSend = 1;
            EN_485 = 1;
		}
	}
}

⌨️ 快捷键说明

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