LPC1752 CAN总线学习#
CAN 工作模式#
- 正常模式:
CAN 寄存器
MOD
的RM,LOM,STM
位全为0- 正常模式下的自发自收(全局测试):
在正常模式下,发送时同时置位
CMD
寄存器的SRR
位- 只听模式:
置位
MOD
寄存器的LOM
位,该模式下禁一切发送,收到 CAN 总线的数据也不做应答- 测试模式下的自发自收(局部测试):
置位
MOD
寄存器的STM
位发送时同时置位
CMD
寄存器的SRR
位
同样的测试环境不同板子结果可能不同:
测试条件: CAN 总线不接任何设备,且本设备 CAN 终端电阻不接
测试结果: 有板子能成功收发,有板子不能(必须把终端电阻接上才能通过)
static int32_t CANx_SetMode(ARM_CAN_MODE mode, uint8_t x)
{
LPC_CAN_TypeDef *ptr_CAN;
uint32_t event;
if (x >= CAN_CTRL_NUM) {
return ARM_DRIVER_ERROR;
}
if (can_driver_powered[x] == 0U) {
return ARM_DRIVER_ERROR;
}
ptr_CAN = ptr_CANx[x];
event = 0U;
switch (mode) {
case ARM_CAN_MODE_INITIALIZATION:
ptr_CAN->MOD = CAN_MOD_RM; // Enter reset mode
// Disable filter and allow table RAM access
LPC_CANAF->AFMR = CANAF_AFMR_AccBP | CANAF_AFMR_AccOff;
if (can_unit_state[x] != ARM_CAN_UNIT_STATE_INACTIVE) {
can_unit_state[x] = ARM_CAN_UNIT_STATE_INACTIVE;
event = ARM_CAN_EVENT_UNIT_BUS_OFF;
}
break;
case ARM_CAN_MODE_NORMAL:
LPC_CANAF->AFMR = 0U; // Enable filter
ptr_CAN->MOD &= ~(CAN_MOD_STM | // Deactivate Self Test Mode
CAN_MOD_LOM | // Deactivate Listen Only Mode
CAN_MOD_RM) ; // Enter operating mode
can_loopback[x] = 0U; // Loopback not active
if (can_unit_state[x] != ARM_CAN_UNIT_STATE_ACTIVE) {
can_unit_state[x] = ARM_CAN_UNIT_STATE_ACTIVE;
event = ARM_CAN_EVENT_UNIT_ACTIVE;
}
break;
case ARM_CAN_MODE_RESTRICTED:
return ARM_DRIVER_ERROR_UNSUPPORTED;
case ARM_CAN_MODE_MONITOR:
LPC_CANAF->AFMR = 0U; // Enable filter
ptr_CAN->MOD |= CAN_MOD_LOM; // Activate Listen Only Mode
ptr_CAN->MOD &= ~(CAN_MOD_STM | // Deactivate Self Test Mode
CAN_MOD_RM) ; // Enter operating mode
can_loopback[x] = 0U; // Loopback not active
if (can_unit_state[x] == ARM_CAN_UNIT_STATE_ACTIVE) {
can_unit_state[x] = ARM_CAN_UNIT_STATE_PASSIVE;
event = ARM_CAN_EVENT_UNIT_PASSIVE;
}
break;
case ARM_CAN_MODE_LOOPBACK_INTERNAL:
LPC_CANAF->AFMR = 0U; // Enable filter
//ptr_CAN->MOD |= CAN_MOD_STM | // Activate Self Test Mode
// CAN_MOD_LOM ; // Activate Listen Only Mode
// 内部测试(局部测试)是自测模式下,自发自收来完成的
ptr_CAN->MOD |= CAN_MOD_STM; // Activate Self Test Mode
ptr_CAN->MOD &= ~(CAN_MOD_LOM |
CAN_MOD_RM) ; // Enter operating mode
can_loopback[x] = 1U; // Loopback active
if (can_unit_state[x] == ARM_CAN_UNIT_STATE_ACTIVE) {
can_unit_state[x] = ARM_CAN_UNIT_STATE_PASSIVE;
event = ARM_CAN_EVENT_UNIT_PASSIVE;
}
break;
case ARM_CAN_MODE_LOOPBACK_EXTERNAL:
LPC_CANAF->AFMR = 0U; // Enable filter
//ptr_CAN->MOD |= CAN_MOD_STM; // Activate Self Test Mode
//ptr_CAN->MOD &=~(CAN_MOD_LOM | // Deactivate Listen Only Mode
// CAN_MOD_RM) ; // Enter operating mode
// 外部测试(全局测试)是正常模式下,自发自收来完成
ptr_CAN->MOD &= ~(CAN_MOD_STM | // Deactivate Self Test Mode
CAN_MOD_LOM | // Deactivate Listen Only Mode
CAN_MOD_RM) ; // Enter operating mode
can_loopback[x] = 1U; // Loopback active
if (can_unit_state[x] == ARM_CAN_UNIT_STATE_PASSIVE) {
can_unit_state[x] = ARM_CAN_UNIT_STATE_ACTIVE;
event = ARM_CAN_EVENT_UNIT_ACTIVE;
}
break;
}
if ((CAN_SignalUnitEvent[x] != NULL) && (event != 0U)) {
CAN_SignalUnitEvent[x](event);
}
return ARM_DRIVER_OK;
}