如何使用MCU来控制读取PSI5类型传感器设备的数据。
关于PSI5,请参考这位大佬的文章 PSI5协议详解 ,里面有详细的写PSI5 协议的定义。这对于我们第一次用到PSI5协议类型的传感器有非常大的帮助。
我最近做的项目用到这个类型的传感器,协议类型是 P20CRC-500/3H.
所以就是
P: 同步并行总线模式
20:传感器与ECU之间的数据长度为20bit
CRC:表示传感器使用CRC进行数据校验
500:数据与数据之间的周期为500us (Note: 这里意味着MCU应该每500us向PSI5传感器发一次脉冲,这里巨坑)
3:每个周期之间的有3个时间槽
H:数据传输速率为189kpbs
一般清晰下,我的理解是很少有MCU和PSI5传感器直接连接的。一般是MCU<->PSI5控制器<->PSI5传感器。
我们选择elmos的 E521.41。E521.41有4个通道,可以接4个PSI5传感器。
MCU <-- SPI --> E521.41 <----> PSI5传感器
所以我们要做的操作是,每500us控制elmos的这个传感器来发一个脉冲,然后再读取数据。
以下是elmos芯片的发脉冲命令
至于是发短脉冲,还是长脉冲,请根据你自己的传感器手册来,我用的这个是发短脉冲。
发了脉冲后,就可以读传感器的数据了。
elmos支持读16bit, 24bit, 32bit 和48bit.
16bit帧格式里有效数据是11bit
24bit帧格式有效数据是19bit
32bit帧格式有效数据是27bit
以下是我用的传感器的协议
| Start Bit | Frame Control | status | SensorData(16bit) | CRC | ||||||||||||||||||||
| S1 | S2 | F0 | F1 | F2 | E0 | A0 | A1 | A2 | A3 | A4 | A5 | A6 | A7 | A8 | A9 | A10 | A11 | A12 | A13 | A14 | A15 | C2 | C1 | C0 |
我们可以数出来有效数据是25bit.
我们选用读32bit来读这个传感器. 19 <25< 27
问了elmos的人员,芯片收集数据的时候,会把起始位2bit去掉。其实是填了23bit,所以32bit读帧格式如下
| Fid 3位 | Err 2位 | 27 Bit 数据 | |||||||||||||||||||||||||||||
| Fid2 | Fid1 | Fid0 | Err1 | Err0 | D26 | D25 | D24 | D23 | D22 | D21 | D20 | D19 | D18 | D17 | D16 | D15 | D14 | D13 | D12 | D11 | D10 | D9 | D8 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
| elmos填充位 | CRC | 传感器数据 | 帧控制和状态 | ||||||||||||||||||||||||||||
| C0 | C1 | C2 | A15 | A14 | A13 | A12 | A11 | A10 | A9 | A8 | A7 | A6 | A5 | A4 | A3 | A2 | A1 | A0 | E0 | F2 | F1 | F0 | |||||||||
以上就是包括帧的格式。
同时,这个传感器是再slot2和slot3才读数据。所以也要对emols配置下。
那这里就有个问题了,slot1要不要配置呢?肯定是需要的。
ASIC_CNFG_1 =0x0002
ASIC_CNFG_2 = 0x02F0
ASIC_CNFG_3 = 0x006F(4路都打开,我4路都用了)
CH1_CFG1 = 0x0005
Bit[15] IDAC_CNT_MODE = 0 // 不改
Bit[14:13] IDAC_CNT_INC2 = 00 // 不改
Bit[12:11] IDAC_CNT_INC1 = 00 // 不改
Bit[10] EN_ER_CHK = 0 // ⚠️ 禁用校验 (无传感器)
Bit[9] T1_CRC = 0 // 无所谓
Bit[8:4] TS1_FLEN = 00000 // ⚠️ 帧长=0 (不期望接收数据)
Bit[3:0] T1_LEN = 0101 // 时隙长度=5×32μs=160μs (占位)
(每个slot 160us 3个就快500us)
CH1_CFG2 = 0x2EF5
Bit[15] = 0
Bit[14:13] IDAC_CNT_DEC2 = 01 // 保持默认!
Bit[12:11] IDAC_CNT_DEC1 = 01 // 保持默认!
Bit[10] EN_ER_CHK = 1 // ✅ 使能CRC校验
Bit[9] T2_CRC = 1 // ✅ CRC模式
Bit[8:4] TS2_FLEN = 01111 // ✅ 帧长=25bit (FLEN=25-10=15)
Bit[3:0] T2_LEN = 0101 // 时隙长度=160μs
CH1_CFG3 = 0x7EF5
Bit[15:11] = 00000
Bit[10] EN_ER_CHK = 1 // ✅ 使能CRC校验
Bit[9] T3_CRC = 1 // ✅ CRC模式
Bit[8:4] TS3_FLEN = 01111 // ✅ 帧长=25bit
Bit[3:0] T3_LEN = 0101 // 时隙长度=160μs
CH1_CFG4 = 0x0000 禁用
CH1_CFG5 = 0x0000 禁用
CH1_CFG6 = 0x0000 禁用
CH1_CFG7 = 0x0400
SPI_BUFFER_CNFG = 01 // 32bit/buffer
SYNC_DLY = 0
最后的最后,提醒一个点。
ASIC_CNFG_3需要最后写,也就是开启放到最后。