首页 > 代码库 > 用普通IO接收串口数据

用普通IO接收串口数据

<pre name="code" class="cpp">//文件urece.h

#ifndef _URECE_H_
#define _URECE_H_


#define     V_BATOU       0x80   //电池充满
#define     V_BATLV       0x40   //电池低电压
#define     V_BATOI       0X20   //电池放电过流
#define     V_BATOTP      0x10   //电池过温
#define     V_BATOTIM     0x08   //电池充电超时
#define     V_BATERR      0x04   //电池损坏


#define     V_NUM1      8   //中断NUM次取一位数据

#define     V_BITNUM    8   //一字节的包含的位数
#define     V_BYTENUM    6   //接收数据总字节数


          
//====红外接收相关定义=============================
#define		IrDatHigh	(P_IrRec == 1) //接收数据高
#define		IrDatLow	(P_IrRec == 0) //接收数据低


//=======变量定义 ================
typedef	struct IrReceData
{
    uint8 R_LevlSta ; //电平状态
    uint8 R_SavSta ; //连续保存电平状态
    uint8 ReBitNum ; //接收数据位 计算
    uint8 ReByteNum ; //接收数据位 计算
    uint8 ReCont ; //每Bit数据所需的中断时间 8次 


}IrReceData ;
extern IrReceData IrReceDat ;
//-----
#define		R_LevlSta  	    IrReceDat.R_LevlSta
#define		R_SavSta  	    IrReceDat.R_SavSta
#define		ReBitNum  	    IrReceDat.ReBitNum
#define		ReByteNum  	    IrReceDat.ReByteNum
#define		ReCont  	    IrReceDat.ReCont


//===============================
extern uint8 ReBuf[6] ;
extern uint8 ReSavBuf[6] ;

extern void ReceiveDat(void) ;
extern uint8 ValidRceMsg(void) ;

#endif


//文件urece.c

/*
********************************************************************************
* Description  : 
*     发射每段数据前必需加入一段引导码 以便接收端确认并开始接收数据
*     数据以脉宽调制的方式由高向低位发送出去

*     数据1为:1MS高  数据0为:1MS低
*
* 具本码形如下 :
*            +-----+
*            |     |          引导码
*            |     |           = 4ms 为低电平
*            |     |           = 4ms 为高电平
*  +---------+     +
*
*          +--+                               
*          |  |      数字1                          数字0
*          |  |                                     1MS  为低电平
*          |  |      1MS 为高电平                   
*          +  +                           +---+  
*
*  
* 

数据先发高位再发低位

检验码为前面5个字节相加 不管进位
 
***************************************************************************/



#include "global.h"
#include "urece.h"


IrReceData IrReceDat ;

uint8 ReBuf[6] ;  //临时接收区
uint8 ReSavBuf[6] ; //数据中转区

//*************************************
// 函数名称:ReceiveDat
// 函数功能:红外单线接收程序
// 入口参数:无
// 出口参数:无
//***************************************
void ReceiveDat(void)    //125u
{
    uint8 i ,Tmp;

    if(F_IrRecOk) return ;  //数据未取出 不接收数据

    R_LevlSta = 0 ;
    if(IrDatHigh)R_LevlSta++ ;
    if(IrDatHigh)R_LevlSta++ ;
    if(IrDatHigh)R_LevlSta++ ;

    R_SavSta <<= 1 ;

    if(R_LevlSta&SETB1) //Io为高电平 SETB1=0X02
    {
        R_SavSta |= 1 ;
    }

    if(F_IrBusy)   //总线正在接收数据
    {
        ReCont -- ;
        if(ReCont == 0)//已接收一BIT数据
        {
            ReBitNum -- ;
            //提取数据
            //P1 ^= 0X01 ; //--测试
            Tmp = R_SavSta ;
            for(i=8;i>0;i--)
            {
                if(Tmp &0x01)
                {
                    ReCont ++ ;    
                }
                Tmp >>= 1 ;
            }

            if(ReCont >= 5) //
            //if(ReCont < 4) //数据取反
            {
                ReBuf[ReByteNum] |= (1<<(ReBitNum)) ;   
//                Test_ON ;   //^^           
            }
            else
            {
//                Test_OFF ;   //^^
            }

            ReCont = V_NUM1 ;
            if(ReBitNum == 0)  //接收完一字节数据
            {
                ReBitNum = V_BITNUM ;
                ReByteNum ++;
                if(ReByteNum >= V_BYTENUM)//数据接收完成
                {
                    ReByteNum = 0 ;
                    F_IrBusy = 0 ; //释放总线
                    F_IrRecOk = 1 ; //置接收成功标志
//                  Test_OFF ; //^^
                }
            } 
                       
        }    
    }
    else  //总线处于空闲状态
    {
        if(!(R_SavSta & 0x01)) //总线置0 开始接收数据
        {
            F_IrBusy = 1 ; 
            ReCont = V_NUM1 ;
            ReBitNum = V_BITNUM ;
            ReByteNum = 0 ;    //接收数据总量清0
            for(i=0;i<V_BYTENUM;i++)
            {
                ReBuf[i] = 0 ;    
            }
            
        }    
    }  
}
//***************************************
// 函数名称:ValidRceMsg
// 函数功能:验证从机数据  两次接收到的数据一致认为接收成功
// 入口参数:无
// 出口参数:无
// 备注: 10ms跑一次
//***************************************
uint8 ValidRceMsg(void)  //
{
    uint8 i ;
    uint16 wTmp=0 ;

    if(F_IrRecOk)  //接收到数据
    {
        for(i=0;i<(V_BYTENUM-1);i++)
        {
            wTmp += ReBuf[i] ;    
        } 
               
        i = wTmp&0xff ;

        if(ReBuf[V_BYTENUM-1] == i)  //验证成功
        {
            return 1 ;
        }
        else
        {
            return 0 ;
        }

    }

    return 0 ;
}  




//应用实例
void main(void)
{


	while(1)
	{
		if(F_IrRecOk)
		{
			if(ValidRceMsg())//数据检验成功
			{
					//取数据
			}

			F_IrRecOk = 0 ;
		}
	}
}


//----中断函数------
void interrupt(void) //1MS
{
	ReceiveDat() ;   
}