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

sending data from microcontroller to the computer using tiva series c

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

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

  1. 一个从USART_x获取数据:UARTCharGet(UART1_BASE)
  2. 另一个通过 USART_x 发送数据:UARTCharPut(UART0_BASE,d)

问题在于有两种只接受字符的方法。因此,将这些方法用于 double 是不可能的,因为 double 是 8 个字节,而一个字符是一个字节。我正在尝试将双打发送到我的计算机。有什么想法吗?

第二个问题是在计算机端写一个程序,从微控制器中获取数据(字节)。

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

一般来说,您遇到的是序列化问题,最好的方法是为此目的使用专门的库。

你可以用一种肮脏但简单的方法来解决它。 你得好好assemble你另一边的数据恢复到原来的两倍。

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,则应将此联合封装到某个框架中,例如为了在另一边成功地重新assemble这个。

 _____________ ________ __________ ___________ ________
|             |        |          |           |        |
| FRAME_BEGIN | LENGTH | MyDouble | FRAME_END | CRC-8? |
|_____________|________|__________|___________|________|

接下来您可能应该对该结构强制执行字节对齐,这是由编译器指令完成的。它确保您的结构没有填充字节等,并分配最小需要的大小。这在嵌入式应用程序用例中非常流行,在这些用例中,一些二进制对象将在串行接口上​​传输——这正是您的情况。这种简单的解决方案可能适用于特定的硬件+软件配置,但从专业的角度来看,它肯定不是可移植的好解决方案。

你需要找到一种方法来分解大量数据,并将其发送给客户端,然后客户端需要一种方法来重新assemble数据,并且还需要知道这些数据何时被处理已发送。

一个非常简单的方法是将双精度数的所有数字转换为字符。效率低下,但它很容易完成工作,如下所示。这是可取的原因是因为它可以让您轻松创建自己的 "instruction set"。例如,您可以将字符 '!' 保留为 "the letter following ! denotes a special instruction",这样当客户端看到序列“!d”时,它就知道接下来的 32 个字节的数据代表一个 double ,并重新assemble它。

如果您只发送原始字节,当您想要创建转义码或操作码以向客户端发出特殊情况信号时,它会变得更加复杂。

代码清单


#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.

另一个适合我的解决方案(类似于 Krystian 的解决方案)。我定义了一个函数,它的参数是一个双精度数和一个字节数组。 double 必须转换为字节数组。这就是为什么我定义了一个大小为 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));

}