资讯详情

BH60绝对位置编码器测试

■ 简介


传感器型号"> 它是一个多圈绝对值旋转编码器。本文通过实验验证了其开发和使用。 旋转编码器的性能如下:

  • BH60:外径:60mm
  • Z1:0:10mm输出轴
  • M1212:多圈,12-4096圈;12:单圈分辨率4096
  • MB1:MODBUS RTU, 引线长1米。

▲ BH60的名牌和内部结构示意图

▲ BH60名牌及内部结构示意图

参照本文的实验结果,为方便未来高精度测量实验的构建:

01实验电路


1.制作传感器的实验接口

根据编码器铭牌信息,它可以使用MODBUS RTU协议。传感器的引线定义由 给出。

实验接口的焊接和生产按上述顺序完成。

▲ 定义传感器的功能线

2.静态加电试验

  • ,工作电流约30mA。
  • 见下表格:
PIN 电源 电源- A B- 置零 编程
1 5.056200 0.019221 3.177800 0.065227 0.024253 0.024475

02控制板STM8H电路


使用STC8H1K28作为实验控制MCU。设计基于面包板连接的相应实验电路。

1.实验电路板1

▲ 实验电路原理图

▲ 实验电路板

2.单片机软件2

: 工作时钟:35MHz,调试串口460800bps。

在35MHz时钟频率下, UART波特率设置输出19200。 T 2 = 0 x F E 38 T_2 = 0xFE38 T2=0xFE38。

▲ 输出0x55波形

▲ 发送波形和MAX487的DIR控制波形

接入STC8H1K28外部端口。

▲ MAX487模块连入单片机接口引线

使用另外一块MAX487对输出总线进行接收。验证前面发送数据的完整性。

|

▲ 总线波形以及487接收波形|上:总线A线信号;下:487接收信号

根据前面传感器接口定义,将传感器接入MAX487模块的总线电路。

 

03软件协议


根据传感器型号,BH60使用 协议来传递信息。相关的通信协议可以在 协议中给出。

在MODBUS的ADU中,最后两个字节为 ,它的实现方式见下面的C语言代码。

// Compute the MODBUS RTU CRC
UInt16 ModRTU_CRC(byte[] buf, int len)
{ 
        
  UInt16 crc = 0xFFFF;
  
  for (int pos = 0; pos < len; pos++) { 
        
    crc ^= (UInt16)buf[pos];          // XOR byte into least sig. byte of crc
  
    for (int i = 8; i != 0; i--) { 
            // Loop over each bit
      if ((crc & 0x0001) != 0) { 
              // If the LSB is set
        crc >>= 1;                    // Shift right and XOR 0xA001
        crc ^= 0xA001;
      }
      else                            // Else LSB is not set
        crc >>= 1;                    // Just shift right
    }
  }
  // Note, this number has low and high bytes swapped, so use it accordingly (or swap bytes)
  return crc;  
}

★ 注意:CRC传输的时候是 低字节在前,高字节在后

▲ BH60读出数据波形

//------------------------------------------------------------------------------
unsigned int ModbusCRC(unsigned char * pByte, int nLength) { 
        
    unsigned int nCRC;
    unsigned int i;
    unsigned char ucByte, j;
    
    nCRC = 0xffff;
    
    for(i = 0; i < nLength; i ++) { 
        
        ucByte = *(pByte + i);
        nCRC ^= (unsigned int)ucByte;
        
        for(j = 0; j < 8; j ++) { 
        
            if((nCRC & 0x1) != 0) { 
        
                nCRC >>= 1;
                nCRC ^= 0xA001;
            } else nCRC >>= 1;
        }        
    }
            
    return nCRC;
}

//------------------------------------------------------------------------------
void BH60AppendCRC(unsigned char ucLength) { 
        
    unsigned int nCRC;
    nCRC = ModbusCRC(g_ucBH60Buffer, ucLength);
    g_ucBH60Buffer[ucLength + 1] = (unsigned char)(nCRC >> 8);
    g_ucBH60Buffer[ucLength] = (unsigned char)nCRC;
}
long BH60Buffer2Number(void) { 
        
    unsigned long lnNumber;
    
    if(g_ucBH60Buffer[6] & 0x80)
        lnNumber = 0xff;
    else lnNumber = 0;
        
    lnNumber = (lnNumber << 8) + g_ucBH60Buffer[6];
    lnNumber = (lnNumber << 8) + g_ucBH60Buffer[3];
    lnNumber = (lnNumber << 8) + g_ucBH60Buffer[4];
    return (long)lnNumber;
}
else IFARG0("readbh60") { 
        
    sscanf(SDA(1), "%d", &nNumber);
    for(i = 0; i < nNumber; i ++) { 
        
        printf("%ld ", BH60ReadNumber());
        WaitTime(50);
    }
    
    printf("\r\n");
} else IFARG0("readbh60b") { 
        
    lnNumber = BH60ReadNumber();
    SendChar((unsigned char)(lnNumber));
    lnNumber >>= 8;
    SendChar((unsigned char)(lnNumber));
    lnNumber >>= 8;
    SendChar((unsigned char)(lnNumber));
}

 

04测试传感器分辨率


手动旋转传感器10圈,然后读取输出的角度,大约41074。平均下来每圈为4107.4。这个参数对应每圈4096数据。

▲ 手动旋转传感器

▲ 旋转10圈读取的数据

 

※ 结论


通过STC8H1K28通过485总线的MODBUS读取传感器的数据,测试了旋转传感器的基本参数以及通信协议。

/* **============================================================================== ** BH60.C: -- by Dr. ZhuoQing, 2020-07-13 ** **============================================================================== */
#include <stdio.h>
//------------------------------------------------------------------------------
#define BH60_GLOBALS 1 // Define the global variables
#include "BH60.H"
#include "MAIN.H"
#include "STC8H.H"
#include "C51BASIC.H"

//------------------------------------------------------------------------------
void BH60Init(unsigned char ucAddress) { 
        
    g_ucBH60Address = ucAddress;
}

//------------------------------------------------------------------------------
unsigned int ModbusCRC(unsigned char * pByte, int nLength) { 
        
    unsigned int nCRC;
    unsigned int i;
    unsigned char ucByte, j;
    
    nCRC = 0xffff;
    
    for(i = 0; i < nLength; i ++) { 
        
        ucByte = *(pByte + i);
        nCRC ^= (unsigned int)ucByte;
        
        for(j = 0; j < 8; j ++) { 
        
            if((nCRC & 0x1) != 0) { 
        
                nCRC >>= 1;
                nCRC ^= 0xA001;
            } else nCRC >>= 1;
        }        
    }
            
    return nCRC;
}

//------------------------------------------------------------------------------
void BH60AppendCRC(unsigned char ucLength) { 
        
    unsigned int nCRC;
    nCRC = ModbusCRC(g_ucBH60Buffer, ucLength);
    g_ucBH60Buffer[ucLength + 1] = (unsigned char)(nCRC >> 8);
    g_ucBH60Buffer[ucLength] = (unsigned char)nCRC;
}

//------------------------------------------------------------------------------
void BH60SendBuffer(unsigned char ucLength) { 
        
    unsigned char i;

    BH60AppendCRC(ucLength);
    
    ON(DIR_PIN);
    
    for(i = 0; i < ucLength + 2; i ++) { 
        
        UART2SendChar(g_ucBH60Buffer[i]);
    }
     
    OFF(DIR_PIN);
    
    UART2_CLEAR;

}

//------------------------------------------------------------------------------
void BH60ReadData2Buffer(void) { 
        
    unsigned char i, c;
    
    g_ucBH60Buffer[0] = g_ucBH60Address;
    g_ucBH60Buffer[1] = 0x3;
    g_ucBH60Buffer[2] = 0x0;
    g_ucBH60Buffer[3] = 0x3;
    g_ucBH60Buffer[4] = 0x0;
    g_ucBH60Buffer[5] = 0x2;
    BH60SendBuffer(6);
    
    for(i = 0; i < 9; i ++) { 
        
        if(UART2ReceChar(&c)) return;
        g_ucBH60Buffer[i] = c;
    }

}

void BH60ReadConfig2Buffer(void) { 
        
    unsigned char i, c;
    
    g_ucBH60Buffer[0] = g_ucBH60Address;
    g_ucBH60Buffer[1] = 0x3;
    g_ucBH60Buffer[2] = 0x0;
    g_ucBH60Buffer[3] = 0x0;
    g_ucBH60Buffer[4] = 0x0;
    g_ucBH60Buffer[5] = 0x3;
    BH60SendBuffer(6);
    
    for(i = 0; i < 11; i ++) { 
        
        if(UART2ReceChar(&c)) return;
        g_ucBH60Buffer[i] = c;
    }
}

//------------------------------------------------------------------------------
long BH60Buffer2Number(void) { 
        
    unsigned long lnNumber;
    
    if(g_ucBH60Buffer[6] & 0x80)
        lnNumber = 0xff;
    else lnNumber = 0;
        
    lnNumber = (lnNumber << 8) + g_ucBH60Buffer[6];
    lnNumber = (lnNumber << 8) + g_ucBH60Buffer[3];
    lnNumber = (lnNumber << 8) + g_ucBH60Buffer[4];
    return (long)lnNumber;
}

//------------------------------------------------------------------------------
long BH60ReadNumber(void) { 
        
    BH60ReadData2Buffer();
    return BH60Buffer2Number();
}

//==============================================================================
// END OF THE FILE : BH60.C
//------------------------------------------------------------------------------

/* **============================================================================== ** BH60.H: -- by Dr. ZhuoQing, 2020-07-13 ** ** Description: ** **============================================================================== */
#ifndef __BH60__
#define __BH60__
//------------------------------------------------------------------------------
#ifdef BH60_GLOBALS
   #define BH60_EXT
#else
   #define BH60_EXT extern
#endif // BH60_GLOBALS

//------------------------------------------------------------------------------
#define BH60_ADDRESS 1

//==============================================================================
void BH60Init(unsigned char ucAddress);

//------------------------------------------------------------------------------
#define BH60_BUFFER 16

BH60_EXT unsigned char xdata g_ucBH60Buffer[BH60_BUFFER];
BH60_EXT unsigned char xdata g_ucBH60Address;

unsigned int ModbusCRC(unsigned char * pByte, int nLength);
void BH60AppendCRC(unsigned char ucLength);

//------------------------------------------------------------------------------
void BH60SendCharBuffer(unsigned char ucLength);

void BH60ReadData2Buffer(void);
void BH60ReadConfig2Buffer(void);

long BH60Buffer2Number(void);

//------------------------------------------------------------------------------
long BH60ReadNumber(void);

//==============================================================================
// END OF THE FILE : BH60.H
//------------------------------------------------------------------------------
#endif // __BH60__


  1. :AD\Test\2020\Tools\BUS487STC8H.SchDoc ↩︎

  2. :C51\STC\Test\2020\Tools\BUS487STC8H1K28\BUS487STC8H1K28.uvproj ↩︎

标签: 绝对值多圈角度传感器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台