利用联合体通过串口收发浮点数

以下介绍两种方法,一种是利用指针,一种是利用联合体,时间宝贵的看客可以直接跳到第二种方法

这里只是讨论数据发送前和接收后的处理,不讨论具体发送过程


方法一:指针

UART串口有一个缺点,就是发送和接受是一个字节一个字节的接收,如果发送的浮点数那可怎么办啊?

有人会说,那就一个字节一个字节发送啊

那么,我先定义一个double data

32位机中,一个double类型占8个字节,也就是说

data需要拆分8块通过UART发送

how?

学习c语言的时候,你肯定读过这句话:指针是c语言的精髓

那就用指针吧!

怎么用?

我也不清楚,现在只有一个变量,那么就声明一个指针指向这个变量吧

double *p;
p = &data;

p会将8个字节当成一个整体,这样p+1就不能指向下一个字节的地址了

那么如果我将p强转成 unsigned char *呢?

或者我们声明一个unsigned  char * 指向这个data

unsigned  char  *q;
q = (unsigned  char *)p;

那么串口发送就用一个for循环就够了

for(i=0;i<8;i++)
{
    send(*(q+i));
}

接收方先用一个数组将数据从低位开始接收

再使用一个double指针强行指向数组头就行了

下面这段代码是模拟串口发送前后数据拆分组合的过程

vs2010


方法二:联合体

方法一太繁琐了

有没有简单点的办法?

利用联合体(共同体)有多简单?

直接上代码

#include "stdafx.h"
#define MAX_LENTH 8
union U1
{
    char s[MAX_LENTH];
    double d;
};

union U2
{
    char s[MAX_LENTH];
    double d;
};

int _tmain(int argc, _TCHAR* argv[])
{
    U1 u1;
    U2 u2;
    int i=0;

    u1.d = 2.111;
    u2.d = 3.00;
    printf("u1.d = %lf\n",u1.d);
    printf("u2.d = %lf\n",u2.d);
    printf("Send Data...");

    for(i=0;i<MAX_LENTH;i++)
    {
        u2.s[i] = u1.s[i];
    }

    printf("u2.d = %lf\n",u2.d);
    while(getchar()==‘q‘);
    return 0;
}

方法一简直就是浪费脑力啊!

vs2010结果

为什么联合体会这么神奇呢?

因为它的所有成员相对于基地址的偏移量都为0

也就是说

双精度浮点数地址 &u1.d 与数组首地址 u1.s是一样的


“马后炮”:

其实方法一的方法和联合体的思想是一样的

利用了数组保存接收的数据(数据的实质就是内存存储二进制),将一个指向double的指针指向这份数组的首地址,那么我们通过取值符号*将这份数据完好无缺的读出来了啊!只不过联合体中double的地址就是数组首地址 ,不需要像方法一那样强转!

时间: 2024-08-06 17:53:35

利用联合体通过串口收发浮点数的相关文章

wince串口收发的编码问题

在编写串口收发的嵌入式程序时碰到了一些奇怪的问题,主要是发送的数据乱码,接收的数据为空,但是数据长度并不为零.经过一些来来回回的修改,反反复复的参考别人的代码,最终认为主要是因为wince内部使用的是unicode编码,而PC机端的串口调试助手都是ascii码,两者之间需要转换,即在发送数据之前要先把unicode转换成标准ascii码,收到数据数据后要转换回来,转换方法都是在网上找大神的资料参考的: unicode转换成标准ascii码: CString csStr(_T("输入350个以上的

在VB中利用API进行串口通信

本文转自http://blog.csdn.net/lyserver/article/details/4153335 '* ******************************************************* *'*    程序名称:basComm.bas'*    程序功能:在VB中利用API进行串口通信'*    作者:lyserver'*    联系方式:http://blog.csdn.net/lyserver'* ************************

串口收发数据时字符、十六进制、二进制格式详细区分

在使用串口调试助手时发送和接收数据都是以字节 (Byte) 为单位,并且可以选择字符.十六进制.二进制三种收发格式 ,那么这三种格式究竟怎样区分呢? 首先我们来明确一个概念 :串口收发数据的单位 '' 字节 (Byte) '' ,   1Byte = 8 bits , 串口收发数据格式一般为  1bit起始位(一般为0) + 8bits 数据位(一字节) +1bit校验位(可有可无) +1bit结束位(一般为1) 下面逐一区分三种收发格式: (1) 十六进制:   由于1位十六进制数位宽为 4b

QT5 串口收发实例代码

以下代码是自己测试门禁系统使用的 主要用到了串口的接收和发送  开发环境:xp  QT5.1.1 串口:38400   N  8  1 自动检测可用串口 在xp上测试没问题 有些usb转串口会出现波特率不准的问题,CH340的usb转232使用完全正常 以下为收发的线程.h 和.cpp两个文件 最后附上转sacii显示的代码 如果要参考的话,源代码已上传:http://download.csdn.net/detail/liang890319/6463227 [cpp] view plain co

在 S5PV210 的 开发板上 使用 串口 收发信息

参考学习教程:周立功嵌入式Linux开发教程-(上册) 材料:首先 准备一个 安装好 Linux 的 开发板 使用  xshell 工具 连接 开发板  ,winscp 工具 连接 开发板  ,  准备 一个 Ubuntu  32位 ,装上 交叉编译链.. 使用下面 代码 和 Makefile 文件 进行编译  ,生成的  执行 文件  利用 winscp 软件复制到 Linux开发板上 ,利用 xshell 运行 这个可执行文件. 下面    代码的  功能  是   打开 串口 ,进行 等待

串口完整项目之串口收发字符串

上一篇博文中详细设计了串口发送模块,串口接收模块设计思想基本相同,只不过将总线的下降沿作为数据接收的开始条件.需要注意有两点:其一,串口接收中读取每一位bit数据时,最好在每一位的中间点取值,这样数据较为准确.第二,串口接收的比特数据属于异步数据,因此需要打两拍做同步处理,避免亚稳态的出现.关于串口接收的设计细节这里不再赘述,不明之处请参考串口发送模块设计思路.串口接收代码如下: 1 `timescale 1ns / 1ps 2 3 module uart_rx( 4 input clk, 5

串口收发字符转换为整数

最近在做VB串口上位机,其中一个问题就是:如何将串口收到的字符串原样转换为整型: 比如:收到"12345"  赋值给变量就是12345 在VC6.0环境下验证通过:(参靠了这位帅哥的:http://zz.csdn.net/bin/logs.php) #include<iostream.h> #include <stdio.h> #include <string.h> int  mi(unsigned char dat, unsigned char m

【STM32】串口收发驱动Drv_Uart|学习笔记

一.什么事串口? 大家常说串口,其实串口有很多种UART,SPI,IIC都是串口,一般大家口中的串口就是UART(Universal Asynchronous Receiver/Transmitter),STM32上集成了UART的控制器,所以我们通过简单的配置就可以实现UART通信的功能.当然光有控制器可以在单板间通信,但大部分的应用场景都是需要远距离的抗干扰传输,这时就需要做电平转换,,目前工业上常用的串口屏,串口透传zigbee,诸如此类的设备都会用到标准的串行接口,所以单板上一般会加一个

stm32串口实验:stm32通过usart1进行串口收发,PA9(TX)和PA10(RX)

这是stm32开发中比较简单的实验,原理是通过串口助手发送信息,stm32接收到信息以后在串口助手中打印相同的内容. 这里直接分享keil5工程代码,是在工程模板的基础上移植和修改了正点原子的串口代码 百度网盘链接:https://pan.baidu.com/s/1aptEjcYPuQlDD_ayZaNoJw 提取码:8hr9 (如果失效的话可以在下方评论留下邮箱,我看到会给你发一份) 顺便把usart.c和usart.h还有mian.c中的代码复制到下面,小伙伴可以直接移植到自己的工程中 实现