#include "STC89C51RC_RD_PLUS.h"
#include "math.h"
#include "intrins.h"
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
extern volatile uchar IN_IO,OUT_IO; //定义IO输入输出映射
extern void input_io(void); //输入处理函数
extern void jd_on(uchar x); //接通继电器函数
extern void jd_off(uchar x); //断开继电器函数
extern uint CRC16(uchar *pushMsg,unsigned short usDataLen);//modbus crc 函数
extern uchar *pushMsg; /*要进行CRC校验的消息*/
uchar idata recebuf[16]=0; //接收数据缓冲区
uchar idata recebuf_com[16]=0; //接收命令数据缓冲区
uchar idata command_Len=0; //待处理命令消息字节长度
uchar idata command_ok=0; //接收到一个命令结束,等待处理时为1;否则为0.
uchar idata sendbuf[16]=0; //发送数据缓冲区
uchar idata send_Len=1; //发送数据长度
uchar idata rece_Len=0; //接收数据长度
uint idata ad1,ad2,ad3,ad4; //模拟量输入寄存器
uint idata ad_1[5],ad_2[5],ad_3[5],ad_4[5]; //模拟量滤波器
uchar idata addr; //本机地址
uint idata crc_z; //crc校验结果
uchar idata timer0_cn=0;
uchar code check=1; //奇偶校验。check=0时,偶校验;check=1时;奇校验
uchar idata js_check=0; //奇偶校验检查位。js_check=1时正确,js_check=2时错误!
uint TLC2543(uchar prot);//AD转换函数
void group_out_ad(void); //数据上传函数
void group_out_io(void); //数据上传函数
void delay(uchar x); //短延时函数
void AV_in(void); //模拟量输入函数
void Serial(void); //串口配置函数
void chenck_fun(uchar x);//
void command(void); //接收到的消息命令处理函数
void command_01(void);
void command_02(void);
void command_03(void);
void command_04(void);
void command_05(void);
void command_06(void);
void jc(void);
/*以下定义LED指示状态*/
sbit XJ=P3^7;
sbit RUN=P3^6;
/*以下定义为TLC2543 SPI口软件模拟及转换表数组*/
sbit cs=P3^5;
sbit clk=P3^2;
sbit din=P3^3;
sbit dout=P3^4;
uint code r[8]={128,64,32,16,8,4,2,1};
/*====延时函数=====*/
void delay(uchar x)
{
uchar i;
while(x--){for(i=0;i<25;i++);}
}
/*======================*/
/*======AD转换函数======*/
/* prot:通道号 */
/* return:函数返回值 */
/*======================*/
uint TLC2543(uchar prot)
{
uchar i;
uchar ad_reg; //通道号寄存器
uint rdsh=0,rdsl=0;
cs=0; //使能AD转换
ad_reg=prot; //取通道号
ad_reg=ad_reg<<4;
/*先写入通道号*/
for(i=0;i<8;i++)
{
din=(bit)(ad_reg&0x80);
clk=1;clk=0;
ad_reg=ad_reg<<1;
}
for(i=0;i<4;i++){din=0;clk=1;clk=0;} //补4个时钟
cs=1;delay(1);cs=0; //等待转换
ad_reg=prot; //取通道号
ad_reg=ad_reg<<4;
/*读AD转换结果*/
for(i=0;i<8;i++)
{
if(dout==1){rdsh+=r[i];}
din=1;
clk=1;clk=0;ad_reg=ad_reg<<1;
}
for(i=0;i<4;i++)
{
if(dout==1){rdsl+=r[i];}
din=0;
clk=1;clk=0;
}
cs=1;
return((rdsh<<4)+(rdsl>>4));
}
/*=========================*/
/*======模拟量输入函数=====*/
/*===4路模拟量读取及滤波===*/
/*=========================*/
void AV_in(void)
{
uchar i;
uint result;
for(i=0;i<=3;i++){ad_1[i]=ad_1[i+1];}
ad_1[4]=TLC2543(0);
result=0;
for(i=0;i<=4;i++){result+=ad_1[i];}
ad1=(result/5);
for(i=0;i<=3;i++){ad_2[i]=ad_2[i+1];}
ad_2[4]=TLC2543(1);
result=0;
for(i=0;i<=4;i++){result+=ad_2[i];}
ad2=(result/5);
for(i=0;i<=3;i++){ad_3[i]=ad_3[i+1];}
ad_3[4]=TLC2543(2);
result=0;
for(i=0;i<=4;i++){result+=ad_3[i];}
ad3=(result/5);
for(i=0;i<=3;i++){ad_4[i]=ad_4[i+1];}
ad_4[4]=TLC2543(3);
result=0;
for(i=0;i<=4;i++){result+=ad_4[i];}
ad4=(result/5);
}
/*===========================*/
/*=====下位机发送数据函数====*/
/*===========================*/
void group_out_ad(void)
{
uchar i;
uint k;
pushMsg=&sendbuf[0];
crc_z=CRC16(pushMsg,send_Len);//crc校验结果
k=crc_z;
sendbuf[send_Len]=(uchar)(crc_z>>8); //+CRC_Hi
send_Len++;
sendbuf[send_Len]=(uchar)k; //+CRC_Li
EA=0;
for(i=0;i<=send_Len;i++)
{
chenck_fun(sendbuf[send_Len]);
SBUF=sendbuf[i];while(!TI);TI=0;
}
EA=1;
send_Len=send_Len-2; //恢复
RUN=1;
}
/*==============*/
/*==系统主函数==*/
/*==============*/
void main (void)
{
AUXR = 0x01;
Serial();
IE =0x92;
IP =0x00;
TR0=1;RUN=1;XJ=1;
jd_off(0xff);
P0=0xFF;
while(1)
{
WDT_CONTR = 0x36;
addr=P0; //取地址
AV_in();
if(command_ok==1)
{XJ=0;command();}
}
}
void command(void) //接收到的消息命令处理函数
{
uint js_CRC,star_fun,sl_n,AI;
RUN=0;
pushMsg=&recebuf_com[0];
crc_z=CRC16(pushMsg,command_Len-2); //crc校验结果
js_CRC=recebuf_com[command_Len-2];
js_CRC=(js_CRC<<8)|((uint)(recebuf_com[command_Len-1]));
if((recebuf_com[0]==addr)&&(js_CRC==crc_z))//是否发给本机,并CRC正确?recebuf_com[0]地址 recebuf_com[1]功能码
{
switch (recebuf_com[1])
{
case 0x01: //读取线圈状态
{
star_fun=recebuf_com[2];star_fun=(star_fun<<8)|(recebuf_com[3]);//取开始地址
sl_n=recebuf_com[4];sl_n=(sl_n<<8)|(recebuf_com[5]); //读取地址
switch (star_fun)
{
case 0:
{
command_01();
sendbuf[3]=(0x01&OUT_IO)?1:0; //低
group_out_ad();
break;
}
case 1:
{
command_01();
sendbuf[3]=(0x02&OUT_IO)?1:0; //低
group_out_ad();
break;
}
case 2:
{
command_01();
sendbuf[3]=(0x04&OUT_IO)?1:0; //低
group_out_ad();
break;
}
case 3:
{
command_01();
sendbuf[3]=(0x08&OUT_IO)?1:0; //低
group_out_ad();
break;
}
case 4:
{
command_01();
sendbuf[3]=(0x10&OUT_IO)?1:0; //低
group_out_ad();
break;
}
case 5:
{
command_01();
sendbuf[3]=(0x20&OUT_IO)?1:0; //低
group_out_ad();
break;
}
default:
sendbuf[0]=addr; //取地址
sendbuf[1]=0xff; //命令号
send_Len=2; //发送数据长度
group_out_ad();
break;
}
break;
}
case 0x02: //读取输入状态
{
star_fun=recebuf_com[2];star_fun=(star_fun<<8)+recebuf_com[3];//取开始地址
//sl_n=recebuf_com[4];sl_n=(sl_n<<8)|(recebuf_com[5]); //读取的数量
switch (star_fun)
{
case 1:
{
command_02();
sendbuf[3]=(0x01&P1)?1:0; //低
group_out_ad();
break;
}
case 2:
{
command_02();
sendbuf[3]=(0x02&P1)?1:0; //低
group_out_ad();
break;
}
case 3:
{
command_02();
sendbuf[3]=(0x04&P1)?1:0; //低
group_out_ad();
break;
}
case 4:
{
command_02();
sendbuf[3]=(0x08&P1)?1:0; //低
group_out_ad();
break;
}
case 5:
{
command_02();
评论0