Python实现通过信号位置更新Can报文

def calc_new_value(data, start_bit, bit_len, target_value, encoding_order="intel"):
    """
    根据格式,修改指定位的数据
    :param data: 待修改的原始数据
    :param start_bit: 起始bit位
    :param bit_len: 占位长度
    :param target_value: 目标值
    :param encoding_order: motorola、intel
    """
    def padding_zero(value, n=8):
        """
        补零操作
        :param value: 需要补零的数据
        :param n: 需要补齐的位数,默认补齐8位
        :return: 补零后的数据
        """
        return value if len(value) == n else '0' * (n - len(value)) + value

    def get_byte_list(start_bit, bit_len, encoding_order="intel"):
        """
        根据起始位和长度,计算出当前需要修改哪些字节
        :param start_bit: 起始位
        :param bit_len: 长度
        :return: 字节索引列表
        """
        # 计算需要修改的byte  -s
        byte_set = set()
        for i in range(bit_len):
            byte_set.add(int((start_bit + i) / 8))
        byte_list = list(byte_set)

        if encoding_order != 'intel':
            # motorola格式,索引号是从前往后的,所以使用加减法的方式进行换算
            # intel下的[2,3],对应到motorola下的[1, 2]
            # intel下的[2,3, 4],对应到motorola下的[0, 1, 2]
            byte_list = [i - (len(byte_list) - 1) for i in byte_list]
        # 计算需要修改的byte  -e
        return byte_list

    def byte_join(byte_list, data, encoding_order="intel"):
        """
        将data中的数据根据byte_list进行拼接
        :param byte_list: 待处理的byte
        :param data: 所有数据
        :return: 拼接后的二进制数据
        """
        final_str = ''
        # intel:将后面的byte放到前面的byte的前面
        # motorola:将前面的byte放到后面的byte的前面
        if encoding_order == "intel":
            byte_list = byte_list[::-1]
        for i in range(len(byte_list)):
            byte_num = byte_list[i]
            byte_value = data[byte_num]
            byte_value_bin = bin(byte_value)[2:]
            byte_value_bin = padding_zero(byte_value_bin)
            final_str += byte_value_bin
        final_list = list(final_str)
        return final_list

    byte_list = get_byte_list(start_bit, bit_len, encoding_order)
    print("需要修改的byte=", byte_list)

    final_list = byte_join(byte_list, data, encoding_order)
    print("拼接后的二进制列表=", final_list)

    # 将拼接后的数据进行倒置,与列表形式对齐
    final_list_reverse = final_list[::-1]
    print("翻转后的二进制列表=", final_list_reverse)

    target_value_bin = list(bin(target_value)[2:])
    target_value_bin_reverse = target_value_bin[::-1]
    print('翻转后的期望修改的值=', target_value_bin_reverse)

    # 根据start_bit向零对齐处理,找到开始进行修改的位:第一个byte对应的bit索引
    if encoding_order == 'intel':
        # intel模式下,用第一个byte拿到索引
        edit_bit = start_bit - 8 * byte_list[0]
    else:
        # motorola模式下,用最后一个byte拿到索引
        edit_bit = start_bit - 8 * byte_list[-1]
    # 遍历需要修改的长度进行取值
    for i in range(bit_len):
        final_list_reverse[edit_bit + i] = target_value_bin_reverse[i] if i < len(target_value_bin_reverse) else '0'
    final_list = final_list_reverse[::-1]
    print("修改后的二进制列表=", final_list)

    # 需要将byte_list倒序,因为叠加的时候是后面的叠加到了前面
    if encoding_order == "intel":
        byte_list = byte_list[::-1]
    for i in range(len(byte_list)):
        split_value = ''.join(final_list[i + 7 * i:i + 7 * i + 8])
        data[byte_list[i]] = int(split_value, 2)
    print("修改后的完整数据=", data)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值