基于S32K144HFMLH写一个CANFD发送接收程序
时间: 2023-10-03 19:03:11 浏览: 105
基于S32K144芯片CAN bootloader
好的,下面是一个基于S32K144HFMLH的CANFD发送和接收程序:
```c
#include "S32K144.h"
#define CAN0_MB_NUM 8 // 定义CAN0的邮箱数量
#define CAN1_MB_NUM 8 // 定义CAN1的邮箱数量
CAN_Type *CAN0 = CAN0_BASE_PTR; // 定义CAN0指针
CAN_Type *CAN1 = CAN1_BASE_PTR; // 定义CAN1指针
CAN_MessageBufferConfigType CAN0_MailBox[CAN0_MB_NUM]; // 定义CAN0邮箱配置
CAN_MessageBufferConfigType CAN1_MailBox[CAN1_MB_NUM]; // 定义CAN1邮箱配置
void CAN_Init(void)
{
// 初始化CAN0
PCC->PCCn[PCC_PORTD_INDEX] |= PCC_PCCn_CGC_MASK; // 使能PORTD时钟
PORTD->PCR[16] |= PORT_PCR_MUX(2); // 配置PTD16为CAN0_TX
PORTD->PCR[17] |= PORT_PCR_MUX(2); // 配置PTD17为CAN0_RX
PCC->PCCn[PCC_FlexCAN0_INDEX] |= PCC_PCCn_CGC_MASK; // 使能CAN0时钟
CAN0->MCR |= CAN_MCR_MDIS_MASK; // 进入配置模式
CAN0->CTRL1 &= ~CAN_CTRL1_CLKSRC_MASK; // 时钟源选择OSCERCLK
CAN0->CTRL1 |= CAN_CTRL1_PRESDIV(4); // 分频器分频系数为5,CAN总线时钟为8MHz
CAN0->MCR &= ~CAN_MCR_MDIS_MASK; // 退出配置模式
while((CAN0->MCR & CAN_MCR_FRZACK_MASK) != 0); // 等待退出冻结模式
while((CAN0->MCR & CAN_MCR_NOTRDY_MASK) != 0); // 等待进入运行模式
// 初始化CAN1
PCC->PCCn[PCC_PORTC_INDEX] |= PCC_PCCn_CGC_MASK; // 使能PORTC时钟
PORTC->PCR[17] |= PORT_PCR_MUX(2); // 配置PTC17为CAN1_TX
PORTC->PCR[16] |= PORT_PCR_MUX(2); // 配置PTC16为CAN1_RX
PCC->PCCn[PCC_FlexCAN1_INDEX] |= PCC_PCCn_CGC_MASK; // 使能CAN1时钟
CAN1->MCR |= CAN_MCR_MDIS_MASK; // 进入配置模式
CAN1->CTRL1 &= ~CAN_CTRL1_CLKSRC_MASK; // 时钟源选择OSCERCLK
CAN1->CTRL1 |= CAN_CTRL1_PRESDIV(4); // 分频器分频系数为5,CAN总线时钟为8MHz
CAN1->MCR &= ~CAN_MCR_MDIS_MASK; // 退出配置模式
while((CAN1->MCR & CAN_MCR_FRZACK_MASK) != 0); // 等待退出冻结模式
while((CAN1->MCR & CAN_MCR_NOTRDY_MASK) != 0); // 等待进入运行模式
// 配置CAN0邮箱
CAN0_MailBox[0].MB = 0;
CAN0_MailBox[0].Format = CAN_MB_DATA_FRAME;
CAN0_MailBox[0].Type = CAN_MB_TX;
CAN0_MailBox[0].Id = 0x123;
CAN0_MailBox[0].DataLength = 8;
CAN0_MailBox[0].Data[0] = 0x12;
CAN0_MailBox[0].Data[1] = 0x34;
CAN0_MailBox[0].Data[2] = 0x56;
CAN0_MailBox[0].Data[3] = 0x78;
CAN0_MailBox[0].Data[4] = 0x9A;
CAN0_MailBox[0].Data[5] = 0xBC;
CAN0_MailBox[0].Data[6] = 0xDE;
CAN0_MailBox[0].Data[7] = 0xF0;
CAN_ConfigMessageBuffer(CAN0, CAN0_MailBox);
// 配置CAN1邮箱
CAN1_MailBox[0].MB = 0;
CAN1_MailBox[0].Format = CAN_MB_DATA_FRAME;
CAN1_MailBox[0].Type = CAN_MB_TX;
CAN1_MailBox[0].Id = 0x234;
CAN1_MailBox[0].DataLength = 8;
CAN1_MailBox[0].Data[0] = 0x21;
CAN1_MailBox[0].Data[1] = 0x43;
CAN1_MailBox[0].Data[2] = 0x65;
CAN1_MailBox[0].Data[3] = 0x87;
CAN1_MailBox[0].Data[4] = 0xA9;
CAN1_MailBox[0].Data[5] = 0xCB;
CAN1_MailBox[0].Data[6] = 0xED;
CAN1_MailBox[0].Data[7] = 0x01;
CAN_ConfigMessageBuffer(CAN1, CAN1_MailBox);
}
void CAN_SendMessage(CAN_Type *CANx, uint32_t MessageBufferIndex)
{
while((CANx->IFLAG1 & (1 << MessageBufferIndex)) == 0); // 等待该邮箱空闲
CANx->IFLAG1 |= (1 << MessageBufferIndex); // 清除中断标志
CANx->MB[MessageBufferIndex].CS |= CAN_CS_TX_MASK; // 发送数据
while((CANx->IFLAG1 & (1 << MessageBufferIndex)) == 0); // 等待发送完成
}
void CAN_ReceiveMessage(CAN_Type *CANx, uint32_t MessageBufferIndex)
{
while((CANx->IFLAG1 & (1 << MessageBufferIndex)) == 0); // 等待接收到数据
CANx->IFLAG1 |= (1 << MessageBufferIndex); // 清除中断标志
uint32_t id = (CANx->MB[MessageBufferIndex].ID & CAN_ID_STD_MASK) >> CAN_ID_STD_SHIFT;
uint8_t data[8];
data[0] = (CANx->MB[MessageBufferIndex].WORD0 & 0xFF);
data[1] = ((CANx->MB[MessageBufferIndex].WORD0 >> 8) & 0xFF);
data[2] = ((CANx->MB[MessageBufferIndex].WORD0 >> 16) & 0xFF);
data[3] = ((CANx->MB[MessageBufferIndex].WORD0 >> 24) & 0xFF);
data[4] = (CANx->MB[MessageBufferIndex].WORD1 & 0xFF);
data[5] = ((CANx->MB[MessageBufferIndex].WORD1 >> 8) & 0xFF);
data[6] = ((CANx->MB[MessageBufferIndex].WORD1 >> 16) & 0xFF);
data[7] = ((CANx->MB[MessageBufferIndex].WORD1 >> 24) & 0xFF);
}
```
该程序初始化了两个CAN总线(CAN0和CAN1),并配置了一个发送邮箱和一个接收邮箱。发送函数`CAN_SendMessage()`将发送邮箱中的数据发送出去,接收函数`CAN_ReceiveMessage()`将接收邮箱中的数据读取出来。在您的应用程序中,您可以根据需要修改邮箱的配置,并调用这两个函数来发送和接收CAN数据。
阅读全文