package message import "log/slog" //应答器传输模块BTM与车载ATP通信协议定义 const ( CAN_ADDR_REQ_BTM = byte(0x62) //设备地址 CAN_ADDR_REQ_ATP = byte(0x81) //设备地址 CAN_ADDR_RSP_BTM = byte(0x02) //设备地址 CAN_ADDR_RSP_ATP = byte(0x01) //设备地址 CAN_FRAME_ATP_REQ = byte(0x02) //帧类型-查询请求帧 CAN_FRAME_STATUS_RSP = byte(0x01) //状态应答帧 CAN_FRAME_TIME_SYNC_RSP = byte(0x02) //时间同步应答帧 CAN_FRAME_DATA_RSP = byte(0x80) //数据应答帧 CAN_FRAME_DATA_END_RSP = byte(0xff) //数据结束应答帧 ) //////////////////////////////////////////////////////////////////////////////////// // CanFrameId CAN串行总线帧ID定义,29bits type CanFrameId struct { //ID1 8bits ID1 byte //ID2 8bits ID2 byte //ID3 8bits ID3 byte //ID4 5bits ,有效位[bit4,bit0],无效位[bit7,bit5] ID4 byte } // NewCanFrameId 创建CAN串行总线帧ID // dstAddr 目的设备地址 // srcAddr 源设备地址 // frameType 帧类型 // sn 序列号 func NewCanFrameId(dstAddr byte, srcAddr byte, frameType byte, sn byte) *CanFrameId { return &CanFrameId{ ID1: dstAddr, ID2: srcAddr, ID3: frameType, ID4: sn, } } //////////////////////////////////////////////////////////////// // AtpRequestFrame ATP查询帧 type AtpRequestFrame struct { //帧ID FId CanFrameId //功率放大器命令,false-0关闭功率放大器,true-1s开启功率放大器 PowerAmplifierTurnOn bool //功率放大器控制者,false-0BTM控制,true-1ATP控制 PowerAmplifierControlledByAtp bool //重发请求 ResendRequest byte //速度,1=0.1km/h Speed uint16 //当前ATP系统时间,1=1ms Time uint32 //crc 校验码,从数据流中接收到的 Crc16 uint16 //解码时CRC16校验结果,true-校验通过 Crc16CheckOk bool } // NewAtpRequestFrame 创建ATP查询帧 func NewAtpRequestFrame(sn byte) *AtpRequestFrame { return &AtpRequestFrame{ FId: *NewCanFrameId(CAN_ADDR_REQ_BTM, CAN_ADDR_REQ_ATP, CAN_FRAME_ATP_REQ, sn), } } func (f *AtpRequestFrame) Decode(cf *CanetFrame) bool { f.FId = cf.CanId // bits := NewCanBitsReader(cf.CanData, 8) // if d, ok := bits.ReadBits(1); ok { f.PowerAmplifierTurnOn = d == 1 } else { return false } if d, ok := bits.ReadBits(1); ok { f.PowerAmplifierControlledByAtp = d == 1 } else { return false } if d, ok := bits.ReadBits(2); ok { f.ResendRequest = d } else { return false } //speed f.Speed = 0x0000 if d, ok := bits.ReadBits(4); ok { f.Speed = uint16(d) f.Speed <<= 8 } else { return false } if d, ok := bits.ReadByte(); ok { f.Speed |= uint16(d) } else { return false } //time f.Time = 0 timeArr := make([]byte, 4, 4) if d, ok := bits.ReadByte(); ok { timeArr[0] = d } else { return false } if d, ok := bits.ReadByte(); ok { timeArr[1] = d } else { return false } if d, ok := bits.ReadByte(); ok { timeArr[2] = d } else { return false } if d, ok := bits.ReadByte(); ok { timeArr[3] = d } else { return false } crc16 := calculateAtpReqCrc16(timeArr) t1 := uint32(timeArr[0]) t2 := uint32(timeArr[1]) t3 := uint32(timeArr[2]) t4 := uint32(timeArr[3]) f.Time |= t1 << 24 f.Time |= t2 << 16 f.Time |= t3 << 8 f.Time |= t4 //crc f.Crc16 = 0 if d, ok := bits.ReadByte(); ok { crc1 := uint16(d) f.Crc16 |= crc1 << 8 } else { return false } if d, ok := bits.ReadByte(); ok { crc2 := uint16(d) f.Crc16 |= crc2 } else { return false } //crc校验 f.Crc16CheckOk = f.Crc16 == crc16 if !f.Crc16CheckOk { slog.Debug("解码AtpRequestFrame,CRC16校验未通过!!") } // return true } func (f *AtpRequestFrame) Encode() *CanetFrame { cf := &CanetFrame{} cf.CanId = f.FId cf.CanLen = 8 cf.FF = true cf.RTR = false // bits := NewCanBitsWriter(8) // if f.PowerAmplifierTurnOn { bits.AddBits(1, 1) } else { bits.AddBits(0, 1) } // if f.PowerAmplifierControlledByAtp { bits.AddBits(1, 1) } else { bits.AddBits(0, 1) } // bits.AddBits(f.ResendRequest, 2) //速度 bits.AddBits(byte(f.Speed>>8), 4) bits.AddByte(byte(f.Speed)) //时间 timeArr := make([]byte, 4, 4) timeArr[0] = byte(f.Time >> 24) timeArr[1] = byte(f.Time >> 16) timeArr[2] = byte(f.Time >> 8) timeArr[3] = byte(f.Time) for _, timeByte := range timeArr { bits.AddByte(timeByte) } //crc crc16 := calculateAtpReqCrc16(timeArr) bits.AddByte(byte(crc16 >> 8)) bits.AddByte(byte(crc16)) // cf.CanData = bits.(CanBusData).GetData() // return cf }