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

📄 serial.c

📁 一个分选系统的软件:用SmallRtos操作系统
💻 C
字号:
/*********************************************************************************************************
**--------------文件信息--------------------------------------------------------------------------------
**文   件   名: serial.c
**创   建   人: 刘宝贵
**最后修改日期: 2004年4月20日
**描        述: 串行口驱动
**
**--------------历史版本信息----------------------------------------------------------------------------
** 创建人: 刘宝贵
** 版  本: V1.00
** 日 期: 2004年4月20日
** 描 述: 原始版本
**
**------------------------------------------------------------------------------------------------------
** 修改人:
** 版  本:
** 日 期:
** 描 述:
**
**------------------------------------------------------------------------------------------------------
**--------------当前版本修订------------------------------------------------------------------------------
** 修改人: 刘宝贵
** 日 期: 2004年4月20日
** 描 述: 
**
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/

#include "config.h"

uint8 OS_Q_MEM_SEL NotUse _at_ 0x0000;      //指针的NULL为0,这个变量占用0地质避免出现有效的NULL指针
uint8 OS_Q_MEM_SEL SerialInData[100];        //给读串口消息队列分配的队列空间
uint8 OS_Q_MEM_SEL SerialOutData[200];       //给写串口消息队列分配的队列空间
void PutChar(uint8 Data);                   //发送一个字节
void Send(uint8 Data);                      //发送一个数据包
uint8 GetCharWithCheck(void);               //从读串口消息队列取一字节,并且对该字节校验

bit SerialCanSend = 1;
bit CommSending = 0;
//uint8 data test;
uint8 data inchk;          //校验和
uint8 data outchk;         //校验和
uint8 data cid;            //命令码
uint8 data rtn;            //返回码  RTN值  表示意义
uint8 xdata buf[100];      // 缓冲串口数据     
#define RIGHT         1    //         01H	正常
#define CHKSUM_ERROR  2    //         02H	CHKSUM 错
#define LENGTH_ERROR  3    //         03H	LENGTH 错
#define CID_ERROR     4    //         04H	CID 无效
#define TYPE_ERROR    5    //         05H	命令格式错
#define DATA_ERROR    6    //         06H	无效数据
#define LOGIC_ERROR   7    //         07H	逻辑错

#define OTHER_ERROR   0XE0 //         E0H~EFH	其他错误

/*********************************************************************************************************
** 函数名称: PutChar
** 功能描述: 发送一个字节
** 输 入: Data:发送的数据
** 输 出: 无
** 全局变量: 无
** 调用模块: 无
**
** 作 者: 陈明计
** 日 期: 2002年12月4日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void PutChar(uint8 Data)
{
    OS_ENTER_CRITICAL();
    if (SerialCanSend == 1)
    {
        SerialCanSend = 0;
        SBUF0 = Data;
    }
    else
    {
        OSQIntPost(SerialOutData,Data);
    }
    OS_EXIT_CRITICAL();
}  

/*********************************************************************************************************
** 函数名称: PutCharWithcheck
** 功能描述: 发送一个字节同时校验
** 输 入: Data:发送的数据
** 输 出: 无
** 全局变量: chk
** 调用模块: PutChar
**
** 作 者: 刘宝贵
** 日 期: 2004年4月21日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void PutCharWithCheck(uint8 Data)
{
    outchk ^= Data ;
    PutChar (Data);
}  

/*********************************************************************************************************
** 函数名称: CommSendInfo
** 功能描述: 发送一个报文
** 输   入: 无
** 输   出: 无
** 全局变量: address cid rtn chk
** 调用模块: OSQCreate PutCharWithCheck PutChar
**
** 作 者: 刘宝贵
** 日 期: 2004年4月25日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void CommSendInfo(void)
{
    OSQCreate(SerialOutData,200);
    outchk = 0;
    PutCharWithCheck(0xeb);
    PutCharWithCheck(0x90);
    PutCharWithCheck(0xeb);
    PutCharWithCheck(0x90);
    PutCharWithCheck(Address);
    PutCharWithCheck(cid);
    PutCharWithCheck(1);
    PutCharWithCheck(rtn);
    PutChar(outchk);
    PutChar(0x0d);
}
/*********************************************************************************************************
** 函数名称: GetCharWithCheck
** 功能描述: 从读串口消息队列取一字节,并且对该字节校验
** 输   入: 无
** 输   出: temp:从串口消息队列取的字节
** 全局变量: inchk:校验和
** 调用模块: OSQPend
**
** 作   者: 刘宝贵
** 日   期: 2004年4月21日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
uint8 GetCharWithCheck(void)
{
    uint8 data temp;
    OSQPend(&temp,SerialInData,0);     /* 接收一个字节       */
    inchk^=temp;
    return(temp);
}  

/*********************************************************************************************************
** 函数名称: GetCharWithoutCheck
** 功能描述: 从读串口消息队列取一字节
** 输   入: 无
** 输   出: temp:从串口消息队列取的字节
** 全局变量: 无
** 调用模块: OSQPend
**
** 作   者: 刘宝贵
** 日   期: 2004年4月21日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
uint8 GetCharWithoutCheck(void)
{
    uint8 data temp;
    OSQPend(&temp,SerialInData,0);     /* 接收一个字节       */
    return(temp);
}  

/*********************************************************************************************************
** 函数名称: TaskReceive
** 功能描述: 串口接收处理任务
** 输   入: 无
** 输   出: 无                     
** 全局变量: 无
** 调用模块: 无
**
** 作   者: 刘宝贵
** 日   期: 2004年4月20日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void TaskReceive(void)
{
    uint8 code  head[4] = {0xEB,0x90,0xEB,0x90};
    OSQCreate(SerialInData,100);                 /* 建立所需要的消息队列 */
    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;
                }//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 + -