【串行编址】
一、串行编址触发条件
(1)当存在BMS从关机到开机的事件发生时,该BMS发起编址请求,BMS CAN的所有BMS进入编址模式开始编址。每簇BMS编址成功后,同时立即发起对该簇的所有BMU进行编址。
(2)簇内任一一台设备重新开机
串行编址策略是一簇的全部编址完成才编址下一簇
缺点:在设备较多的情况下编址时间过长
优点:逻辑清晰,代码简洁
二、编址的硬件接线图:
通过DIDO的电平变换确定编址的顺序,时序变化决定编址地址,一般来说地址不会跳变
三、串行编址流程图
串行编址策略是一簇的全部编址完成才编址下一簇
四、串行编址过程描述
满足重新编址的条件-----进入是否重新编址的检测函数中判断
- 按下任意一台BMS复位键:BOOT状态拉高DO,将自身设备ID设置为0XFF,广播发送进入编址模式的报文
- can网络中各BMS接收进入编址模式,DO拉高
- 2S后检测到哪个BMS的DI为低电平确认该BMS为主机
- 确认好主机,主机开始编址自己的BMU
- CAN接收中断会持续有数据,主机的BMU持续编址
- BMU编址完成,CAN接收缓存区无报文,监控计时器++
- 监控计时器计时到,进入BMU监控器函数,判断BMU个数是否正常、BMU编址是否成功,在BMSCAN上发送BMU编址成功
- 主机接收到该报文,发送BMS编址,编址下一个BMS2
- BMS2编址自己的BMU
- 重复第3步,直到CAN总线没有报文了,主机监控器计时到
- 判断是否整个编址结束
五、主代码框架
void AutoEncode_Task(void * pvParameters)
{
BaseType_t err = pdFALSE;
volatile UBaseType_t uxHighWaterMark;
(void)pvParameters;
if(GetMsgVal(MBMS_SAM_SIG_ID_GROUP_NO) == INVALID_GROUP_NO)
{
//自动编码预处理过程
ResetAutoEncode();
//判断自己是否为主机,启动编址
MasterEncodeInit();
}
g_Encode_Binary_Semaphore = xSemaphoreCreateBinary();
uxHighWaterMark = uxTaskGetStackHighWaterMark( NULL );
for( ;; )
{
if(SYS_STATUS_NORMAL != GetSysRunModeFg())
{
vTaskDelete(NULL);
}
if(NULL != g_Encode_Binary_Semaphore)
{
err = xSemaphoreTake(g_Encode_Binary_Semaphore, AUTOENCODE_TIME_OUT_VAL);
if(pdTRUE == err)
{
//接收编址指令并回复
ParseAutoEncodeMsg(&g_EncodeFrame);
}
else
{
if(TRUE == GetMsgVal(MBMS_SAM_SIG_ID_BMU_IS_ADDRESSING))
{
//BMU编址超时监测
AutoEncodeBMUMonitor();
}
else if(TRUE == GetMsgVal(MBMS_SAM_SIG_ID_BMS_IS_ADDRESSING)
&& MASTER_GROUP_NO == GetMsgVal(MBMS_SAM_SIG_ID_GROUP_NO))
{
//主机编址超时监测
AutoEncodeEndMonitor();
}
}
}
else if(pdFALSE == err)
{
vTaskDelay(300);
}
uxHighWaterMark = uxTaskGetStackHighWaterMark( NULL );
}
}