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

/**************************************************************************************
*时间: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;
   } 
    }
 } 
}
//*********************************  全部程序结束  **************************************** *

你可能感兴趣的:(modbus,遥控,遥测,要信,三遥)