计算机中的位bit字节Byte帧frame关系

本文介绍了计算机中数据的基本单位,包括位(bit)、字节(Byte)及其含义,并解释了在网络传输过程中如何将数据封装成帧(frame)进行传输。通过学习这些基本概念,读者可以更好地理解计算机内部的数据处理及网络通信的基础。

1.计算机中的位bit

二进制系统中,每个0或1就是一个位bit,位是数据存储的最小单位。其中8bit就成为一个字节Byte。计算机中的CPU位数值得是CPU一次能处理的最大位数。
例如:32位计算机的CPU一次能处理32位数据

2.计算机中的字节Byte

字节Byte乃Binary digit(二进制数)的缩写,字节是通过网络传输信息(或在硬盘或内存存储信息)的单位,1Byte=8bits

3.计算机中的帧frame

在网络中,网络设备将位组成一个个字节,然后这些字节封装成帧,在网络上传输。为什么要把数据封装成帧呢?因为用户数据一般比较大,有的克达到MB字节甚至更大,

一下子发出去十分困难,于是就需要把数据分成许多小份,在按照一定的次序发送出去。帧是计算机发送数据是产生的,确切的说是由计算机安装的网卡产生的。

#include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <string.h> #include <math.h> #define DATA_FRAME_SIZE 8 // CAN 数据长度(固定为 8 字节) // 根据 LSB0 编码(小端字节序)将信号值写入到 CAN 数据中 void write_signal(uint8_t *data, int start_bit, int length, uint32_t signal_value) { // 打印信号值的二进制表示 printf(“\nSignal Value (binary): “); for (int i = length - 1; i >= 0; i–) { printf(”%d”, (signal_value >> i) & 1); } printf(“\n”); // 从起始开始写入信号值 for (int i = 0; i < length; i++) { int current_bit = start_bit + i; // 当前信号的全局置 int byte_index = current_bit / 8; // 当前所在的字节索引 int bit_offset = current_bit % 8; // 当前字节中的偏移(LSB0) // 获取信号值的当前(从最低有效开始) uint8_t bit_value = (signal_value >> i) & 0x01; // 设置数据中的对应 if (bit_value) { data[byte_index] |= (1 << bit_offset); // 设置为1 } else { data[byte_index] &= ~(1 << bit_offset); // 清除(设置为0) } // 调试输出 printf(" Bit %d (byte %d, offset %d) = %d\n", current_bit, byte_index, bit_offset, bit_value); } } // 验证并获取用户输入,支持范围检查 int get_valid_input(const char *prompt, int min, int max) { int value; while (1) { printf(“%s (%d-%d): “, prompt, min, max); if (scanf(”%d”, &value) == 1 && value >= min && value <= max) { while (getchar() != ‘\n’); // 清空输入缓冲区 return value; // 输入合法,返回结果 } else { printf(“Invalid input. Please enter a value in the range [%d, %d].\n”, min, max); while (getchar() != ‘\n’); // 清空输入缓冲区 } } } // 从用户获取信号值,基于动态长度校验值范围 uint32_t get_signal_value(int length) { // 计算最大值 uint32_t max_signal_value; if (length < 32) { max_signal_value = (1U << length) - 1; } else if (length == 32) { max_signal_value = UINT32_MAX; } else { // 对于长度大于32,我们使用64计算 max_signal_value = (uint32_t)(pow(2, length) - 1); } uint32_t value; while (1) { printf("Enter Signal Value (0-%u): ", max_signal_value); if (scanf("%u", &value) == 1 && value <= max_signal_value) { while (getchar() != '\n'); // 清空输入缓冲区 return value; } else { printf("Invalid Signal Value. Please enter a value in the range [0, %u].\n", max_signal_value); while (getchar() != '\n'); // 清空输入缓冲区 } } } // 打印布局表格(物理视图) void print_bit_layout(uint8_t *data, int start_bit, int length) { printf(“\nCAN Data Frame Bit Layout (Physical View):\n”); printf(" ±----------------------------------------------------------------+\n"); printf(" | Bit: 7 6 5 4 3 2 1 0 | Byte |\n"); printf(" ±----------------------------------------------------±---------+\n"); // 计算信号覆盖的范围 int signal_end_bit = start_bit + length - 1; // 打印每个字节布局 for (int byte = 0; byte < DATA_FRAME_SIZE; byte++) { printf(" | "); // 打印每个(从高到低) for (int bit = 7; bit >= 0; bit--) { int global_bit = byte * 8 + (7 - bit); // 计算全局置 uint8_t bit_value = (data[byte] >> bit) & 0x01; // 检查当前是否在信号范围内 int is_signal_bit = (global_bit >= start_bit && global_bit <= signal_end_bit); // 打印值并标记信号 if (is_signal_bit) { printf("[%d] ", bit_value); // 信号用方括号标记 } else { printf(" %d ", bit_value); // 非信号 } } // 打印字节索引十六进制值 printf("| Byte %d: %02X |\n", byte, data[byte]); } printf(" +-----------------------------------------------------+----------+\n"); // 打印全局索引 printf(" | Global Bit Index: | |\n"); printf(" | "); for (int byte = 0; byte < DATA_FRAME_SIZE; byte++) { for (int bit = 7; bit >= 0; bit--) { int global_bit = byte * 8 + (7 - bit); printf("%2d ", global_bit); } printf("| |\n | "); } printf("\b\b\b\b +-----------------------------------------------------------------+\n"); // 打印信号信息 printf("\nSignal Information:\n"); printf(" - Start Bit: %d (LSB)\n", start_bit); printf(" - End Bit: %d (MSB)\n", signal_end_bit); printf(" - Length: %d bits\n", length); printf(" - Signal occupies bits %d to %d (inclusive)\n", start_bit, signal_end_bit); // 打印数据的物理视图 printf("\nPhysical Data Frame Layout (LSB0):\n"); printf(" Byte 0: "); for (int bit = 0; bit < 8; bit++) { printf("%d", (data[0] >> bit) & 1); } printf(" (LSB first)\n"); for (int i = 1; i < DATA_FRAME_SIZE; i++) { printf(" Byte %d: ", i); for (int bit = 0; bit < 8; bit++) { printf("%d", (data[i] >> bit) & 1); } printf("\n"); } } // 将生成的 CAN 数据附加到文件 void append_to_file(const char *filename, uint32_t signal_id, uint8_t *data, int dlc) { FILE *file = fopen(filename, “a”); if (file == NULL) { perror(“Error: Cannot open file”); exit(EXIT_FAILURE); // 无法打开文件 } fprintf(file, "$%u $%d ", signal_id, dlc); // 输出 Signal ID DLC for (int i = 0; i < dlc; i++) { fprintf(file, "%02X ", data[i]); // 输出每个字节的数据 } fprintf(file, "\n"); fclose(file); // 关闭文件 printf("CAN message appended to %s\n", filename); } // 主函数 int main() { uint32_t signal_id; // 信号 ID int start_bit; // 起始 int length; // 信号长度 uint32_t signal_value; // 信号值 char continue_flag = ‘y’; // 打开文件并清空内容(只执行一次) FILE *file = fopen("CAN_message.txt", "w"); if (file == NULL) { perror("Error: Cannot create file"); return EXIT_FAILURE; } fclose(file); // 主循环,允许用户生成多条消息 while (continue_flag == 'y' || continue_flag == 'Y') { printf("\n===== New Message Generation (LSB0 Format) =====\n"); // 输入 Signal ID signal_id = get_valid_input("Enter Signal ID (positive integer)", 1, INT32_MAX); // 输入 Start Bit start_bit = get_valid_input("Enter Start Bit", 0, 63); // 输入 Length length = get_valid_input("Enter Signal Length", 1, 64); // 检查 Start Bit Length 的组合是否合法 if (start_bit + length > 64) { printf("Error: Start Bit + Signal Length exceeds the data frame range (64 bits).\n"); printf("Start Bit: %d, Length: %d, Max End Bit: %d\n", start_bit, length, start_bit + length - 1); continue; // 提示错误后重新开始一轮输入 } // 输入 Signal Value signal_value = get_signal_value(length); // 初始化 CAN 数据 uint8_t data[DATA_FRAME_SIZE] = {0}; write_signal(data, start_bit, length, signal_value); // 打印布局表格 print_bit_layout(data, start_bit, length); // 将数据写入文件 append_to_file("CAN_message.txt", signal_id, data, DATA_FRAME_SIZE); // 用户选择是否继续生成消息 printf("\nGenerate another message? (y/n): "); scanf(" %c", &continue_flag); while (getchar() != '\n'); // 清空输入缓冲区 } printf("Program exited. File will be overwritten on next run.\n"); return 0; } 字节写入顺序有点问题,是往上走的,写完16-23的byte2之后,再写8-15的byte1 Global Bit Index: 打印的也有问题 从左往右应该是bit7到bit0: 从上往下是byte0到byte7: 打印第一行应该是 7 6 5 4 3 2 1 0 第二行应该是 15 14 13 12 11 10 9 8
最新发布
08-27
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值