#include "PL3200.h"
#define LIMIT_3105 0x30 // lxw载波序列捕获门限
#define LIMIT_3200 0x70 // lxw载波序列捕获门限
#define uchar unsigned char
#define uint unsigned int
//I/O 口设置
sbit RS_TLED = P0^3; // 串口发送指示灯D3
sbit RS_RLED = P0^4; // 串口接收指示灯D4
sbit PLC_TLED = P0^5; // 载波发送指示灯D5
sbit PLC_RLED = P1^2; // 载波接收指示灯D6
sbit FUNC_LED = P0^2; // 载波通讯方式,亮:3200模式;灭:3105模式D2
sbit function = P1^3; // 载波通讯方式,0:3200模式;1:3105模式D12
sbit PSK_OUT = P3^7; //
sbit Rxd_p30 = P3^0; //
sbit Txd_p31 = P3^1; //
// 全局变量设置
uchar data function_now; // 当前的通讯方式,0:3200方式。0xff:为3105模式
uchar data function_flage; // time = 6 sec
uchar data COM_recv_len; // 串口接收数据长度
uchar data COM_State; // the state of com receive
uchar data COM_recv_pointer; // 表示串口接收控制变量
uchar data COM_send_timer; // 延时时间变量
uchar data PLC_Rxd_pointer; // 载波接收过程中的字节数
uchar data PLC_Rxd_tlen; // PLC 接收total len
uchar bdata PLC_data; // 发送字节缓冲
uchar data PLC_send_pointer; // 载波发送字节计数
uchar data PLC_timer; // 载波发送延时计数器
uchar data PLC_total_len; // 载波发送字节长度+8
uchar data PLC_Rxd_timer; // 载波发送延时时间变量
uchar data PLC_Rxd_tdata; // PLC_recieve cusion
uchar data WDI; // 软狗变量
// 位变量
bit bdata PLC_Rxd_flag; // 载波有接收标志
bit bdata PLC_Rxd_state; // 载波接收控制变量
bit bdata PLC_Rxd_OK; // 载波接收完成标志
bit bdata PLC_sending; // 载波正在发送标志
uchar xdata PLC_recv_buf[250]; // 载波接收缓冲区
uchar xdata COM_recv_buf[250]; // 串口接收缓冲区
uchar xdata R_T_buf_bak[250]; // 通讯数据备份
/**************************************************************************************
*
* FUNCTION: timeint0
*
* DESCRIPTION: 定时器0中断程序;
* 50 ms 发生一次中断
* 对延时变量进行减1处理
*
* PARAMETERS: none
*
* RETURNED: none
*************************************************************************************/
void timeint0 ( void ) interrupt 1
{
if ( COM_send_timer!=0 )
{
COM_send_timer--; // 串口发送延时
}
if ( PLC_Rxd_timer>0 )
{
PLC_Rxd_timer--;
}
else
{
PLC_Rxd_timer=0;
PLC_RLED=1; // turn off the lamp of receiving
PLC_Rxd_state=0; // resume receive state
}
if ( PLC_timer>0 ) //增加载波发送延时控制lxw2006-3-2
PLC_timer--;
if ( function_flage ) function_flage--;
else
{
function_flage=10;
if ( function ) //载波方式管脚判断
function_now = function_now *2 + 1; //function_now=0xff为3105方式lxw2006-2-10
else
function_now = function_now *2; //function_now=0为3200方式lxw 2006-2-10
}
TH0=0x63; // 置定时器计数 50ms 中断一次 ( 12MHz )
TL0=0xcc;
if ( WDI == 0x9a )
{
WDT_RST=0xa1; // 清看门狗
WDI=0;
}
}
/**************************************************************************************
*
* FUNCTION: txdbyte
*
* DESCRIPTION: 一字节串口发送函数
*
* PARAMETERS:
* in: dachar——要发送的1字节数据
* out: none
*
*
* RETURNED: none
*
*************************************************************************************/
void txdbyte ( uchar dachar ) // 单片机串口发送
{
SBUF=dachar;
COM_send_timer=10; // 500毫秒钟发送不成功退出
while ( !TI )
{
if ( COM_send_timer == 0 )
break;
}
TI=0;
}
/**************************************************************************************
*
* FUNCTION: PLC_int
*
* DESCRIPTION: 载波中断收、发程序
*
* PARAMETERS:
*
* out: PLC_Rxd_OK=1 载波接收成功
* R_T_buf_bak[] 载波接收成功的数据
*
* RETURNED: none
*************************************************************************************/
void PLC_int ( void ) interrupt 7
{
uchar data i;
uchar data state; // 载波通讯状态
uchar data SSC_adr_bak;
SSC_adr_bak=SSC_ADR; //PRTECT
SSC_ADR=0x00; //选择载波状态寄存器
state= SSC_DAT;
// if ( ( state&0x80 ) == 0x0 )
// return;
if ( ( state&0x01 ) == 1 ) //载波发送状态
{ // 载波发送
if ( ( PLC_send_pointer < PLC_total_len ) &&
( PLC_send_pointer < 240 ) )
{
SSC_BUF=R_T_buf_bak[PLC_send_pointer]; //发送下一个字节
PLC_send_pointer+=1;
}
else
{ //发送完成
PLC_sending=0; // 清正在发送标志
PLC_data=0;
PLC_TLED=1; // 发送指示灯灭
}
}
else
{ // 载波接收
PLC_Rxd_timer=20; // 最大字节接收延时时间为1S
if ( ( state&0x04 ) == 0x04 ) //如果接收的是祯头标志
{
if ( PLC_Rxd_state == 0 ) //如果处于等待接收状态
{
PLC_Rxd_tdata=SSC_BUF; //接收第一个字节,并准备接收后面的字节
PLC_Rxd_tlen=PLC_Rxd_tdata;
PLC_recv_buf[0]=PLC_Rxd_tdata;
PLC_Rxd_pointer=1; //lxw2006-3-2 17:07
//PLC_Rxd_tlen =60;
PLC_Rxd_state=1;
PLC_RLED=0; //接收指示灯亮
}
else // translate to rec
{
PLC_Rxd_state=0;
SSC_ADR=0X0;
SSC_DAT=0X0;
}
}
else
{
if ( PLC_Rxd_state == 1 ) // 如果已经接收了祯头,继续接收后续字节
{
PLC_Rxd_tdata=SSC_BUF;
PLC_recv_buf[PLC_Rxd_pointer]=PLC_Rxd_tdata;
/* if ( PLC_Rxd_pointer == 0x04 ) // 接收到了载波字节个数
{
PLC_Rxd_tlen=PLC_Rxd_tdata+7; // 加7的意思是3个地址码+1个控制码+1个长度码+2个校验码
if ( PLC_Rxd_tlen>100 )
PLC_Rxd_tlen=100; // 接收字节长度限制
}*/
PLC_Rxd_pointer+=1;
if ( PLC_Rxd_pointer>PLC_Rxd_tlen )
{
PLC_Rxd_OK=1;
PLC_RLED=1; //接收完毕灯灭
PLC_Rxd_state=0;
for ( i=0 ; i< ( PLC_Rxd_tlen+1 ) ; i++ )
{
R_T_buf_bak[i]=PLC_recv_buf[i];
}
SSC_ADR=0X0; // translate to rec
SSC_DAT=0X0;
}
}
else // translate to rec
{
PLC_Rxd_state=0;
SSC_ADR=0X0;
SSC_DAT=0X0;
}
}
}
SSC_ADR=SSC_adr_bak;
}
/**************************************************************************************
*
* FUNCTION: set_PLC_3200
*
* DESCRIPTION: set the PLC function of pl3201
*
* PARAMETERS: none
*
* RETURNED: none
* EDITION: V1.0
*************************************************************************************/
void set_PLC_3200 ( )
{
SSC_ADR=0XFF; // 2005.11.29 LXW
SSC_DAT=0XFF; // 禁止写保护
SSC_ADR=0x03; // 选择3201载波通讯控制寄存器3
SSC_DAT=0xc0; // 开启载波通讯功能,打开中断,选择接收状态置为3200模式
SSC_ADR=0x04; // 设置捕获门限
SSC_DAT=LIMIT_3200;
SSC_ADR=0XFF;
SSC_DAT=0XAA; // 使能写保护
}
/********************************************************************