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

📄 comm_module.c

📁 一个电表的程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*===========================================================================
* 			 2006年。三星仪表SOC芯片开发项目
*
*
* 文件名称:Comm_Module.c
* 文件标识:
* 摘    要:  1、红外与rs485共用uart口
              2、通常在RS485口,红外接收RX低电平时引起INT0中断,通信口切换到红外通信(关闭INT0中断),
                 在一定时间后,自动切换到RS485(同时开INT0中断接收)。
              3、红外与RS485切换是由(IR_CTRL=1  RS485_CTRL = 0)切换到红外,(IR_CTRL=1  RS485_CTRL = 0)切换到RS485


*
* 当前版本:Ver 1.0
* 作    者:罗冬生
* 修改内容:
* 修改日期:
* 完成日期:



===============================================================================================*/
#ifndef   _Comm_Module_
#define   _Comm_Module_

//===============================================================================================

#include "includes.h"

//-----------------------------------------------------------------------------------------

#define  iD_err          0x02           //数据标识错误
#define  Password_err    0x04           //密码错误
#define  Data_err        0x01           //非法数据

#define  SysData_err     0x07           //系统数据错误


//-----------------------------------------------------------------------------------------

void Read_Response(void);
void  Write_Response(void);            //"04"写命令处理
void DL645_Command(void);
void DL645_DataSend(void);
//===============================================================================================
 unsigned char RxTxBuf[RxTxLenMax];        //收发数据缓冲区
 __idata unsigned char RxTxFlg;            //通信状态标志,0=空闲,1=正在接收,2=已接收完一帧数据,3=正在发送
 __idata unsigned char RxTxLen;            //收发数据长度
 unsigned char *RxTxAdr;                   //收发数据地址指针


 //                      Comm_Time;        // 通信接收与发送之间延时:nn(MS)*10
 //                  CommByte_Time;        // 通信字节之间延时:nn(ms)*10
//===============================================================================================

//          串行通信端口初始化 ,默认通信端口为RS485

void UartInit(void)
{

    EPCFG_bit.MODE38_TxD = 0;    //38KHz不输出到发送端口
    IR_CTRL =0;                  // 红外通信不使能, 即关闭红外
    RS485_CTRL = 1;              // RS585通信使能控制,使能RS485

    IE_bit.ES = 0;            //关闭UART收发中断
    //RxTxAdr = RxTxBuf;      //置接收指针
    RxTxFlg = 0;              //标志清零,处于接收状态

    SCON   = 0xD0;      //MODE3通信模式,接收使能。11010000B: SM0 SM1 SM2 REN TB8 RB8 TI RI
    SBAUDT = 0x07;      //波特率参数:DIV+SBTH = 7,DC = 0
    SBAUDF = 0xAB;      //使能uart内部时钟(0x80)作波特率发生器,SBAUDF =43=0x2B(不使用定时器1作波特率发生器)
    IE_bit.ES = 1;      //使能UART收发中断

    TCON_bit.IT0 = 1;   //外部输入(0为边沿触发)控制红外与RS485之间的切换
    TCON_bit.IE0 =0; // 1;   //外部输入0中断使能
  //  INTPR =1;
}

//===============================================================================================

//       外部中断0的中断程序

#pragma vector=0x03
__interrupt void INT0_ISR(void)
{
   CommHWDelyTime = 250;         //设置2s钟
   RS485_CTRL =0;                // 开通RS585通信   ,关闭
   IR_CTRL =1;                   //关闭红外通信     ,使能控制
   TCON_bit.IE0 = 0;             // 关闭外部输入0中断使能

}

/*=====================================================================================================

                 串口通信中断程序


* 函数名称:UART_ISR
*
* 摘    要:  接收和发送中断处理程序

*
* 当前版本:Ver 1.0
* 作    者:罗冬生
* 修改内容:
* 修改日期:
* 完成日期:
======================================================================================================*/


#pragma vector=0x23
__interrupt void UART_ISR(void)
{
   unsigned char i;
//-----------------------------------------------------------------------------------------
   if(SCON_bit.RI)                            //接收中断处理程序
   {
      i=SBUF;
      SCON_bit.RI=0;
      CommByte_Time = 8;                      //80ms(字节之间通信最大等待时间500ms)

        G_LED ^= 1;

      if  (IR_CTRL)
         CommHWDelyTime = 250;                //2000ms(红外通信延时)

      switch (RxTxFlg)                       //判断接收标志状态
      {
      case 0:                                //空闲状态
         if (i==0x68)
           {                                 //第一个68字符处理
            RxTxFlg = 1;
            RxTxBuf[0] =0x68;
            RxTxLen =1;
           }
         break;
      case 1:                               //正在接收状态
         if (RxTxLen >= RxTxLenMax)         //接收长度判断?
            RxTxFlg=0;                      //超出接收缓冲区清接收标志。
         else
         {
            RxTxBuf[RxTxLen] =SBUF;          //保存接收数据
            RxTxLen++;                       //修改计数值
            if  (RxTxLen==8)
            {
              if (i!=0x68)                  // 第二个68判断
                 RxTxFlg=0;                 // 接收错误
            }
            else if  (RxTxLen>=12)          // 长度单元接收数据判断处理
            {
              if (RxTxLen == RxTxBuf[9]+12 )
               {
                  if (i==0x16)                 //最后一个接收字符是否是"16"判断?
                     RxTxFlg=2;                //接收正确,置一帧接收标志
                  else
                     RxTxFlg=0;                //接收字符超过应接收长度
               }
              else if (RxTxLen > RxTxBuf[9]+12 )
               {
                 RxTxFlg=0;                //接收字符超过应接收长度
               }
            }
         }
         break;

      case 2:
         break;              //已有一帧数据待处理

      case 3:
         break;              //正在发送数据

      default :
         RxTxFlg=0;          //非正确数据,复位标志
      }
   }

//-----------------------------------------------------------------------------------------

   if  (SCON_bit.TI)                              // 发送中断服务程序
   {
      SCON_bit.TI = 0;                 //清发送中断
      if ((RxTxLen) && (RxTxFlg==3))
      {
        CommByte_Time =8;              //80ms(发送一个字节最大等待时间80ms)
        SendByte(*RxTxAdr);            //发送一个字节
        RxTxAdr++;
        RxTxLen--;

        if (IR_CTRL)                   //是否为红外通信?
        {
          CommHWDelyTime = 250;
        }

      }
      else if (RxTxFlg==3)
      {
        SCON_bit.RI=0;
        SCON_bit.REN = 1;            //开接收
        EPCFG_bit.MODE38_TxD = 0;    //关闭38KHz输出到发送端口
        RxTxFlg = 0 ;
      }
   }
}


/*=====================================================================================================


* 函数名称:CommModule_645
*
* 摘    要:  国标645通信处理程序 ,中断接收到一帧完整数据后进行处理

*
* 当前版本:Ver 1.0
* 作    者:罗冬生
* 修改内容:
* 修改日期:
* 完成日期:
======================================================================================================*/


void CommModule(void)
{
  if (Key_Prog)                  //编程按键测试
     Key = 0;
  else
  {
    LcdBuffer[11] |= 0x08;    //显示按键符号
    LcdUpData();              //刷新显示
    DelayMs(5);
    if (!Key_Prog)
    {
     Key_Flg = 1;             //置编程允许标志
     Key_Time = KeyMaxTime;           //编程开关有效时间
    }
  }


  switch (RxTxFlg)
  {
    case 1:
      if (!CommByte_Time)
         RxTxFlg = 0;                  //接收超时,清标志
      break;

    case 2:                            //有一帧通信命令要处理
      DL645_Command();                 // DL/T 645命令处理
      if (RxTxFlg !=3)
         RxTxFlg = 0;                  //没有数据发送清标志
      break;

    case 3:
     if (!CommByte_Time)
       UartInit ();                    //在设定的时间内没有发送完毕,初始化UART串口
     break;

    default:
      Comm_Flg=0 ;
  }
}

//--------------------------------------------------------------------------------

⌨️ 快捷键说明

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