I2C 帧接收和发送优化 - C 代码实现
{
"title": "I2C 帧接收和发送优化 - C 代码实现",
"description": "本文介绍了使用 C 语言实现的 I2C 帧接收和发送功能的优化代码,包括对帧头判断逻辑、发送数据逻辑和代码结构的改进,提高了代码的可读性和可维护性。",
"keywords": "I2C, 帧接收, 帧发送, 优化, C 语言, 代码实现",
"content": "#define MAX_I2C_FRAME_DATA_LEN 32\nvoid i2c_tx_onebyte(uint8_t tx_onebyte)\n{\n static uint8_t i2c_frame_data[MAX_I2C_FRAME_DATA_LEN]; //存储需要发送的数据帧,最大32位\n static uint8_t i2c_frame_data_len = 0; //缓存中已经存储的长度\n static BOOL is_rx_i2c_frame_data = USER_FALSE; //iic数据接收标识\n if (!is_rx_i2c_frame_data)\n {\n if (tx_onebyte == 0xFE) //接收到帧头\n {\n is_rx_i2c_frame_data = USER_TRUE;\n i2c_frame_data_len = 0;\n i2c_frame_data[i2c_frame_data_len++] = tx_onebyte;\n }\n }\n else\n {\n // 如果缓存数组未存满,将接收到的数据存入缓存数组中。\n if (i2c_frame_data_len < MAX_I2C_FRAME_DATA_LEN)\n {\n i2c_frame_data[i2c_frame_data_len++] = tx_onebyte;\n }\n // 如果缓存数组已经存满,强制将缓存数组中的数据发送出去,并将缓存数组清空。\n else\n {\n uint16_t send_len = 0;\n while (i2c_frame_data_len > 0)\n {\n if (i2c_frame_data_len > MAX_I2C_FRAME_DATA_LEN)\n {\n i2c_send_one_frame_data(i2c_frame_data + send_len, MAX_I2C_FRAME_DATA_LEN);\n send_len += MAX_I2C_FRAME_DATA_LEN;\n i2c_frame_data_len -= MAX_I2C_FRAME_DATA_LEN;\n }\n else\n {\n i2c_send_one_frame_data(i2c_frame_data + send_len, i2c_frame_data_len);\n send_len += i2c_frame_data_len;\n i2c_frame_data_len -= i2c_frame_data_len;\n }\n }\n i2c_frame_data_len = 0;\n }\n /*\n 如果接收到了帧尾0xFF,说明当前数据帧已经接收完成。\n 调用i2c_send_one_frame_data函数将缓存数组中的数据帧发送出去,\n 并将is_rx_i2c_frame_data标记为FALSE,\n 表示结束当前数据帧的接收和发送。\n */\n if (tx_onebyte == 0xFF)\n {\n // 如果缓存数组中有数据,将其发送出去,并将缓存数组清空。\n if (i2c_frame_data_len > 0)\n {\n uint16_t send_len = 0;\n while (i2c_frame_data_len > 0)\n {\n if (i2c_frame_data_len > MAX_I2C_FRAME_DATA_LEN)\n {\n i2c_send_one_frame_data(i2c_frame_data + send_len, MAX_I2C_FRAME_DATA_LEN);\n send_len += MAX_I2C_FRAME_DATA_LEN;\n i2c_frame_data_len -= MAX_I2C_FRAME_DATA_LEN;\n }\n else\n {\n i2c_send_one_frame_data(i2c_frame_data + send_len, i2c_frame_data_len);\n send_len += i2c_frame_data_len;\n i2c_frame_data_len -= i2c_frame_data_len;\n }\n }\n i2c_frame_data_len = 0;\n }\n is_rx_i2c_frame_data = USER_FALSE;\n }\n }\n}\n检查bug并优化程序内容:在给定的代码中,有以下几个问题和优化点:\n\n1. 在接收数据时,判断帧头是否为0xFE的逻辑有误。根据注释,应该是接收到帧头0xFE才开始接收数据,但代码中的判断条件是当帧头不为0xFE时才开始接收数据。修改判断条件为if (tx_onebyte == 0xFE)。\n\n2. 在发送数据时,存在冗余的代码。在缓存数组已满时,通过while循环将缓存数组中的数据发送出去,并清空缓存数组。然而,在while循环中的两个分支中,执行的代码是相同的,可以将两个分支合并为一个,减少冗余代码。修改为以下代码:\n\nc\ni2c_send_one_frame_data(i2c_frame_data + send_len, i2c_frame_data_len);\nsend_len += i2c_frame_data_len;\ni2c_frame_data_len = 0;\n\n\n3. 在发送数据时,可以将发送数据的逻辑提取为一个函数,以提高代码的可读性和可维护性。\n\n下面是优化后的代码:\n\nc\nvoid i2c_tx_onebyte(uint8_t tx_onebyte)\n{\n static uint8_t i2c_frame_data[MAX_I2C_FRAME_DATA_LEN];\n static uint8_t i2c_frame_data_len = 0;\n static BOOL is_rx_i2c_frame_data = USER_FALSE;\n\n if (!is_rx_i2c_frame_data)\n {\n if (tx_onebyte == 0xFE)\n {\n is_rx_i2c_frame_data = USER_TRUE;\n i2c_frame_data_len = 0;\n i2c_frame_data[i2c_frame_data_len++] = tx_onebyte;\n }\n }\n else\n {\n if (i2c_frame_data_len < MAX_I2C_FRAME_DATA_LEN)\n {\n i2c_frame_data[i2c_frame_data_len++] = tx_onebyte;\n }\n else\n {\n i2c_send_data_frame(i2c_frame_data, i2c_frame_data_len);\n i2c_frame_data_len = 0;\n }\n \n if (tx_onebyte == 0xFF)\n {\n if (i2c_frame_data_len > 0)\n {\n i2c_send_data_frame(i2c_frame_data, i2c_frame_data_len);\n i2c_frame_data_len = 0;\n }\n is_rx_i2c_frame_data = USER_FALSE;\n }\n }\n}\n\nvoid i2c_send_data_frame(uint8_t* data, uint8_t len)\n{\n uint8_t send_len = 0;\n\n while (len > 0)\n {\n uint8_t send_data_len = (len > MAX_I2C_FRAME_DATA_LEN) ? MAX_I2C_FRAME_DATA_LEN : len;\n i2c_send_one_frame_data(data + send_len, send_data_len);\n send_len += send_data_len;\n len -= send_data_len;\n }\n}\n\n\n这样优化后的代码结构更清晰,逻辑更明确,提高了可读性和可维护性。
原文地址: https://www.cveoy.top/t/topic/pMJf 著作权归作者所有。请勿转载和采集!