串口数据解析问题

freedomfly911 2009-03-23 05:02:49
我用api函数开发了一个串口调试程序,现在需要接收并以double形式显示角度,请问如何做,谢谢大家。
输入数据帧格式如下表。
序号 名称 占用字节数目 备注
1 帧头 2 取值:0x5555
2 长度码 1 取值:“方位码”占用的字节长度=2
3 方位码 2 取值范围:0~720;单位:0.5度;
4 CRC码 2 将“长度码”和“方位码”的内容作CRC-16效验
5 帧尾 2 取值:0xAAAA
注:
0x 55 55 02 00 B4 D0 77 AA AA // 90 度
0x 55 55 02 01 0E 50 54 AA AA // 135 度
0x 55 55 02 01 69 11 BE AA AA // 180.5 度
0x 55 55 02 01 6E 50 7C AA AA // 183 度
0x 55 55 02 01 E0 D0 18 AA AA // 240 度
0x 55 55 02 01 FB 90 13 AA AA // 253.5 度


我的代码是
BOOL CCommtestDlg::ProcessCOMMNotification (UINT wParam,long lParam)
{
..............
CString StrTemp;
BYTE abIn[MAXBLOCK];
int len;
len=ReadBlock(abIn,MAXBLOCK); //缓冲区字符长度
for(int i=0;i <len;i++)
{
BYTE bt=abIn[i];
if(m_ctrlHexDisplay.GetCheck())
StrTemp.Format("%02x ",bt);
else
StrTemp.Format("%c",bt);
???????
...全文
352 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
morris88 2009-04-09
  • 打赏
  • 举报
回复

#pragma pack(1)
typedef struct {
unsigned short fHeader;
unsigned char fLen;
unsigned short fAngel;
unsigned short fCrc;
unsigned short fTailer;
} angelFrame;
#pragma pack()

bool angelConvert(unsigned char *buf, unsigned long *angel)
{
#define SWAP16(x) (unsigned short)(((x) < < 8) | ((x) >> 8))
unsigned char *p = buf;

if (!p) {
return false;
}

while (*p == '\x55')
++p;

/* check header */

angelFrame *f = (angelFrame *)(p - 2);

/* check length */
/* check crc */

*angel = SWAP16(f->fAngel);

return true;
}

void __fastcall TForm1::Button1Click(TObject *Sender)
{
unsigned char *buf[] = {
"\x55\x55\x02\x00\xB4\xD0\x77\xAA\xAA",
"\x55\x55\x02\x01\x0E\x50\x54\xAA\xAA",
"\x55\x55\x02\x01\x69\x11\xBE\xAA\xAA",
"\x55\x55\x02\x01\x6E\x50\x7C\xAA\xAA",
"\x55\x55\x02\x01\xE0\xD0\x18\xAA\xAA",
"\x55\x55\x02\x01\xFB\x90\x13\xAA\xAA"
};
AnsiString asAngel;
unsigned long iAngel;
float fAngel;

for (int i = 0; i < 6; i++) {
angelConvert(buf[i], &iAngel);
fAngel = 0.5 * iAngel;
asAngel.printf("%f", fAngel);
ShowMessage(asAngel);
}
}
freedomfly911 2009-04-09
  • 打赏
  • 举报
回复
真实数据是有其他设备发过来的,如果我想模拟输入来测试,请问我该怎么输入?
串口连起,在另个串口调试工具中直接输入“55 55 02 01 FB 90 13 AA AA ”?
morris88 2009-03-27
  • 打赏
  • 举报
回复
bool angelConvert(unsigned char *buf, unsigned long *angel)
{
#define SWAP16(x) (unsigned short)(((x) << 8) | ((x) >> 8))
unsigned char *p = buf;

if (!p) {
return false;
}

while (*p == '\x55')
++p;

/* check header */

angelFrame *f = (angelFrame *)(p - 2);

/* check length */
/* check crc */

*angel = SWAP16(f->fAngel);

return true;
}
morris88 2009-03-27
  • 打赏
  • 举报
回复
#pragma pack(1)
typedef struct {
unsigned short fHeader;
unsigned char fLen;
unsigned short fAngel;
unsigned short fCrc;
unsigned short fTailer;
} angelFrame;
#pragma pack()

bool angelConvert(unsigned char *buf, unsigned long *angel)
{
#define SWAP16(x) (unsigned short)(((x) << 8) | ((x) >> 8))

angelFrame *f = (angelFrame *)buf;
*angel = SWAP16(f->fAngel);

return true;
}

void __fastcall TForm1::Button1Click(TObject *Sender)
{
unsigned char *buf[] = {
"\x55\x55\x02\x00\xB4\xD0\x77\xAA\xAA",
"\x55\x55\x02\x01\x0E\x50\x54\xAA\xAA",
"\x55\x55\x02\x01\x69\x11\xBE\xAA\xAA",
"\x55\x55\x02\x01\x6E\x50\x7C\xAA\xAA",
"\x55\x55\x02\x01\xE0\xD0\x18\xAA\xAA",
"\x55\x55\x02\x01\xFB\x90\x13\xAA\xAA"
};
AnsiString asAngel;
unsigned long iAngel;
float fAngel;

for (int i = 0; i < 6; i++) {
angelConvert(buf[i], &iAngel);
fAngel = 0.5 * iAngel;
asAngel.printf("%f", fAngel);
ShowMessage(asAngel);
}
}
freedomfly911 2009-03-27
  • 打赏
  • 举报
回复

if( 0xAA == buf[ 7 ] && 0xAA == buf[ 8 ] )
{
flag = 2;
//校检
}

改成这样后还是无法得到角度,请大家帮帮忙,小弟不胜感激。
freedomfly911 2009-03-25
  • 打赏
  • 举报
回复
请帮忙看一下,是哪的问题,结果不对。谢谢!
for(int i=0;i<len;i++)
{
BYTE bt=abIn[i];
if(m_ctrlHexDisplay.GetCheck())
StrTemp.Format("%02x ",bt);
else
StrTemp.Format("%c",bt);
m_strRXData+=StrTemp;

char ch = (char)bt;
m_strPortRXData += (char)ch;

BYTE buf[9];
memcpy(buf,abIn+i,9);


if( 0x55 == buf[ 0 ] && 0x55 == buf[ 1 ] )
{
flag = 1;
}
if( 0xAA == buf[ 8 ] && 0xAA == buf[ 9 ] )
{
flag = 2;
//校检
}
if(flag = 2)
{
float Angel;
Angel = (buf[3] * 0x100 + buf[4])/2;
m_meter.UpdateNeedle(Angel);
}
m_EditRXData.SetWindowText(m_strRXData);
}
我不懂电脑 2009-03-25
  • 打赏
  • 举报
回复
用什么函数读入buf?
void *memcpy(
void* dest,
const void* src,
size_t count
);
freedomfly911 2009-03-25
  • 打赏
  • 举报
回复
我对c++不是很熟悉,能否给出详细代码

用什么函数读入buf?
for(int i=0;i <len;i++)
{
BYTE bt=abIn[i];
char ch = (char)bt;
BYTE buf[9];

??????????????????????

float Angel;
Angel = (buf[3] * 0x100 + buf[4]) / 2.0;
CppFile 2009-03-24
  • 打赏
  • 举报
回复
首先,每次当串口读取到数据的时候,都保存到一个buffer中,如果将接受到的长度小于帧长度,则存入buffer后继续等待数据,如果buffer中的长度大于等于帧长度,则开始分析buffer中的内容,首先校验开始码,如果第一个不是开始吗,则后移一位检查,直到找到开始吗为止,然后判断buffer中的长度时候够一帧的数据,如果不够,则退出分析,继续等待串口数据,如果够一帧的长度,则判断结束码是否正确,如果正确,则判断校验,如果也正确,则可以读数据,分析了,这个应该和你的业务有关系,应该没问题的
march_zhou 2009-03-24
  • 打赏
  • 举报
回复
接收到的数据进一队列,然后扫描队列,检测到帧头和帧尾后取出一帧数据,然后CRC校验,校验通过后进行数据解析。
怎样显示浮点数不用我教了吧
xjq2003 2009-03-23
  • 打赏
  • 举报
回复
一个字符一个字符接受后保存到BUF中
从BUF[0]开始分析就是了
如果BUF[0],BUF[1] 是0x55

freedomfly911 2009-03-23
  • 打赏
  • 举报
回复
谢谢楼上,我用的是api开发的软件,没用到MScomm控件
能不能给出代码示范,不胜感激!!!!
我不懂电脑 2009-03-23
  • 打赏
  • 举报
回复
用MSComm二进制方式接收数据保存到buffer然后用memcpy拷贝到缓冲中,强制转换为double

604

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder VCL组件使用和开发
社区管理员
  • VCL组件使用和开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧