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

📄 pdemo_df.c

📁 此程序为晓成公司的参考程序资料
💻 C
📖 第 1 页 / 共 2 页
字号:
// 单、复费率载波DEMO收发板程序
// 适用费率规约:  不加跳线端子,适用于复费率
//                 4、5脚加跳线端子,适用于单费率
// CPU :PL3105
// 功能:1. 接收PC机串口下发的抄表命令并通过载波转发
//       2. 接收载波返回的抄表应答命令并通过串口转发给PC机
// 串口波特率:  2400BPS  无校验
// 复费率接收最长有效字节数:247
// 单费率接收最长字节数:14
// 程序完成日期: 2004年2月27日
// 

#include "PL3105.h"

#define uchar unsigned char
#define uint  unsigned int

//I/O 口设置
sbit RXD_TXD = P3^7;    // 载波数据输入、输出口
sbit txd     = P3^1;    // 向上发
sbit rxd     = P3^0;    // 串口收
sbit rlamp   = P1^2;    // 接收指示灯
sbit tlamp   = P1^3;    // 发送指示灯
sbit d_f     = P1^1;    // 单——复费率转换

// 全局变量设置
uchar bdata pl_data;          // 发送字节缓冲
sbit  pl_h=pl_data^7;
uchar  data  pl_len,ti_len;   // 发送字节计数
uchar data  d_f_x;            // 单——复费率标识
uchar data  pl_8;             // 发送位计数
uchar data  x,n,plret_l;
uchar xdata r[250];
uchar data  ystxd;//, ysrxd;
uint  data   x_09af;
uchar data   r_data,r_8;
uchar data   wdi;
uchar data   r_len,r_len1;
// 位变量
bit   bdata  r_x,r_d;
bit   bdata  plmrxd;
bit   bdata  plmtxd;
uchar xdata   pl_buf[250];

/////////////////////////////////////
// 定时器0中断程序
// 功能: 对延时变量进行减1处理
/////////////////////////////////////
void  timeint0(void) interrupt 1   //  定时中断程序 50 ms 发生一次中断
{ if  (ystxd!=0)
     {  ystxd--;
     }
  TH0=0x63;                        // 置定时器计数  50ms 中断一次( 12MHz )
  TL0=0xcc;
  if(wdi==0x9a)
    { WDT_RST=0xa1;                // 清看门狗
      wdi=0;
    }
}

////////////////////////////////////
// 载波中断收、发程序
// 入口:PLM_RS
//       PLM_RS=0  载波接收;  PLM_RS=1 载波发送
// 返回: plmrxd=1  载波接收成功
//       pl_buf[]  载波接收成功的数据
////////////////////////////////////
void  pl_pro(void) interrupt 7
{ uchar data i;
  if(d_f_x=='D') goto d_zb;
                      // 复费率载波处理
  if(PLM_RS)
      { // 载波发送
        if(pl_8<8)
            {  RXD_TXD=pl_h;
               pl_8++;
               pl_data=pl_data<<1;
               if(pl_8==8)  goto pl_ret;
            }
          else
            { pl_ret:
              pl_8=0;                         // 位计数清0
              pl_len++;                       // 发送长度加1
              plret_l++;
              pl_data=r[pl_len];              // 下一个字节
              if(plret_l==20) { PLM_RST=0xa2; plret_l=0; }
              if((pl_len>=ti_len)||(pl_len>240))
                {  //发送完成
                  PLM_RS=0;     // 置成收态
                  ti_len=0;  pl_data=0; pl_8=0;
                  for(pl_len=0;pl_len<20;pl_len++)
                    r[pl_len]=0;
                  pl_len=0;  RXD_TXD=1;
                  tlamp=1;                    // 发送指示灯灭
                  plmtxd=0;                   // 清正在发送标志
                }
            }
      }
     else
      { // 载波接收
         RXD_TXD=1;
         if (r_x==0)
            { if (RXD_TXD==1)
                 { x_09af=x_09af|1; }
              if (x_09af==0x09af)
                 { r_x=1; r_8=0; r_d=0; x_09af=0; r_data=0;
                   rlamp=0;                // 接收指示灯亮
                 }
                else  { x_09af=x_09af<<1; }
            }
          else  { if (r_d==0)
                   {  if (RXD_TXD==1)
                         r_data=r_data|1;
                      r_8++;
                      if (r_8!=8)
                         r_data=r_data<<1;
                        else  { pl_buf[0]=r_data; r_8=0;  r_d=1;
                                r_len=1;     r_data=0;  r_len1=240;
                              }
                    }
                   else  { if (RXD_TXD==1)
                              r_data=r_data|1;
                           r_8++;   r_d=1;
                           if (r_8!=8)
                              r_data=r_data<<1;
                             else  { pl_buf[r_len]=r_data; r_8=0;
                                     if(r_len==4)  { r_len1=r_data+7; }
                                     r_len++; r_data=0;
                                     if (r_len>=r_len1)
                                       { r_x=0;  r_d=0;  plmrxd=1;
                                         rlamp=1;                // 接收指示灯灭
                                       }
                                   }
                          }
                 }
      }
  goto  zb_end;

  d_zb:                // 单费率载波处理
   if(PLM_RS)
      { // 载波发送
        if(pl_8<8)
            {  RXD_TXD=pl_h;
               pl_8++;
               pl_data=pl_data<<1;
               if(pl_8==8)  goto pl_ret_d;
            }
          else
            { pl_ret_d:
              pl_8=0;                         // 位计数清0
              pl_len++;                       // 发送长度加1
              pl_data=r[pl_len];              // 下一个字节
              if(pl_len==20) PLM_RST=0xa2;    // 复位发送计数器
              if((pl_len>=ti_len)||(pl_len>40))
                {  //发送完成
                  PLM_RS=0;     // 置成收态
                  ti_len=0;  pl_data=0; pl_8=0;
                  for(pl_len=0;pl_len<20;pl_len++)
                    r[pl_len]=0;
                  pl_len=0;  RXD_TXD=1;
                  tlamp=1;                    // 发送指示灯灭
                  plmtxd=0;                   // 清正在发送标志
                }
            }
      }
     else
      { // 载波接收
         RXD_TXD=1;
         if (r_x==0)
            { if (RXD_TXD==1)
                 { x_09af=x_09af|1; }
              if (x_09af==0x09af)
                 { r_x=1; r_8=0; r_d=0; x_09af=0;  r_data=0;
                   rlamp=0;                // 接收指示灯亮
                 }
                else  { x_09af=x_09af<<1; }
            }
          else  { if (r_d==0)
                   {  if (RXD_TXD==1)
                         r_data=r_data|1;
                      r_8++;
                      if (r_8!=8)
                         r_data=r_data<<1;
                        else  { i=r_data;  i=i&0x20;
                                if(i==0x20) r_len1=14;   // 上行
                                  else                   // 下行
                                   {  i=r_data; i=i&0x18;
                                      if((i==0x18)||(i==0x10))
                                         { i=r_data; i=i&0x07;
                                           r_len1=8+(2*i);
                                         }
                                        else
                                         if(i==0x08) r_len1=8;
                                           else r_len1=14;
                                   }
                                pl_buf[0]=r_data; r_8=0;  r_d=1;
                                r_len=1;     r_data=0;
                              }
                    }
                   else  { if (RXD_TXD==1)
                              r_data=r_data|1;
                           r_8++;
                           if (r_8!=8)
                              r_data=r_data<<1;
                             else  { pl_buf[r_len]=r_data; r_8=0;
                                     r_len++; r_data=0;
                                     if (r_len>=r_len1)
                                       { r_x=0;  r_d=0;  plmrxd=1;
                                         rlamp=1;                // 接收指示灯灭
                                       }
                                   }
                          }
                 }
      }
  zb_end:;
}

///////////////////////////////////
// 初始化设置函数
// 功能:进行系统初始化设置
///////////////////////////////////
void initsys(void)
{  // 控制看门狗喂狗时间长度
  CKCON=0X3F;
  // 8位/16位运算模式选择位设置
  ALU_MOD=0;      // 设置成8位运算模式
  //载波通讯配置
  PLM_SSC=1;      // (D8H)使能载波通讯PLM_SSC(EXT_CFG.0)=1
  EIE=0X01;       // (A9H 使能INT2中断(EX2=1)
  IT2=1;          // (C8H) 为边沿触发方式(IT2=1)。
  PLM_RS=0;       // PLM_RS(EXT_CTRL.0)=1  为0时,载波处于接收状态
  //串口通讯配置
  TMOD = 0x21 ;   // 设 T/C1 为定时方式2 设置为8位自装载计数器  T/C0 为定时方式 14
  SCON=0x50;      // 工作方式1
  PCON=0X80;      // 波特率加倍
  TH1=0xf6;
  TL1=0xf6;       // 加倍设定波特率 9.6MHz(PL3105按4800计算) 下数 F6H
  TR1=1;          // 启动定时器1
  // 不显示使能
  LED_LCD=0;
  // 定时器0中断配置
  TH0=0x63;  TL0=0xcc;   // 定时 50 ms 一个定时中断
  TR0 = 1;               // 启动 T0 定时器
  // 中断级别设置
  IP=0x02;               // 定时器 T0 中断为高级中断
  EIP=1;                 // 外部中断2 为高级中断
  // 中断允许设置
  IE=0x82;               // 允许ET0=1定时器 T0 中断;  开放中断
}

///////////////////////////////////
// 初始化重置函数
// 功能:进行系统初始化重置
///////////////////////////////////
void initsys_ref(void)
{  // 载波设置重置
   uchar  data i;
   if (PLM_SSC!=1) PLM_SSC=1;      // (D8H)使能载波通讯PLM_SSC(EXT_CFG.0)=1
   if (EIE!=1)     EIE=0X01;       // (A9H 使能INT2中断(EX2=1)
   if (IT2!=1)     IT2=1;          // (C8H) 为边沿触发方式(IT2=1)
   // 串口设置重置
   if (TMOD!=0x21) TMOD = 0x21 ;   // 设 T/C1 为定时方式2 设置为8位自装载计数器  T/C0 为定时方式 14
   if (PCON!=0x80) PCON=0X80;      // 波特率加倍
   i=SCON;
   i=i&0xf0;
   if(i!=0x50)  initsys();
   if (TH1!=0xf6)  TH1=0xf6;
   if (TR1!=1)     TR1=1;          // 启动定时器1
   // 中断设置重置
   if (IE!=0x82)   IE=0x82;
   if (IP!=2)      IP=2;
   if (EIP!=1)     EIP=1;          // 外部中断2 为高级中断

⌨️ 快捷键说明

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