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

📄 hdlc_st30.c

📁 C51实现HDLC数据链路协议的源程序
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <reg51.h>

#define OFFSETTIME      6

#define FREQ            22.1184
#define HDLCCYCLE       54                     /*54uS*/
#define HDLCADDR        1                      /*本机地址=1,(0-7)*/

#define NONE            0                      /*接收状态,无*/
#define ERROR           1                      /*接收状态,错误*/
#define RIGHT           2                      /*接收状态,正确*/

#define CMD_DATA        0
#define CMD_REPEAT      1
#define CMD_OUTLINE     2
#define CMD_NO          3

#define ADBUFMAX        31                     /*30个数据*/

#define FALSE           0
#define TRUE            1

#define COMMAND         1
#define DATARECI        2
#define COMDRECI        3
#define ERRORRECI       4

#define HDLC_HEADHIGH   56

#define RFSEND          1
#define RFRECI          0

code unsigned char  Con_Crc[256]={0x00, 0x5e, 0xbc, 0xe2, 0x61, 0x3f, 0xdd, 0x83,
                 0xc2, 0x9c, 0x7e, 0x20, 0xa3, 0xfd, 0x1f, 0x41,
                 0x9d, 0xc3, 0x21, 0x7f, 0xfc, 0xa2, 0x40, 0x1e,
                 0x5f, 0x01, 0xe3, 0xbd, 0x3e, 0x60, 0x82, 0xdc,
                 0x23, 0x7d, 0x9f, 0xc1, 0x42, 0x1c, 0xfe, 0xa0,
                 0xe1, 0xbf, 0x5d, 0x03, 0x80, 0xde, 0x3c, 0x62,
                 0xbe, 0xe0, 0x02, 0x5c, 0xdf, 0x81, 0x63, 0x3d,
                 0x7c, 0x22, 0xc0, 0x9e, 0x1d, 0x43, 0xa1, 0xff,
                 0x46, 0x18, 0xfa, 0xa4, 0x27, 0x79, 0x9b, 0xc5,
                 0x84, 0xda, 0x38, 0x66, 0xe5, 0xbb, 0x59, 0x07,
                 0xdb, 0x85, 0x67, 0x39, 0xba, 0xe4, 0x06, 0x58,
                 0x19, 0x47, 0xa5, 0xfb, 0x78, 0x26, 0xc4, 0x9a,
                 0x65, 0x3b, 0xd9, 0x87, 0x04, 0x5a, 0xb8, 0xe6,
                 0xa7, 0xf9, 0x1b, 0x45, 0xc6, 0x98, 0x7a, 0x24,
                 0xf8, 0xa6, 0x44, 0x1a, 0x99, 0xc7, 0x25, 0x7b,
                 0x3a, 0x64, 0x86, 0xd8, 0x5b, 0x05, 0xe7, 0xb9,
                 0x8c, 0xd2, 0x30, 0x6e, 0xed, 0xb3, 0x51, 0x0f,
                 0x4e, 0x10, 0xf2, 0xac, 0x2f, 0x71, 0x93, 0xcd,
                 0x11, 0x4f, 0xad, 0xf3, 0x70, 0x2e, 0xcc, 0x92,
                 0xd3, 0x8d, 0x6f, 0x31, 0xb2, 0xec, 0x0e, 0x50,
                 0xaf, 0xf1, 0x13, 0x4d, 0xce, 0x90, 0x72, 0x2c,
                 0x6d, 0x33, 0xd1, 0x8f, 0x0c, 0x52, 0xb0, 0xee,
                 0x32, 0x6c, 0x8e, 0xd0, 0x53, 0x0d, 0xef, 0xb1,
                 0xf0, 0xae, 0x4c, 0x12, 0x91, 0xcf, 0x2d, 0x73,
                 0xca, 0x94, 0x76, 0x28, 0xab, 0xf5, 0x17, 0x49,
                 0x08, 0x56, 0xb4, 0xea, 0x69, 0x37, 0xd5, 0x8b,
                 0x57, 0x09, 0xeb, 0xb5, 0x36, 0x68, 0x8a, 0xd4,
                 0x95, 0xcb, 0x29, 0x77, 0xf4, 0xaa, 0x48, 0x16,
                 0xe9, 0xb7, 0x55, 0x0b, 0x88, 0xd6, 0x34, 0x6a,
                 0x2b, 0x75, 0x97, 0xc9, 0x4a, 0x14, 0xf6, 0xa8,
                 0x74, 0x2a, 0xc8, 0x96, 0x15, 0x4b, 0xa9, 0xf7,
                 0xb6, 0xe8, 0x0a, 0x54, 0xd7, 0x89, 0x6b, 0x35};

sbit HDLCOUT=P1^4;                             /*输出口*/
sbit HDLCTXEN=P1^5;                            /*=1发送;=0接收*/
sbit HDLCIN=P3^3;                              /*输入口*/
sbit SENSORSTAT=P1^7;                          /*传感器状态*/
sbit LEDOUT=P3^7;

bit f_SendBufFlow;
bit f_SendBusy;
bit f_AD_Over=0;                               /*AD转换完标志*/
bit f_ADFlow=0;                                /*AD缓冲区满标志*/
bit f_HDLCStat;

unsigned char Check_Sum;

union DataUnion{
 unsigned int Int; 
 unsigned char Char;
}AD_TempReg,AD_OffsetReg;

unsigned int AD_AbsValue=0;


#define OUTMODE() EX0=0;TR0=0;HDLCOUT=1;HDLCTXEN=RFSEND
#define INMODE()  HDLCTXEN=RFRECI

unsigned char mTask_ID;

/***********************************************************************/
unsigned char mData_Reg;
unsigned char mByte_Counter;                   /*移位字节计数器*/
unsigned char mBit_Counter;                    /*移位位计数器*/

unsigned char mHdlc_LoopCounter;               /*HDLC位计数*/

unsigned char mHDLC_Cmd;                       /*命令寄存器*/
unsigned char mHDLC_Addr;                      /*地址寄存器*/

unsigned char HDLC_ReciStat;                   /*接收状态*/

unsigned char SendByte_Counter;                /*HDLC移位字节计数器*/
unsigned char SendBit_Counter;                 /*HDLC移位位计数器*/
extern unsigned char Send_Buf[ADBUFMAX+3];

unsigned char ADByte_Counter=0;
unsigned char ADBit_Counter=0;
unsigned char AD_Ins0_Reg=0;
extern unsigned char AD_Buf[ADBUFMAX+3];

unsigned int AD_DataPoint=0;

unsigned char AD_Counter=ADBUFMAX;


void ExtInt0_Init()
{
  IT0=0x3;                                     /*INT0下降沿触发;*/
  EX0=1;
}

void ExtInt0(void) interrupt 0 {               /*int0中断*/
     TL0=0X100-(FREQ*HDLCCYCLE/12)+OFFSETTIME; /*采样时间/2*/
     EX0=0;
     TR0=1;
     TF0=1;
}

/**********************************************************
定时器
设置定时器0为HDLC采样时间中断,自动重装
设置定时器1为限时器
设置定时器2为波特率发生器
**********************************************************/
void Timer0_Init(void)
{
  TMOD|=0x2;                                   /*T0自动装载方式.*/
  TH0=0X100-FREQ*HDLCCYCLE/12;                 /*22.182MHZ*/
  TL0=0X100-FREQ*HDLCCYCLE/12;

  ET0=1;
}

void Timer1_Init(void)
{
  TMOD|=0x10;                                  /*T1:16位方式.*/
  TH1=(unsigned char)((0X10000-8000*FREQ/12)/256); /*8ms*/
  TL1=(unsigned char)(0X10000-8000*FREQ/12); 
  TR1=1;
  ET1=1;
}


/*采样数据*/
void timer1(void) interrupt 3 {                /*T1中断*/
  TL1+=(unsigned char)(0X10000-8000*FREQ/12)+2;
  TH1=(unsigned char)((0X10000-8000*FREQ/12)/256);
  f_AD_Over=1;
}

void PushAdBuf(unsigned int P_Data,unsigned char P_Bits)
{
  char i;

  for(i=0;i<P_Bits;i++){
    AD_Ins0_Reg<<=1;
    if(P_Data&1){
      P_Data>>=1;
      AD_Buf[ADByte_Counter]|=ADBit_Counter;
      AD_Ins0_Reg|=1;
    }
    else {
      P_Data>>=1;
Push_Next:
      AD_Buf[ADByte_Counter]&=~ADBit_Counter;
    }

    ADBit_Counter<<=1;                         /*指示位置移动*/
    if(ADBit_Counter==0){
      ADBit_Counter=1;
      ADByte_Counter++;
    }

    if((AD_Ins0_Reg&0x7f)==0x7f){              /*插0*/
      AD_Ins0_Reg<<=1;
      goto Push_Next;
    }

  }
}

/***************************************************************************
AD数据->发送缓冲区
成功,返回
****************************************************************************/
void Tran_ADToSend()
{
unsigned char i;

  if(f_ADFlow){                                /*AD缓冲满*/
    if(f_SendBusy)return;                      /*正在发送,退出*/
      Check_Sum+=HDLCADDR;
      PushAdBuf(Con_Crc[Check_Sum],8);        /*根据HDLC压入缓冲区 */
      for(i=0;i<ADBUFMAX+3;i++)Send_Buf[i]=AD_Buf[i];

      SendByte_Counter=ADByte_Counter;
      SendBit_Counter=ADBit_Counter;
      ADByte_Counter=0;
      ADBit_Counter=0;
      AD_Counter=ADBUFMAX;
      f_ADFlow=0;                             /*AD缓冲区空*/

      f_SendBufFlow=1;                        /*发送缓冲区满*/
  }
}


/************************************************************************
AD情况检查
************************************************************************/
void AD_CheckState()
{
unsigned char i;
 
  if((!f_AD_Over)|f_ADFlow)return;            /*无AD转换完标志或有AD缓冲满标志,退出*/
  f_AD_Over=0;
  AD_TempReg.Int=AD_DataPoint;
  AD_DataPoint+=2;
  if(AD_DataPoint>0xfff)AD_DataPoint=0;

  if((ADByte_Counter==0)&&(ADBit_Counter==0)){ /*开始写入绝对值*/
    Check_Sum=AD_TempReg.Char+*(&AD_TempReg.Char+1);
    ADBit_Counter=1;
    AD_Ins0_Reg=0;
    PushAdBuf(AD_TempReg.Int,12);              /*根据HDLC压入缓冲区*/
    AD_AbsValue=AD_TempReg.Int;
  }
  else {
    AD_OffsetReg.Int=AD_TempReg.Int-AD_AbsValue;
    if(AD_OffsetReg.Char&0x80){
        AD_OffsetReg.Int=(~AD_OffsetReg.Int)+1;
        if(AD_OffsetReg.Int>0x7f)i=0xff;
        else i=*(&AD_OffsetReg.Char+1)|0x80;
        AD_AbsValue-=(i&0x7f);
    }
    else {
        if(AD_OffsetReg.Int>0x7f)i=0x7f;
        else i=*(&AD_OffsetReg.Char+1);
        AD_AbsValue+=i;
    }
    
    PushAdBuf(i,8);                            /*根据HDLC压入缓冲区*/
    Check_Sum+=i;
  }
  if((--AD_Counter)==0){
     f_ADFlow=1;
  }
}


/***********************************************************************
HDLC采样任务初始化
***********************************************************************/
void Task_Init(void)
{
  HDLC_ReciStat=NONE;
  mTask_ID=0;
}

/*HDLC采样任务运行*/
/***************************************************************************
接收
****************************************************************************/
void timer0(void) interrupt 1 using 1{         /*T0中断*/

  f_HDLCStat=HDLCIN;
  
  switch(mTask_ID){
    case 0:                                    /*等待低电平为起始*/
            if(f_HDLCStat){
              TR0=0;
              EX0=1;
              break;              
            }

⌨️ 快捷键说明

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