CAN总线是工业、汽车上应用较多,本次介绍如何在MPLAB X环境下进行SAME51 CAN驱动。

SAME51有两路CAN-FD模块:
符合CAN协议2.0版A、B部分和ISO 11898-1:2015
•最多两个控制器区域网络CAN
-支持CAN2.0 A/B和CAN-FD (ISO 11898-1:2015)
•支持最多64个数据字节的CAN FD
•CAN错误日志
•AUTOSAR优化
•SAE J1939优化
•两个可配置的接收fifo
•在接收高优先级消息时分离信令
•多达64个专用接收缓冲区和多达32个专用发送缓冲区
•可配置发送FIFO,发送队列,发送事件FIFO
•直接消息RAM访问CPU
•可编程环回测试模式
•屏蔽模块中断
•断电支持;在CAN支持上调试
•传输速率:
- 1mb /s的CAN 2.0模式
- CAN-FD模式10mb /s
其引脚分配如下所示:

本次使用的是CAN0 (PA22, PA23)。在MCC里面配置CAN0:

CAN参数配置:

生成CAN0模块初始化代码:
void CAN0_Initialize(void)
{
/* Start CAN initialization */
CAN0_REGS->CAN_CCCR = CAN_CCCR_INIT_Msk;
while ((CAN0_REGS->CAN_CCCR & CAN_CCCR_INIT_Msk) != CAN_CCCR_INIT_Msk)
{
/* Wait for initialization complete */
}
/* Set CCE to unlock the configuration registers */
CAN0_REGS->CAN_CCCR |= CAN_CCCR_CCE_Msk;
/* Set Nominal Bit timing and Prescaler Register */
CAN0_REGS->CAN_NBTP = CAN_NBTP_NTSEG2(3UL) | CAN_NBTP_NTSEG1(10UL) | CAN_NBTP_NBRP(0UL) | CAN_NBTP_NSJW(3UL);
/* Global Filter Configuration Register */
CAN0_REGS->CAN_GFC = CAN_GFC_ANFS_RXF0 | CAN_GFC_ANFE_REJECT;
/* Set the operation mode */
CAN0_REGS->CAN_CCCR &= ~CAN_CCCR_INIT_Msk;
while ((CAN0_REGS->CAN_CCCR & CAN_CCCR_INIT_Msk) == CAN_CCCR_INIT_Msk)
{
/* Wait for initialization complete */
}
(void) memset(&can0Obj.msgRAMConfig, 0x00, sizeof(CAN_MSG_RAM_CONFIG));
}配置发送Fifo:
printf(" ------------------------------ \r\n");
printf(" CAN Demo \r\n");
printf(" ------------------------------ \r\n");
/* Set Message RAM Configuration */
CAN0_MessageRAMConfigSet(Can0MessageRAM);
/* Prepare the message to send*/
uint8_t txFiFo[CAN0_TX_FIFO_BUFFER_SIZE];
CAN_TX_BUFFER *txBuffer = (CAN_TX_BUFFER *) txFiFo;
memset(txFiFo, 0x00, CAN0_TX_FIFO_BUFFER_ELEMENT_SIZE);
txBuffer->id = 0x168;
txBuffer->dlc = 8;
txBuffer->xtd = 1;
txBuffer->fdf = 1;
txBuffer->brs = 1;
for (uint8_t count = 8; count >= 1; count--) {
txBuffer->data[count - 1] = 51;
}在循环中进行CAN报文发送:
while (true) {
/* Maintain state machines of all polled MPLAB Harmony modules. */
SYS_Tasks();
printf(" Transmitting Message:");
txBuffer->data[1] = Index;
txBuffer->data[0] = Tune;
if (CAN0_InterruptGet(CAN_INTERRUPT_TC_MASK)) {
CAN0_InterruptClear(CAN_INTERRUPT_TC_MASK);
}
//if (CAN0_MessageTransmit(messageID, messageLength, message, CAN_MODE_NORMAL, CAN_MSG_ATTR_TX_FIFO_DATA_FRAME) == true) {
if (CAN0_MessageTransmitFifo(1, txBuffer) == true) {
printf("CAN Send Success. Speed =%lu, Bright=%d \r\n", currentIndex, TuneLED);
} else {
printf("CAN Send Failed \r\n");
}
}//end of while还有一点需要注意,新版本的CAN API接口发生了变化。可参考: https://microchip.my.site.com/s/article/Harmony-3-bootloader-V3-5-0-does-not-compile-with-the-Can-driver-generated-by-CSP-V3-10-0
In CSP V3.10.0 the transmit interface for the can driver was changed from:
bool CAN0_MessageTransmit(uint32_t id, uint8_t length, uint8_t* data, CAN_MODE mode, CAN_MSG_TX_ATTRIBUTE msgAttr);
to
bool CAN0_MessageTransmitFifo(uint8_t numberOfMessage, CAN_TX_BUFFER *txBuffer);
编译烧录,遇到错误:

在网上查找了资料,找到了原来ATMEL公司的一个KBA:
ATSAM device - RDDI_DAP_OPERATION_FAILED Error https://microchip.my.site.com/s/article/ATSAM-device---RDDI-DAP-OPERATION-FAILED-Error
【临时方案】后来尝试把连接到开发板的TJA1050 GND引脚暂时与开发板断开,竟然可以成功烧录了。烧录成功后,再连接TJA1050与开发板。
打开串口:

USB CAN工具:

改变发送数据,CAN调试工具成功接收到更新后的数据。

参考:
CANx_MessageTransmitFifo Function https://onlinedocs.microchip.com/oxy/GUID-450989FA-38E4-4D68-AB61-15ADB29AD718-en-US-6/GUID-4BBEDABD-6866-446F-BE57-7C5117D86F44.html
Harmony 3 bootloader V3.5.0 does not compile with the Can driver generated by CSP V3.10.0 https://microchip.my.site.com/s/article/Harmony-3-bootloader-V3-5-0-does-not-compile-with-the-Can-driver-generated-by-CSP-V3-10-0
我要赚赏金
