You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言中unsigned short与byte数组互转实现需求(SPI传输用)

How to Convert unsigned short Array to uint8_t (Byte) Array and Back for SPI Transmission

没问题,要实现SPI传输中unsigned short数组和字节数组的双向转换且不丢失数据,核心是处理好字节序(因为SPI是字节流,两端必须用相同的字节规则拆分/组合),同时保证缓冲区大小足够。

先说明:你示例里的函数名charArrayToByteArray和arrayByteToCharArray有点误导(我们处理的是unsigned short而非char),我会用更清晰的命名,你可以根据需求改名。

发送端:Convert unsigned short Array to uint8_t Array

unsigned short通常占2字节,所以转换后的字节数组长度是原数组长度的2倍。这里提供两种实现方式,推荐第一种(调用者提供缓冲区),避免内存泄漏风险:

方式1:调用者提供目标缓冲区(推荐)

这种方式不需要动态分配内存,更安全可控:

#include <stdint.h>

// 将unsigned short数组转换为uint8_t字节数组
// 参数说明:
// - src: 源unsigned short数组
// - dest: 目标字节数组,需确保大小 ≥ 2 * src_len 字节
// - src_len: 源数组的元素个数
void ushortArrayToByteArray(const unsigned short *src, uint8_t *dest, size_t src_len) {
    for (size_t i = 0; i < src_len; i++) {
        // 这里采用**大端序**(高位字节在前),SPI通信常用此格式,跨平台兼容性好
        // 如果需要小端序,交换下面两行代码即可
        dest[2 * i] = (uint8_t)(src[i] >> 8);       // 提取高8位
        dest[2 * i + 1] = (uint8_t)(src[i] & 0xFF); // 提取低8位
    }
}

使用示例(对应你的发送端代码):

unsigned short array[10] = {65000, 0, 6000, 15000, 100, 50, 1000, 10, 5000, 2000};
uint8_t byte_buf[20]; // 10个unsigned short → 20字节,必须保证缓冲区足够
ushortArrayToByteArray(array, byte_buf, 10);
send(byte_buf, sizeof(byte_buf)); // 发送20字节数据

方式2:动态分配内存(需手动释放)

如果不想提前固定缓冲区大小,可以动态分配,但一定要记得用free()释放内存:

#include <stdint.h>
#include <stdlib.h>

// 动态分配内存转换unsigned short数组为字节数组,返回NULL表示内存分配失败
uint8_t* ushortArrayToByteArray(const unsigned short *src, size_t src_len) {
    uint8_t *dest = malloc(2 * src_len);
    if (dest == NULL) {
        return NULL;
    }
    for (size_t i = 0; i < src_len; i++) {
        dest[2 * i] = (uint8_t)(src[i] >> 8);
        dest[2 * i + 1] = (uint8_t)(src[i] & 0xFF);
    }
    return dest;
}

使用示例:

unsigned short array[10] = {65000, 0, 6000, 15000, 100, 50, 1000, 10, 5000, 2000};
uint8_t *data = ushortArrayToByteArray(array, 10);
if (data != NULL) {
    send(data, 20); // 发送20字节
    free(data); // 必须释放内存,避免泄漏
}

接收端:Convert uint8_t Array Back to unsigned short Array

接收端的转换必须和发送端的字节序保持一致(大端/小端),否则会得到错误的数据:

方式1:调用者提供目标缓冲区

#include <stdint.h>

// 将字节数组转换为unsigned short数组
// 参数说明:
// - src: 源字节数组
// - dest: 目标unsigned short数组,需确保大小 ≥ src_len / 2 个元素
// - src_len: 源字节数组的长度(必须是偶数,否则无法完整转换)
void byteArrayToUshortArray(const uint8_t *src, unsigned short *dest, size_t src_len) {
    if (src_len % 2 != 0) {
        return; // 字节数为奇数,无法完整转换,可根据需求添加错误处理
    }
    size_t dest_len = src_len / 2;
    for (size_t i = 0; i < dest_len; i++) {
        // 大端序还原,和发送端逻辑对应
        dest[i] = (unsigned short)src[2 * i] << 8; // 高8位左移
        dest[i] |= (unsigned short)src[2 * i + 1]; // 或上低8位
    }
}

使用示例(对应你的接收端代码):

uint8_t buf[20];
uint8_t len = sizeof(buf);
receive(buf, &len);
unsigned short array[10];
byteArrayToUshortArray(buf, array, len);
// 现在array中就是还原后的原始数据

方式2:动态分配内存

#include <stdint.h>
#include <stdlib.h>

// 动态分配内存转换字节数组为unsigned short数组,返回NULL表示错误
unsigned short* byteArrayToUshortArray(const uint8_t *src, size_t src_len) {
    if (src_len % 2 != 0) {
        return NULL; // 字节数为奇数,无法转换
    }
    size_t dest_len = src_len / 2;
    unsigned short *dest = malloc(dest_len * sizeof(unsigned short));
    if (dest == NULL) {
        return NULL;
    }
    for (size_t i = 0; i < dest_len; i++) {
        dest[i] = (unsigned short)src[2 * i] << 8 | (unsigned short)src[2 * i + 1];
    }
    return dest;
}

使用示例:

uint8_t buf[20];
uint8_t len = sizeof(buf);
receive(buf, &len);
unsigned short *array = byteArrayToUshortArray(buf, len);
if (array != NULL) {
    // 使用还原后的array数据
    free(array); // 记得释放内存
}

关键注意事项

  • 字节序一致性:发送端和接收端必须使用完全相同的字节序(大端或小端)。大端序是SPI通信的通用选择,跨平台兼容性更好;如果你的系统是小端序(比如x86、多数ARM),也可以用小端,但两端必须统一。
  • 缓冲区大小:转换后的字节数组长度是原unsigned short数组长度的2倍,接收时要确保缓冲区能容纳足够的字节,否则会截断数据导致还原失败。
  • 内存管理:如果使用动态分配内存的方式,一定要记得调用free()释放,避免内存泄漏。
  • 数据完整性:这种转换方式只是拆分/组合字节,不会改变unsigned short的数值,所以完全不会损失数据(只要传输过程中没有丢包)。

内容的提问来源于stack exchange,提问作者Tibbe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:07:37