您的位置:程序门 -> 硬件/嵌入开发 -> 片机/工控



modbus


[收藏此页] [打印本页]选择字色:背景色:字体:[][][]


modbus
发表于:2007-03-31 10:07:19 楼主
最近下了点程序学习如下,有些看不明白,咨询一下    
程序    
#include     "main.h "    
/******************************    
微控电子     www.mcuc.cn    
modbus     rtu     的c51程序        
单片机89s52    
通信波特率     9600     8位数据     1位停止位     偶校验     485通位接口    
单片机控制板地址     localaddr(变量)    
通信可设置数据的地址:    
字地址     0     -     255     (只取16位的低8位)    
位地址     0     -     255     (只取16位的低8位)    
*******************************/    
uint32     dwtickcount,dwinttick;     //时钟    
uint8     idata     sendbuf[16],recebuf[16];     //发送接收缓冲区    
uint8     idata     checkouterror;     //     ==2     偶校验错            
uint8     idata     recetimeout;         //接收超时    
uint8     idata     c10ms;             //10ms     计时    
bit         b1ms,bt1ms,b10ms,bt10ms,b100ms,bt100ms;     //定时标志位    
//     串行中断程序    
void     commintproc()     interrupt     4    
{    
  if(ti)    
  {    
      ti     =     0;        
      if(sendposi     <     sendcount)     //发送位置 <发送字节个数    
      {    
          sendposi++;    
          acc     =     sendbuf[sendposi];    
          tb8     =     p;     //加上校验位    
          sbuf     =     sendbuf[sendposi];    
     
                  while(ti==0);            
      ti=0;    
      }    
      else    
      {    
          b485send     =     0;                 //发送完后将485置于接收状态     b485send=p1^3;     //75lbc184     发送接收控制    
          rececount     =     0;             //接收到的字节个数     清接收地址偏移寄存器    
          checkouterror     =     0;//==2     偶校验错            
      }    
  }    
  else     if(ri)    
  {    
      ri     =     0;    
      recetimeout     =     10;                 //通讯超时值    
      recebuf[rececount]     =     sbuf;//接收到的字节个数    
      acc     =     recebuf[rececount];    
      if(p     !=     rb8)    
      checkouterror     =     2;     //偶校验出错    
      rececount++;                                         //接收地址偏移寄存器加1    
      rececount     &=     0x0f;                 //最多一次只能接收16个字节    
  }    
}             //     void     commintproc()    
//定时器0     1ms     中断    
void     timer0intproc()     interrupt     1    
{    
tl0     =     timer_low;        
th0     =     timer_hight;    
dwinttick++;    
bt1ms     =     1;    
c10ms++;    
              if(c10ms     > =     10)        
              {    
                              c10ms     =     0;                         //10ms计时器清零    
                              bt10ms     =     1;    
              }    
}             //     void     timer0intproc()    
 
 
//定时处理    
void     timeproc(void)    
{    
  static     uint8     c200ms;    
          bwatchdog     =     ~     bwatchdog;                 //看门狗取反    
  b1ms     =     0;    
  b10ms     =     0;    
  b100ms     =     0;    
     
  et0     =     0;//定时器0禁止    
  dwtickcount     =     dwinttick;    
  et0     =     1;//定时器1禁止    
  if(bt1ms)    
  {    
      bt1ms     =     0;    
      b1ms     =     1;    
                              if(recetimeout> 0)    
                              {    
                                              recetimeout--;    
                                              if(recetimeout==0     &&     rececount> 0)             //判断通讯接收是否超时//接收到的字节个数    
                                              {    
                                                              b485send     =     0;                             //将485置为接收状态    
                                                              rececount     =     0;                         //将接收地址偏移寄存器清零    
              checkouterror     =     0;    
                                              }    
                              }    
  }    
  if(bt100ms)    
  {    
      bt100ms     =     0;         b100ms     =     1;    
  }    
  if(bt10ms)                         //判断中断10ms标志位是否1    
              {    
                              bt10ms     =     0;                     //清中断10ms标志位    
                      b10ms     =     1;    
                              c200ms++;                                                                             //200ms计时器加1    
                              if(c200ms     > =     20)                                                 //判断是否计时到200ms    
                              {    
                                              c200ms     =     0;                                                     //清200ms计时器    
                                              brunled     =     ~brunled;                     //取反运行指示灯                                            
                              }    
              }    
}             //     void     timerproc(void)    
//初始化串口    
void     inituart(void)    
{    
}//void     inituart(void)    
//初始化中断    
void     initint(void)    
{                     inituart();    
                  ea     =     1;     //总中断允许        
}             //     void     initint(void)    
//初始化    
void     initprog(void)    
{        
  initint();    
  b485send     =     0;//75lbc184     发送接收控制    
}    
void     main(void)    
{    
  initprog();    
  while(1)    
  {    
      timeproc();//定时处理        
                              checkcomm0modbus();//检查uart0数据    
          }    
}    
就是如何定rtu桢之间> 3.5个字符             这里的超时判断看不大明白    
谁指点下             qq83310093
发表于:2007-03-31 14:32:351楼 得分:0
定rtu桢之间> 3.5个字符

发四个就完了,对于你说的超时判断,上面的代码我是看懂了,但是,没看到用的,所以
偶也没法猜,所以...
发表于:2007-03-31 15:20:122楼 得分:0
。。没话说
发表于:2007-03-31 15:31:153楼 得分:0
我有关于这方面的资料。qq:328997835
发表于:2007-04-02 16:03:114楼 得分:0
看懂了     加我qq啊       给我讲讲

有资料给我一份啊

好把分数发出去

83310093
发表于:2007-04-02 18:43:225楼 得分:0
定时来判断是否超时
发表于:2007-04-04 09:13:336楼 得分:0
2个问题不明白
1具体是个怎么样的顺序呢

是一帧的内部各数组中断一次调用定时判断一次         还是帧帧间调用定时判断

2比如       发过来       abcabcabc         假如abc为一帧     a   b   c为这帧的数组  
具体弄不明白的程序是如何区分a   b和   abc     abc的呢
就是帧内部是bc       帧帧间是ca
这都差不多
程序咋区分的呢

我写的程序少
还请详细指点一下
谢谢
发表于:2007-04-04 10:26:147楼 得分:0
1具体是个怎么样的顺序呢

是一帧的内部各数组中断一次调用定时判断一次         还是帧帧间调用定时判断

从接收到第一个被认为有效的信号开始调用定时,如果无效或是超时或是正确接收,都重新清掉 "定时器 "
发表于:2007-04-04 10:28:338楼 得分:0
2比如       发过来       abcabcabc         假如abc为一帧     a   b   c为这帧的数组  
具体弄不明白的程序是如何区分a   b和   abc     abc的呢
就是帧内部是bc       帧帧间是ca
这都差不多
程序咋区分的呢


这个就得按要求实现相应的状态机来确定:
rtu模式下,开始+数据量+数据+校验+结束
如果能走完这个状态,表示成功接收,如果有异常,则错误
发表于:2007-04-04 17:24:499楼 得分:0
有时间加我腾讯号吧

举个例子好理解点    

还是有点不怎么理解

谢谢您的热心
发表于:2007-04-04 17:33:1010楼 得分:0
main()
{
while(1)
  {
  watchdog();
  modbus();
    }
}
///////////////////////////////////////
void     modbus   (void)
{
          uint8     crc;
          if(rececount> 7)
            {
        if(recebuf[0]==   p0&0x3f&&recebuf[1]==0x03)
{
  crc=crc16(recebuf,6);
      if(crc   ==   recebuf[7]+(recebuf[6] < <8))
      {
/*1111111111111111111111111111111111*/
}
}
}
}
你说的状态机是指void     modbus   (void)函数吗????????




快速检索

最新资讯
热门点击