您的位置:首页 > 其它

基于MODBUS实现的三遥控制程序

2007-12-03 17:49 281 查看
/**************************************************************************************
*时间:2007/12/3 *
*编程:马志晶 *
*运行环境:AT98S52 *
*功能:串口通信,应用MODBUS规约,通过主机向单片机发送指令实现遥信,遥控,遥测三遥功能 *
*主机客户端:DPM.exe *
**************************************************************************************/
#include"reg52.h"
#include"stdio.h"
#include <intrins.h>
sbit jdq=P1^4;
sbit aj=P3^2;
int s=0;
//unsigned char a[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
unsigned char shuma[11]={0xc0,0xf9,0xa4,0xb0, 0x99,0x92,0x82,0xf8,0x80,0x90, 0xff};
unsigned char zjdz[9]={0x01,0x02,0x03,0x04, 0x05,0x06,0x07,0x08,0x09}; //子机地址
unsigned char btl[4]={0xE8,0xF4,0xFA,0xFD}; //波特率
unsigned char c[2]={0x03,0xFD};
unsigned char b[2]={0xfe,0xef}; //子机参数(数码管选通)
unsigned char shu[2]={0xa4,0xb0}; //子机参数(数码管显示)
unsigned char deng=0xff;
unsigned char buf[8];
unsigned char buf1[2];
unsigned char buff[29];//{0x03,0x02,0x01,0x00,0xA0,0x30};
unsigned char wd[3];
sbit TMDAT =P1^3; //DS18B20的数据输入/输出脚DQ
unsigned int sdata;//测量到的温度的整数部分
bit fg=0; //接收一针完成标志
int num=0;
int z=0,y=1;
//***************************************初始化***********************************
void int_com()
{
TMOD=0X20;
TH1=c[1];
TL1=c[1];
TR1=1;
PCON=0X00;
SCON=0X50;
SM2=1;
//TI=1;
ES=1;
EA=1;
}
//-------------------------------温度函数ds18b20程序-------------------------------------
//******************************** 延时子程序 ***********************************************
delay(unsigned char ms)
{ //
unsigned char i;
while(ms--)
{
for(i = 0; i< 250; i++)
{
_nop_();
_nop_();
_nop_();
_nop_();
}
}
}
//**************************************** 延时函数 **********************************
void dmsec (unsigned int count)
{
unsigned char i;
while(count--)
{for(i=0;i<115;i++);}
}
//*************************************** 发送复位 ***********************************
void tmreset (void)
{
unsigned char i;
TMDAT=0;
for(i=0;i<103;i++);
TMDAT = 1;
for(i=0;i<4;i++);
}
//************************************** 读一位 ***************************************
bit tmrbit (void)
{
unsigned int i;
bit dat;
TMDAT = 0;
i++;
TMDAT = 1;
i++; i++; //微量延时
dat = TMDAT;
for(i=0;i<8;i++);
return (dat);
}
//************************************** 读一个字节 ************************************
unsigned char tmrbyte (void)
{
unsigned char i,j,dat;
dat = 0;
for (i=1;i<=8;i++)
{
j = tmrbit();
dat = (j << 7) | (dat >> 1);
}
return (dat);
}
//*************************************** 写一个字节 **********************************
void tmwbyte (unsigned char dat)
{
unsigned char j,i;
bit testb;
for (j=1;j<=8;j++)
{
testb = dat & 0x01;
dat = dat >> 1;
if (testb)
{
TMDAT = 0; //写0
i++; i++;
TMDAT = 1;
for(i=0;i<8;i++);
}
else
{
TMDAT = 0; //写0
for(i=0;i<8;i++);
TMDAT = 1;
i++; i++;
}
}
}
//************************************ 开始转换 ***********************************
void tmstart (void)
{
tmreset(); //复位
dmsec(1); //延时
tmwbyte(0xcc); //跳过序列号命令
tmwbyte(0x44); //发转换命令 44H,
}
//************************************** 读取温度 **************************************
void tmrtemp (void) //温度存在全局变量 sdata中.小数存在xiaoshu中
{
unsigned char a,b;
tmreset (); //复位
dmsec (1); //延时
tmwbyte (0xcc); //跳过序列号命令
tmwbyte (0xbe); //发送读取命令
a = tmrbyte (); //读取低位温度
b = tmrbyte (); //读取高位温度
if(b>0x7f) //最高位为1时温度是负
{
a=~a; //补码转换,取反加一
b=~b+1;
fg=0; //读取温度为负时fg=0
}
sdata = (a/16+b*16)*8; //整数部分
wd[0]=sdata&0xff;
wd[1]=sdata>>8;
}
//*********************************** 温度采集 **************************************
void DS18B20PRO(void)
{
tmstart(); //发送ds1820 开始转换
tmrtemp(); //读取温度,执行完毕温度将存于TMP中 //
}
//************************************* 校 验 ******************************************
void calccrc(unsigned char *bf,int n)
{
unsigned int crc=0xFFFF;
int i,j;
for(i=0;i<n-2;i++)
{
crc=crc ^ bf[i];
for(j=0;j<8;j++)
{
char TT;
TT=crc&1;
crc=crc>>1;
if (TT==1)
crc=crc^0xA001;
}
}
buf1[0]=crc&0xFF;
buf1[1]=(crc>>8)&0xFF;
}
//**************************************** 中断函数 *****************************************
int receive() interrupt 4
{
EA=0;
if(RI)
{
RI=0;
buf[z++]=SBUF;
if(z==8){fg=1;z=0;}
};
if(TI)
{
if(y>=num)
{
y=1;
TI=0;
};
if(TI)
{
SBUF=buff[y++];
TI=0;
};
}
EA=1;
}
//*************************************** 按键采集 *************************************
unsigned char ajcj()
{
unsigned char a;
a=*(unsigned char xdata *)0x8000;
return a;
}
//************************************* 遥 信 发 1 **************************************
void send1()
{
buff[0]=buf[0];//;0x03
buff[1]=buf[1];//;0x02
buff[2]=0x01;
buff[3]=ajcj();
calccrc(buff,6);
buff[4]=buf1[0];
buff[5]=buf1[1];
num=6;
SBUF=buff[0];
}
//************************************** 遥 信 发 2 ***************************************
void send2()
{
int i;
if(buf[1]==0x05)
{
for(i=0;i<8;i++)
{
buff[i]=buf[i];
}
if(buf[3]==0x00)
if(buf[4]==0xff){deng=deng&0xef;*(unsigned char xdata*)0x4000=deng;}
else {deng=deng|0xf0;*(unsigned char xdata*)0x4000=deng;}
else if(buf[3]==0x01)
if(buf[4]==0xff){deng=deng&0xf7;*(unsigned char xdata*)0x4000=deng;}
else {deng=deng|0x0f;*(unsigned char xdata*)0x4000=deng;};
num=8;
SBUF=buff[0];
}
if(buf[1]==0x01)
{
buff[0]=buf[0];
buff[1]=buf[1];
buff[2]=0x01;
*(unsigned char xdata*)0x4000=deng;
switch(deng)
{
case 0xff: buff[3]=0x00;break;
case 0xef: buff[3]=0x01;break;
case 0xf7: buff[3]=0x02;break;
case 0xe7: buff[3]=0x03;break;
default: break;
}
calccrc(buff,6);
buff[4]=buf1[0];
buff[5]=buf1[1];
num=6;
SBUF=buff[0];
}
}
//***************************************** 通信发 3 **************************************
void send3()
{
int j;
buff[0]=buf[0];
buff[1]=buf[1];
buff[2]=0x18;
buff[3]=wd[1];
buff[4]=wd[0];
for(j=5;j<27;j++)
buff[j]=0x00;
calccrc(buff,29);
buff[27]=buf1[0];
buff[28]=buf1[1];
num=29;
SBUF=buff[0];
}
//******************************** 本机参数设置程序 **************************************
void jk()
{
static i=2,j=3;
int l,k,n;
static m=0;
unsigned char a;
a=ajcj();
if(++m==2)
{
switch(a)
{
case 0xfe:c[0]=zjdz[++i];if(i>8)i=0;break; //子机地址 加
case 0xf7:c[0]=zjdz[--i];if(i<0)i=8;break; //子机地址 减
case 0xfd:c[1]=btl[++j];if(j>3)j=0;break; //分机波特率 加
case 0xef:c[1]=btl[--j];if(j<0)j=4;break; //分机波特率 减
default: break;
}
shu[0]=shuma[i];
shu[1]=shuma[j];
for(k=0;k<2;k++)
{
*(unsigned char xdata*)0x2000=b[k];
*(unsigned char xdata*)0x6000=shu[k];
if(k==0)
for(l=0;l<100;l++)
for(n=0;n<100;n++);
}
}
}
//****************************** 主 函 数 *******************************************
void main()
{
bit i=0;
int_com();
*(unsigned char xdata *)0x8000=0xff;
*(unsigned char xdata *)0x6000=0xff;
*(unsigned char xdata *)0x4000=0xff;
while(1)
{
DS18B20PRO();
while(!aj)
{
jk(); //本机参数设置程序
int_com(); //初始化
}
if((fg==1)&&(buf[0]==c[0]))//发送程序
{
fg=0;
switch(buf[1])
{
case 0x02: send1();break;//遥信发
case 0x05:
case 0x01: send2();break;//遥控发
case 0x03: send3();break;//遥测
default: break;
}
}
}
}
//********************************* 全部程序结束 **************************************** *
本文出自 “海之舟” 博客,请务必保留此出处http://mazhijing.blog.51cto.com/215535/53327
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: