本文测试模块是海芯物联HX-M04G超高频四通道模块
。
一、RFID 模块介绍
HX-M04GT 四通道套件
HX-M04G 四通道模块
HX-M04G是一款高性能的嵌入式UHF超高频电子标签读写模块
,完全自主知识产权设计,结合专有的高效碰撞处理算法,在保持高识读率的同时,实现对电子标签的快速读写处理,用户只需要在模块的基础上作电源处理即可,可以很方便的通过API函数库控制模块工作,适合各种应用场景用户开发可广泛应用于物流、个人身份识别、会议签到系统、门禁系统、防伪系统及生产过程控制等多种无线射频识别(RFID)系统。
- 全面支持
EPC C1G2、ISO18000-6B/C
、GB/T29768-2013(可选配)等主流UHF RFID 空中接口协议
- RF 输出功率(端口):
33dBm±1dB(MAX)
通讯接口 : TTL Uart接口
通信速率 : 串口速率9600~115200bps
工作电压 :5V-17V
待机状态电流 :<50mA (EN 脚高电平)
睡眠状态电流 :<100uA (EN 脚低电平)
工作电流 : 1.2A +/-10%
通用输入输出接口
– 插座 15Pin SD-532611571-024 1.25mm Molex SMT
序号 | 符号 | 描述 |
---|---|---|
1 | GND | 接地 |
2 | GND | 接地 |
3 | 5V-17V DC | 5V-17V DC电源 |
4 | 5V-17V DC | 5V-17V DC电源 |
5 | GPIO 3 | GPIO 输入\输出(可定义) |
6 | GPIO 4 | GPIO 输入\输出(可定义) |
7 | GPIO 1 | GPIO 输入\输出(可定义) |
8 | 蜂鸣器 | 蜂鸣器 |
9 | UART_RXD | TTL 电平 |
10 | UART_TXD | TTL 电平 |
11 | USB_DM | USB 接口 |
12 | USB_DP | USB 接口 |
13 | GPIO 2 | GPIO 输入\输出(可定义) |
14 | EN | 外部使能,高电平有效 |
15 | GPIO 5 | GPIO 输入\输出(可定义) |
二、通信协议介绍
帧结构
帧 头
: 以十六进制“0x5A”作为一帧数据的起始标识。
协议控制字
:用于标识当前消息类型。具体位定义如下:
串行设备地址
:用于标识目标读写器的RS485地址,值范围为0x00~0xFF,仅当协议控制字中RS485标志位置为1时,消息中才包含此字段,否则消息中应不包含此域。
数据长度
:指示数据内容字节总长度,目前规定读写器支持的最大数据内容长度为1024 字节。
数据参数
:上位机指令及参数信息或读写器上传信息内容。
校验码
:除帧头外的数据的CRC16校验和,校验算法采用XMODEM,校验多项式
为X16 + X12 + X5 + 1,初始值置为0。
*注意:CRC16计算不包含帧头
unsigned short CRC16_XMODEM (unsigned char *ptr, int len)
{
unsigned int i;
unsigned short crc = 0x0000;
while(len--)
{
crc ^= (unsigned short)(*ptr++) << 8;
for (i = 0; i < 8; ++i)
{
if (crc & 0x8000)
crc = (crc << 1) ^ 0x1021;
else
crc <<= 1;
}
}
return crc;
}
在数据传输时,字节序采用高位优先的大端格式(big-endian)。
数据参数 介绍
帧格式中的数据内容根据内容可区分成两类
:一种为指令必须包含的参数内容,在下面的描述表格中表示为(M),此类参数不带参数 ID;另一种为可选的参数内容,此类参数带有参数编号(PID)。
参数存在变长数据时,数据格式为:参数长度+参数内容,其中参数长度域为 2 字节数据,长度单位为字节;对于固定长度的参数则无参数长度这个域。
三、通信协议测试
测试代码,生成指令:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
unsigned char test_1[]={0x5A,0x00,0x01,0x02,0x00,0x00,0x00};//查询读写器RFID能力 5A000102000000
unsigned char test_2[]={0x5A,0x00,0x01,0x02,0x10,0x00,0x08,0x00,0x00,0x00,0x01,0x01,0x02,0x00,0x06};//读EPC标签-连续读取-使能天线1 5A0001021000080000000101020006
unsigned char test_3[]={0x5A,0x00,0x01,0x02,0xFF,0x00,0x00};//停止指令 5A000102FF0000
unsigned char test_4[]={0x5A,0x00,0x01,0x02,0x10,0x00,0x08,0x00,0x00,0x00,0x01,0x00,0x02,0x00,0x06};//读EPC标签-连续读取-使能天线1 5A0001021000080000000100020006
unsigned char test_5[]={0x5A,0x00,0x01,0x02,0x10,0x00,0x08,0x00,0x00,0x00,0x0F,0x00,0x02,0x00,0x06};//读EPC标签-单次读取-使能天线1.2.3.4 5A0001021000080000000f00020006
unsigned char test_6[]={0x5A,0x00,0x01,0x02,0x10,0x00,0x08,0x00,0x00,0x00,0x02,0x00,0x02,0x00,0x06};//读EPC标签-单次读取-使能天线2 5A0001021000080000000200020006
unsigned char test_7[]={0x5A,0x00,0x01,0x02,0x10,0x00,0x08,0x00,0x00,0x00,0x04,0x00,0x02,0x00,0x06};//读EPC标签-单次读取-使能天线3 5A0001021000080000000200020006
unsigned char test_8[]={0x5A,0x00,0x01,0x02,0x01,0x00,0x08,0x01,0x05,0x02,0x05,0x03,0x0a,0x04,0x05};//配置读写器功率 5A000102010008011E021E031E041E
unsigned char test_9[]={0x5A,0x00,0x01,0x02,0x10,0x00,0x08,0x00,0x00,0x00,0x0F,0x01,0x02,0x00,0x06};//读EPC标签-连续读取-使能天线1.2.3.4 5A0001021000080000000101020006
unsigned short crc16=0;
//注意:CRC16计算不包含帧头
unsigned short CRC16_XMODEM (unsigned char *ptr, int len)
{
unsigned int i;
unsigned short crc = 0x0000;
while(len--)
{
crc ^= (unsigned short)(*ptr++) << 8;
for (i = 0; i < 8; ++i)
{
if (crc & 0x8000)
crc = (crc << 1) ^ 0x1021;
else
crc <<= 1;
}
}
return crc;
}
int main()
{
int len=0;
unsigned char *p;
//*****************************
len=sizeof(test_1)+2;
p=(unsigned char*)malloc(len);
if(p == NULL)
{
printf("malloc err 1 \n");
}
crc16 = CRC16_XMODEM(&test_1[1],sizeof(test_1)-1);
memcpy(p,test_1,sizeof(test_1));
p[len-2]=(unsigned char)(crc16>>8);
p[len-1]=(unsigned char)crc16;
for(int i=0;i<len;i++)
{
printf("%02x ",p[i]);
}
printf("\n");
free(p);
//*****************************
//*****************************
len=sizeof(test_2)+2;
p=(unsigned char*)malloc(len);
if(p == NULL)
{
printf("malloc err 2 \n");
}
crc16 = CRC16_XMODEM(&test_2[1],sizeof(test_2)-1);
memcpy(p,test_2,sizeof(test_2));
p[len-2]=(unsigned char)(crc16>>8);
p[len-1]=(unsigned char)crc16;
for(int i=0;i<len;i++)
{
printf("%02x ",p[i]);
}
printf("\n");
free(p);
//*****************************
return 0;
}
串口测试结果:
/*
//停止指令
[2025-07-31 04:12:21.720]TX:5A000102FF0000885A
[2025-07-31 04:12:21.739]RX:5A 00 01 02 FF 00 01 00 79 B1
//查询读写器功率
[2025-07-31 04:12:30.409]TX:5A0001020200002959
[2025-07-31 04:12:30.418]RX:5A 00 01 02 02 00 08 01 05 02 05 03 0A 04 05 9C DA
//配置读写器功率
//5A000102010008011E021E031E041E4C28
*/