在本次学习中可以知道:
串口文件的定义以及调用;
串口接收后对数据的判断与保存。
继前文可知接收串口的写法,然后就可以定义相关变量并对接收的数据作处理了。
在此,可以利用while语句不断接收函数,并且判断接收过来的数据内容,然后保存我想要的一部分数据到txt文件中。
代码
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <tchar.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include <math.h>
#define head_str0 "[INFO] frame:"
char head_str[14] = head_str0;
HANDLE hCom1;//串口句柄
typedef struct//这里是我串口要接收的数据的变量
{
unsigned char id;
bool used;
float range;
float velocity;
float azimuth;
float elevation;
float x;
float y;
float z;
float SNR;
float timestamp;
} Target_t;
Target_t TargetList[100];
int main(void)
{
unsigned int wCount;
unsigned int rCount;
hCom1 = CreateFile(_T("COM4"),//COM4口
GENERIC_READ | GENERIC_WRITE,//允许读和写
0,//独占方式
NULL,
OPEN_EXISTING,//打开而不是创建
0,//同步方式
NULL);
FILE* fp1;
if (hCom1 == (HANDLE)-1)
{
printf("打开COM失败!\n");
return FALSE;
}
else
{
printf("COM打开成功!\n");
}
DCB dcb1;//一个串口结构体
GetCommState(hCom1, &dcb1);
dcb1.BaudRate = 921600;//波特率
dcb1.ByteSize = 8;//每个字节有8位
dcb1.Parity = NOPARITY;//无奇偶校验位
dcb1.StopBits = TWOSTOPBITS;//两个停止位
//dcb1.fParity = FALSE;
//dcb1.fNull = FALSE;
SetCommState(hCom1, &dcb1);
COMMTIMEOUTS TimeOuts;
//设定读超时,最长的等待时间
TimeOuts.ReadIntervalTimeout = 2000;//1000
TimeOuts.ReadTotalTimeoutMultiplier = 1000;//500
TimeOuts.ReadTotalTimeoutConstant = 10000;//5000
//设定写超时
TimeOuts.WriteTotalTimeoutMultiplier = 1000;//500
TimeOuts.WriteTotalTimeoutConstant = 4000;//2000
SetCommTimeouts(hCom1, &TimeOuts);//设置超时
SetupComm(hCom1, 20480, 20480);//输入缓冲区和输出缓冲区的大小都是1024
PurgeComm(hCom1, PURGE_TXCLEAR | PURGE_RXCLEAR);//清空缓冲区
wCount = 1;
uint8_t rx=0;
uint8_t flag = 0;
uint8_t frame_start_flag = 0;
uint8_t frame_end_flag = 0;
unsigned char str[1024];
memset(str, 0, 100);
int i = 0;
int j = 0;
int k = 0;
uint32_t frame;
int k_buf[100];
uint8_t numObjOut = 0;
char txt_buf[20];
while (1)//不断读取数据
{
if (!ReadFile(hCom1, &rx, wCount, &rCount, NULL))//类似于读文件,句柄,读取后存放的地址,要读取的字节数,实际读取的字节数
{
printf("读串口失败!");
return FALSE;
}
if (rCount==1 && flag > 0)
{
str[i] = rx;
i++;
}
//printf("flag:%d\n", flag);
switch (flag)
{
case 0:
{
if (rCount == 1)
{
if (rx == '[')
{
flag++;
str[i] = rx;
i++;
}
}
}break;
case 1:
{
if (i >= 13)
{
if (memcmp(str, head_str, 13)==0)
{
flag++;
}
else
{
flag = 0;
i = 0;
memset(str, 0, 1024);
}
}
}break;
case 2:
{
if (rx == '[')
{
sscanf((char*)&str[0], "[INFO] frame:%u", &frame);
printf("frame: %d\n", frame);
flag++;
}
}break;
case 3:
{
sprintf(txt_buf,"./dir/%u.txt", frame);
fp1 = fopen(txt_buf, "a+");//新建一个文本,将数据保存在其中
for (j = 0; j < i; j++)
{
if (str[j] == 'd')
{
sscanf((char *)& str[j + 1], ":%u", &k_buf[k]);
//j = j + 4;
//if (str[j] == 'x')
//{
// sscanf((char*)&str[j + 1], ":%f", &TargetList[k_buf[k]].x);
// printf("text: % 0.2f", TargetList[k_buf[k]].x);
//}
//j = j - 4;
sscanf((char*)&str[j + 1], ":%u x:%f y:%f z:%f v:%f snr:%f time:%f",
&TargetList[k_buf[k]].id, &TargetList[k_buf[k]].x,
&TargetList[k_buf[k]].y, &TargetList[k_buf[k]].z,
&TargetList[k_buf[k]].velocity, &TargetList[k_buf[k]].SNR,
&TargetList[k_buf[k]].timestamp);
printf( "id:%u x:%0.2f y:%0.2f z:%0.2f v:%0.2f snr:%0.2f time:%0.2f\n", TargetList[k_buf[k]].id, TargetList[k_buf[k]].x,
TargetList[k_buf[k]].y, TargetList[k_buf[k]].z,
TargetList[k_buf[k]].velocity, TargetList[k_buf[k]].SNR,
TargetList[k_buf[k]].timestamp);
//TargetList[k_buf[k]].range = sqrt(pow(TargetList[k_buf[k]].x, 2) + pow(TargetList[k_buf[k]].y, 2) + pow(TargetList[k_buf[k]].z, 2));
TargetList[k_buf[k]].range = sqrt((TargetList[k_buf[k]].x * TargetList[k_buf[k]].x) +
(TargetList[k_buf[k]].y * TargetList[k_buf[k]].y) +
(TargetList[k_buf[k]].z * TargetList[k_buf[k]].z));
TargetList[k_buf[k]].azimuth = atan2(TargetList[k_buf[k]].x, TargetList[k_buf[k]].y);
TargetList[k_buf[k]].elevation = asin(TargetList[k_buf[k]].z/TargetList[k_buf[k]].range);
fprintf(fp1, "%f %f %f %f %f %f\n", TargetList[k_buf[k]].range,TargetList[k_buf[k]].velocity,
TargetList[k_buf[k]].azimuth, TargetList[k_buf[k]].elevation,
TargetList[k_buf[k]].SNR,TargetList[k_buf[k]].timestamp);
k++;
}
}
printf("k:%d\n",k);
flag = 0;
i = 0;
memset(str, 0, 1024);
k = 0;
fclose(fp1);
}break;
default:
{
}break;
}
}
//fprintf(fp1, "%02X ", str[j]);
CloseHandle(hCom1);
}
参考文档
如何读取一个串口
createFileA 函数 (fileapi.h)
sscanf 函数的返回值是一个整数,表示成功解析并匹配的参数个数。
仰角和方位角(Elevation and Azimuth)