使用tiva系列c将数据从微控制器发送到计算机

时间:2015-08-15 21:24:35

标签: c microcontroller

我使用Tiva C系列TM4C123GH6PM和Code Composer Studio从另一个相同类型的微控制器获取数据。好吧,我以字节为单位获取数据。项目的目标是组装每个8字节并将它们转换为double然后将这些double发送到计算机。我必须使用USART将数据发送到计算机。

当我使用USART时,我有两种方法:

  1. 一个从USART_x获取数据:UARTCharGet(UART1_BASE)
  2. 另一个通过USART_x发送数据:UARTCharPut(UART0_BASE,d)
  3. 问题在于有两个只接受字符的方法。因此,使用这些方法进行double是不可能的,因为double是8个字节而字符是1个字节。我正在尝试将双打发送到我的电脑。有什么想法吗?

    第二个问题是从计算机侧编写程序以从微控制器获取数据(字节)。

    我应该用c编写这个程序(另一种方法是使用matlab,因为我会使用这些数据进行模拟)? 如何在c 中访问com-Port(如果可能,则在matlab中访问)?

3 个答案:

答案 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配置,但从专业角度来看,它确实不是便携式和良好的解决方案。