这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 综合技术 » 基础知识 » 通讯问题

共2条 1/1 1 跳转至

通讯问题

院士
2006-09-17 18:14:16     打赏
通讯问题



关键词: 通讯     问题    

院士
2006-12-22 22:43:00     打赏
2楼
问 请教一下各位,通讯问题 我有四台设备要通讯 都是485口的,四台设备并在一起,其他三台可以通上,只有单片机的通不上??????   (单片机) 单通可以和西门子的PLC通上, 但和令两台设备通不上,西门子的PLC单通可以和令两台设备就能通上,这是为什么??????????那为大虾帮帮我十分感谢。
1: 最大的可能是波特率不准的原因也可能是程序流程问题。 2: 通讯问题 3: 通讯问题都是9600的,如果程序流程有问题,单片机为什么可以和西门子的PLC通上?????? 4: 不同产品的误差容限不同波特率是一方面,其它如485数据建立时间等等,不同设计的容限都不同,除硬指标如波特率、电压等外,其它的不配合都可用软件解决或因软件造成,如果是这方面的问题,不是“流程”是什么? 5: 楼上的哥哥帮帮小弟吧
chunyang你好:
          /* MODBUS通讯规约中CRC校验码地计算 */
#include "AT89X51.H"
#include "INTRINS.H"
#define uchar unsigned char
uchar in_command=0;
uchar sbuf_count=0;
char getsbuf[8];/*接受字符缓冲区*/
char return_xy[17]={0x01,0x01,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
char *pint3;
char outcount=0;
char m=17;/*返回数据字节数*/
void XyToCrc(char mm,char *pint);
void Init_SerialComm(void);
void Init_CpuIO(void);
void DelayX1ms(uchar count);
void outchar(char i);
void get_digital(void);
void main(void)
{

char *pint1;
char charx,chary;

Init_SerialComm();  /*初始化串口*/
  Init_CpuIO();   /*初始化IO口*/
  
for(;;)
{    
  get_digital();  /*采集数字量*/
  pint1=return_xy;
  return_xy[1]=0x01;
  return_xy[2]=0x0c;  
     XyToCrc(m-2,pint1); /*计算返回数据的校验码*/
     charx=return_xy[0];
  chary=return_xy[1];
     charx=return_xy[2];
  chary=return_xy[3];
  charx=return_xy[4];
  chary=return_xy[5];
  charx=return_xy[6];
  chary=return_xy[7];
  charx=return_xy[8];
  chary=return_xy[9];
  charx=return_xy[10];
  chary=return_xy[11];
  charx=return_xy[12];
  chary=return_xy[13];
  chary=return_xy[14];
  charx=return_xy[15];
  chary=return_xy[16];
  if (outcount>=m)
  {TI=0;RI=0;outcount=0;}
  if(in_command==1)
  {
   in_command=0;
   pint3=return_xy;
   outcount=0;
   XyToCrc(m-2,pint1); /*计算返回数据的校验码*/
   TI=1;  /*数据返回*/
   
  }
  
}
}
void Init_SerialComm(void)   /*初始化串口*/
{
SCON=0x50;   /*SCON: serail mode 1, 8-bit UART, enable receive*/
TMOD=0x20;   /*TMOD: timer 1, mode 2, 8-bit reload*/
TH1=0xfd;    /*baud rate 9600b/s  TH1=0xfd;    */
/*TL1=0xfd;*/
PCON=0x00;    /* SMOD=0*/
IE=0x90;      /*IE.7=EA=1;IE.4=ES=1,IE.3=ET1=0, IE.2=EX1=0,IE.1=ET0=0,IE.0=EX0=0,Enable global interrupt and serial interrupt*/
TR1=1;        /*start timer 1*/
}
void Init_CpuIO(void)         /*初始化IO口*/
{
P1=0xff;/*关闭采集口*/
P2=0xff;/*关闭采集口*/

/*p3_0=RXD,p3_1=TXD,p3_2=/INT0,p3_3=/INT1   P3口的第二定义在IE中设置起用*/
/*p3_4=T0,p3_5=T1,p3_6=/WR,p3_7=/RD      */
}
void DelayX1ms(uchar count)        /*延时1ms*/
{
uchar k;
while(count!=0)
{count--;
for(k=0;k<72;k++)    
{}
}
}
/*串口接收中断处理函数*/
void Serial(void)  interrupt 4
{
char *pint2;
char i,crcl=0,crch=0;
        if(RI)
        {
         RI=0;/* sbuf_count getsbuf[3] */
         getsbuf[sbuf_count++]=SBUF;
         switch(sbuf_count)    /*接收一个数据就判断一次是否是发给自己的命令*/
          {
            case 0x01:
                 if(getsbuf[0]!=return_xy[0])
                 sbuf_count=0x00;
                 break;     
            case 0x02:
                 if(getsbuf[1]!=0x01)
                 sbuf_count=0x00;
                 break;
            case 0x03:
                 if(getsbuf[2]!=0x00)
                 sbuf_count=0x00;
                 break;
            case 0x04:
                 if(getsbuf[3]!=0x00)
                 sbuf_count=0x00;
                 break;
            case 0x05:
                 if(getsbuf[4]!=0x00)
                 sbuf_count=0x00;
                 break;
            case 0x06:
                 if(getsbuf[5]!=0x60)
                 sbuf_count=0x00;
                 break;
            case 0x07:
                 break;     
            case 0x08:
             crcl=getsbuf[6];
             crch=getsbuf[7];
             pint2=getsbuf;            
   XyToCrc(6,pint2);    /*计算接受数据地校验码 */
   if(crcl==getsbuf[6] && crch==getsbuf[7]) /*接受地校验码和计算的校验码相同 */
   {
    in_command=1;    /*产生有效命令 */
   }
   else
   {
    in_command=0;
   }
   for(i=0;i<8;i++)
   {
    getsbuf[i]=0x00;   /*清接受缓冲区 */
   }
   crcl=0x00;crch=0x00;sbuf_count=0;
                 break;   
            default:
                  break;  
          }
}
if(TI)
{
  TI=0;
  if(outcount<m)
  {
   SBUF=*pint3;
   pint3++;
   outcount++;
  }
}


  
}
void XyToCrc(char mm,char *pint)
{
char i,j,k,crcl;
int xyl,crc;
crc=0xffff;   /*先将CRC寄存器全部置高*/   
for(i=0;i<mm;i++)    /*mm个数据计算CRC*/
{
  crcl=crc;  /*与CRC异或*/
  crcl^=*pint;
  xyl=crcl;
  xyl&=0x00ff;
  crc&=0xff00;
  crc|=xyl;
  for(j=0;j<=7;j++) /*计算八次*/
  {
   k=crc&0x0001;
   crc>>=1;
   crc&=0x7fff;   
   if(k==1) /*标志位*/
   {
    crc^=0xa001;    
   }
  }
pint++;   /*取下一个CHAR数据*/
}
/*下面将CRC结果低八位在前高八位在后传入发送缓冲区*/
xyl=crc;
xyl>>=8;
xyl&=0x00ff;
*pint=crc;
pint++;
*pint=xyl;
}
void outchar(char i)     /*数据返回*/
{
    char c;
    for( c=0;c<i;c++)
    {
     SBUF=return_xy[c];
    }
}
void get_digital(void) /*采集数字量*/
{
char i,num=0x01,x,y;

for(i=0;i<8;i++)  /*采集前八组数字量*/
{
  P2=0XFF;P1=~num;
  do /*去抖动*/
  {
   DelayX1ms(10);
   x=~P0;
   DelayX1ms(20);
   y=~P0;   
  }while(x!=y);
  return_xy[i+3]=x;
  num<<=1;
  
}
for(i=0,num=0x01;i<4;i++) /*采集后4组数字量*/
{
  P1=0XFF;P2=~num;
  do
  {
   DelayX1ms(10);
   x=~P0;
   DelayX1ms(20);
   y=~P0;   
  }while(x!=y);
  return_xy[i+11]=x;
  num<<=1;
  
}
P2=0xEF;/*采集本系统所设置的地址*/
do
{
  DelayX1ms(10);
  x=~P0;
  DelayX1ms(20);
  y=~P0;   
}while(x!=y);
return_xy[0]=x;

}
 6: 楼上的哥哥帮帮小弟吧.这是控制开关触电程序,小弟对这一点都不懂,能帮帮我吗?帮我改改可以吗?不胜感谢. 7: 抱歉,我可没有时间帮你看程序!    而且你可能来本坛的时间未久,如此寻求“帮助”的方式是本坛一向不提倡的。方法和方向性的指点俺老汉向来不吝,但如此直接给结果的还从未有过。过去、现在和未来,均此。

共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]