我使用Tiva C系列TM4C123GH6PM和Code Composer Studio从另一个相同类型的微控制器获取数据。好吧,我以字节为单位获取数据。项目的目标是组装每个8字节并将它们转换为double然后将这些double发送到计算机。我必须使用USART将数据发送到计算机。
当我使用USART时,我有两种方法:
问题在于有两个只接受字符的方法。因此,使用这些方法进行double是不可能的,因为double是8个字节而字符是1个字节。我正在尝试将双打发送到我的电脑。有什么想法吗?
第二个问题是从计算机侧编写程序以从微控制器获取数据(字节)。
我应该用c编写这个程序(另一种方法是使用matlab,因为我会使用这些数据进行模拟)? 如何在c 中访问com-Port(如果可能,则在matlab中访问)?
答案 0 :(得分:1)
您需要找到一种方法来分解大量数据,并将其发送给客户端,然后客户端需要一种方法来重新组装数据,并且还知道何时发送此类数据。
一种非常简单的方法是将double的所有数字转换为字符。效率低下,但它可以轻松完成工作,如下所示。这是首选的原因是因为它可以让您轻松创建自己的“指令集”。例如,您可以将字符'!'
保留为“!
后面的字母表示特殊指令”,因此当客户端看到序列“!d
”时,它知道以下32个字节数据表示double
,并重新组装它。
如果您只是发送原始字节,当您想要创建转义码或操作码以向客户发出特殊情况时,它会变得更加复杂。
代码清单
#include <stdio.h>
#define BUF_LEN (32)
typedef union {
float f;
struct {
unsigned int mantissa : 23;
unsigned int exponent : 8;
unsigned int sign : 1;
} parts;
} double_cast;
int main(void)
{
double_cast d1;
d1.f = 0.15625;
printf("sign = %x\n",d1.parts.sign);
printf("exponent = %x\n",d1.parts.exponent);
printf("mantissa = %x\n",d1.parts.mantissa);
char buf[BUF_LEN+1] = { 0 };
snprintf(buf, BUF_LEN+1, "%01X%08X%023X", d1.parts.sign, d1.parts.exponent,
d1.parts.mantissa);
// Send over UART
printf("Double as string: [%s]\n", buf);
//UART_printf("!d%s", buf);
return 0;
}
示例输出
sign = 0
exponent = 7c
mantissa = 200000
Double as string: [00000007C0000000000000000020000]
Credit for the code to break a double into a string goes to u/eran.
答案 1 :(得分:0)
另一种适合我的解决方案(类似于Krystian的解决方案)。我定义了一个函数,它具有double和Bytes数组作为参数。必须将double转换为Bytes数组。这就是为什么我定义了一个字节数组,其大小为8字节。这里有一些代码:
unsigned char bytesArray[sizeof(double)];
unsigned char * doubleToBytes(double num,unsigned char bytes []){
return memcpy(bytes,&num,sizeof(double));
}
在数组中获取字节后,您可以使用以下循环发送数据:
for(i=0;i<sizeof(double);i++){
UARTCharPut(UART1_BASE,(unsigned char)*(bytesArray+i));
}
答案 2 :(得分:-1)
一般来说,您面临的是序列化问题,最好的方法是使用专门的库来实现此目的。
以一种肮脏但简单的方式,你可以像这样解决它。 您必须将另一侧的数据正确组合回来才能翻倍。
typedef union _MyDouble {
double d;
unsigned char bytes[sizeof(double)];
} MyDouble;
MyDouble my_double;
my_double.d = 1.234;
for(i=0; i < sizeof(double); i++) {
UARTCharPut(UART0_BASE, (char)my_double.bytes[i]).
}
另一件事是,如果您使用的是UART,则应将此并集封装到某个帧中,例如:为了在另一边成功地重新组装它。
_____________ ________ __________ ___________ ________
| | | | | |
| FRAME_BEGIN | LENGTH | MyDouble | FRAME_END | CRC-8? |
|_____________|________|__________|___________|________|
接下来的事情是你应该在这个结构上强制执行字节对齐,这是由编译器指令完成的。它确保您的struct没有填充字节等,并分配最小需求大小。这在嵌入式应用程序用例中非常流行,其中一些二进制对象将在串行接口上传输 - 这正是您的情况。这样一个简单的解决方案可能适用于特定的hw + sw配置,但从专业角度来看,它确实不是便携式和良好的解决方案。