基于S32K342芯片与TJA1145AT/FD收发器,怎么实现FlexCAN通信,具体代码和详细解释
时间: 2024-03-04 20:49:40 浏览: 230
FlexCAN是一种常用的CAN通信协议,支持多种工作模式和数据传输速率。在S32K342芯片和TJA1145AT/FD收发器的组合中,可以通过FlexCAN协议实现高效的数据通信。以下是实现FlexCAN通信的具体代码和详细解释。
1. 初始化CAN模块
```c
void Init_FlexCAN(void)
{
/* Enable clock for FlexCAN module */
PCC->PCCn[PCC_FlexCAN1_INDEX] |= PCC_PCCn_CGC_MASK;
/* Set FlexCAN clock source */
CLOCK_SetIpSrc(kCLOCK_FlexCan1, kCLOCK_IpSrcSircAsync);
/* Reset FlexCAN module */
FLEXCAN1->MCR |= FLEXCAN_MCR_SOFTRST_MASK;
while ((FLEXCAN1->MCR & FLEXCAN_MCR_SOFTRST_MASK) == FLEXCAN_MCR_SOFTRST_MASK);
/* Set FlexCAN module to normal mode */
FLEXCAN1->MCR &= ~FLEXCAN_MCR_MDIS_MASK;
/* Configure FlexCAN module */
FLEXCAN1->CTRL1 |= FLEXCAN_CTRL1_PRESDIV(0x01) | FLEXCAN_CTRL1_PROPSEG(0x03) | FLEXCAN_CTRL1_PSEG1(0x03) | FLEXCAN_CTRL1_PSEG2(0x03);
FLEXCAN1->CTRL1 &= ~FLEXCAN_CTRL1_CLK_SRC_MASK;
FLEXCAN1->CTRL1 |= FLEXCAN_CTRL1_ERR_MSK_MASK | FLEXCAN_CTRL1_BOFF_MSK_MASK;
/* Set CAN bus to FD mode */
FLEXCAN1->MCR |= FLEXCAN_MCR_FDEN_MASK;
FLEXCAN1->CTRL1 |= FLEXCAN_CTRL1_FDEN_MASK | FLEXCAN_CTRL1_TDCEN_MASK | FLEXCAN_CTRL1_TDCOFF(0x03);
/* Enable FlexCAN module */
FLEXCAN1->MCR &= ~FLEXCAN_MCR_HALT_MASK;
while ((FLEXCAN1->MCR & FLEXCAN_MCR_FRZACK_MASK) != FLEXCAN_MCR_FRZACK_MASK);
}
```
在初始化FlexCAN模块之前,需要先开启FlexCAN模块的时钟,并设置FlexCAN模块时钟源。初始化过程中,需要进行以下操作:
- 重置FlexCAN模块;
- 将FlexCAN模块设置为正常模式;
- 配置FlexCAN模块的预分频、传播段、相位缓冲段1和相位缓冲段2;
- 设置CAN总线为FD模式;
- 启用FlexCAN模块。
2. 发送CAN数据
```c
void Send_FlexCAN(uint32_t id, uint8_t *data, uint8_t len)
{
flexcan_frame_t frame;
/* Set CAN message ID */
frame.id = id;
frame.format = kFLEXCAN_FrameFormatStandard;
frame.type = kFLEXCAN_FrameTypeData;
/* Set CAN message data */
memcpy(frame.data, data, len);
frame.length = len;
/* Send CAN message */
while ((FLEXCAN1->IFLAG1 & FLEXCAN_IFLAG1_BUF5I_MASK) == FLEXCAN_IFLAG1_BUF5I_MASK);
FLEXCAN1->MB[5].CS |= FLEXCAN_MB_CS_CODE(kFLEXCAN_TxData) | FLEXCAN_MB_CS_DLC(frame.length) | FLEXCAN_MB_CS_SRR_MASK;
FLEXCAN1->MB[5].ID = FLEXCAN_ID_STD(id);
memcpy((void *)&FLEXCAN1->MB[5].DATA[0], (void *)&frame.data[0], frame.length);
FLEXCAN1->MB[5].CS |= FLEXCAN_MB_CS_TXIE_MASK;
}
```
发送CAN数据时,需要先创建一个flexcan_frame_t类型的数据结构,用于设置CAN消息ID、格式、类型、数据和长度。然后,需要将数据结构中的数据复制到CAN消息缓冲区中,并设置CAN消息的长度和发送方式。最后,启动CAN消息发送,并等待发送完成。
3. 接收CAN数据
```c
void Receive_FlexCAN(void)
{
flexcan_frame_t frame;
/* Check if there is a new message available */
if ((FLEXCAN1->IFLAG1 & FLEXCAN_IFLAG1_BUF4I_MASK) == FLEXCAN_IFLAG1_BUF4I_MASK)
{
/* Read new message from buffer */
frame.format = kFLEXCAN_FrameFormatStandard;
frame.type = kFLEXCAN_FrameTypeData;
memcpy((void *)&frame.data[0], (void *)&FLEXCAN1->MB[4].DATA[0], FLEXCAN1->MB[4].CS & FLEXCAN_MB_CS_DLC_MASK);
/* Print received message */
printf("Received message: ID=0x%x, Data=%s\n", FLEXCAN1->MB[4].ID & FLEXCAN_MB_ID_EXT_MASK, frame.data);
/* Clear interrupt flag */
FLEXCAN1->IFLAG1 = FLEXCAN_IFLAG1_BUF4I_MASK;
}
}
```
接收CAN数据时,需要先检查CAN消息缓冲区是否有新的消息。如果有新消息,则需要从缓冲区中读取消息数据,并根据需要进行解析和处理。最后,需要清除中断标志位以允许处理下一条CAN消息。
以上是基于S32K342芯片与TJA1145AT/FD收发器实现FlexCAN通信的代码和解释。需要注意的是,在实际应用中,还需要根据具体的应用场景进行相应的配置和优化。同时,为确保数据传输的可靠性和安全性,还需要考虑CAN消息的加密、校验和等方面的问题。
阅读全文