目录
简介
- CAN模块是CAN总线通信模块,CANFD模块是CAN扩展协议模块,CAN模块和CANFD模块是互斥的,只能同时使用一个,但是CANFD可兼容CAN。
- CAN:适用于数据速率要求较低、数据负载较小的应用,如传统的车辆ECU通信和简单的工业自动化网络。
- CAN FD:适用于需要更高数据速率和更大数据负载的现代应用,如高级驾驶辅助系统(ADAS)、自动驾驶、车载娱乐系统以及复杂的工业自动化控制系统。
- 基于CANFD实现CAN和CANFD数据的发送和接收(波特率为500K,采样点为81.3%数据段波特率2M,采样点为80.0%).
引脚配置
MCU的CANFD_TX和RX引脚以及收发器STB和EN引脚的配置。
FUNCTION | GPIOx_SFR | PIN |
---|---|---|
CANFD_TX | GPIOA_SFR | GPIO_PIN_MASK_3 |
CANFD_RX | GPIOE_SFR | GPIO_PIN_MASK_7 |
STB | GPIOG_SFR | GPIO_PIN_MASK_9 |
EN | GPIOC_SFR | GPIO_PIN_MASK_6 |
/**
* @brief :Canfd Gpio Init,PTA3:CANFD6_TX , PTE7:CANFD6_RX
* @param in :None
* @param out :None
* @retval :None
*/
void Canfd_Gpio_Init(void)
{
GPIO_Pull_Up_Enable(GPIOA_SFR, GPIO_PIN_MASK_3, TRUE);
GPIO_Write_Mode_Bits(GPIOA_SFR, GPIO_PIN_MASK_3, GPIO_MODE_RMP);
GPIO_Pull_Up_Enable(GPIOE_SFR, GPIO_PIN_MASK_7, TRUE);
GPIO_Write_Mode_Bits(GPIOE_SFR, GPIO_PIN_MASK_7, GPIO_MODE_RMP);
GPIO_Pin_RMP_Config(GPIOA_SFR, GPIO_Pin_Num_3, GPIO_RMP_AF6);
GPIO_Pin_RMP_Config(GPIOE_SFR, GPIO_Pin_Num_7, GPIO_RMP_AF6);
}
/**
* @brief: GPIOx output initialization configuration
*
* @param GPIOx Gpio port pointer
* @param GpioPin Pin number
* @retval: None
*/
void GPIOInit_Output_Config(GPIO_SFRmap *GPIOx, uint16_t GpioPin)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_Struct_Init(&GPIO_InitStructure);
GPIO_InitStructure.m_Pin = GpioPin;
GPIO_InitStructure.m_Speed = GPIO_LOW_SPEED;
GPIO_InitStructure.m_Mode = GPIO_MODE_OUT;
GPIO_InitStructure.m_PullUp = GPIO_NOPULL;
GPIO_InitStructure.m_PullDown = GPIO_NOPULL;
GPIO_Configuration(GPIOx, &GPIO_InitStructure);
GPIO_Set_Output_Data_Bits(GPIOx, GpioPin, Bit_SET);
}
void Canfd_Stb_En_Init(void)
{
GPIOInit_Output_Config(GPIOG_SFR, GPIO_PIN_MASK_9);
GPIOInit_Output_Config(GPIOC_SFR, GPIO_PIN_MASK_6);
}
波特率配置
- 波特率为500K,采样点为81.3%
- 数据段波特率2M,采样点为80.0%
const Can_BDRConfigType Canfd_Controller_AllClockAndBDRConfig[1] = {
/* Default 500k hz*/
/* Clock and baudrate config 0 : Index 0 */
{ .PreScale = 1U, .Sjw = 1U, .TSeg1 = 11U, .TSeg2 = 2U, .SampleTimes = CAN_SAMPLE_ONCE }
};
const Can_FdBDRConfigType Canfd_Controller_ALLFdBDRConfig[1] = {
/* Default 2M hz */
/* High Speed Clock and bandrate config 0 : Index 0 */
{
.BrsPrescale = 0U,
.HtSeg1 = 5U,
.HtSeg2 = 0U,
},
};
相关函数及变量
#define BODY_CAN_CTRL_INDEX CANfd6
typedef struct
{
Can_MailboxNumType MailBox;
Canfd_MailboxHeaderType *AttrStruct;
}CAN_MailboxConfig_t;
volatile uint32_t Writewrong_Flag = 0;
volatile uint8_t ArbLose_Flag = 0;
Canfd_MailboxHeaderType ClassicCAN_TxAttr = {
{ {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26,
0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33,
0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
}, Data_Length_8 },
0x111,
0x000,
CANFD_BRS_ENABLE,
CAN_FRAME_CLASSICAL,
CAN_DATA_STANDARD,
MAIL_TRANSMIT,
};
Canfd_MailboxHeaderType CANFD_TxAttr = {
{ {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26,
0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33,
0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
}, Data_Length_64 },
0x222,
0x000,
CANFD_BRS_ENABLE,
CAN_FRAME_FD,
CAN_DATA_STANDARD,
MAIL_TRANSMIT,
};
Canfd_MailboxHeaderType CANFD_RxAttr = {
{ {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26,
0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33,
0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
}, Data_Length_64 },
0x444,
0x000,
CANFD_BRS_ENABLE,
CAN_FRAME_CLASSICAL,
CAN_DATA_STANDARD,
CAN_RECEIVE,
};
static CAN_MailboxConfig_t ClassicCan_TxConfig =
{
Mailbox_0,
&ClassicCAN_TxAttr
};
static CAN_MailboxConfig_t Canfd_TxConfig =
{
Mailbox_0,
&CANFD_TxAttr
};
static CAN_MailboxConfig_t Canfd_RxConfig =
{
Mailbox_1,
&CANFD_RxAttr
};
Can_ControllerConfigType Canfd_Controller_AllConfig[1] = {
/* Can 0 Config */
{
/* Can controller Mode set
Value Range :
CANFD_NORMAL_MODE
CANFD_LOOP_INTERNAL_MODE
CNAFD_LOOP_EXTERNAL_MODE
CANFD_SILENT_MODE */
CANFD_NORMAL_MODE, /* Can controller Mode set
Value Range :
DISABLE
ENABLE */
ENABLE,
/* Can controller clock source set
Value Range :
CAN_CLOCKSOURCE_SCLK
CAN_CLOCKSOURCE_HFCLK
CAN_CLOCKSOURCE_LFCLK */
CAN_CLOCKSOURCE_HFCLK,
/* Can controller Arbitrate clock source set
Value Range :
CAN_CLOCKSOURCE_SCLK
CAN_CLOCKSOURCE_HFCLK
CAN_CLOCKSOURCE_LFCLK */
CAN_CLOCKSOURCE_HFCLK, /* Mailbox block size config
Value Range :
CAN_8_BYTE_DATALENGTH :
CAN_16_BYTE_DATALENGTH :
CAN_32_BYTE_DATALENGTH :
CAN_64_BYTE_DATALENGTH : */
CAN_8_BYTE_DATALENGTH, /* Iso mode or non-iso mode config
Value Range :
CAN_FD_NON_ISOMODE :
CAN_FD_ISOMODE : */
CAN_FD_ISOMODE,
/* Global Mask Set */
#if(HARDWARE_FILTER == STD_ON)
0x00000000,
#else
0xFFFFFFFF,
#endif
/* Enable/disable mailbox full receive config
Value Range :
CAN_MBFULLRECEIVE_DISABLE
CAN_MBFULLRECEIVE_ENABLE */
CAN_MBFULLRECEIVE_DISABLE, /* Interrupt config */
&Can_Controller_InterruptConfig[0],
#if(HARDWARE_FILTER == STD_ON)
/* Hardware Filter config */
&Can_HwFilter,
#endif
/* Arbitrate Segment Baudrate Config */
&Canfd_Controller_AllClockAndBDRConfig[0],
/* Data Segment Baudrate Config */
&Canfd_Controller_ALLFdBDRConfig[0],
},
/* end */
};
//接收邮箱的初始化
void Receive_Mailboxinit(const uint8_t Can_Controller_Index)
{
Can_m_FdMailBox_Write(Can_Controller_Index, Canfd_RxConfig.MailBox,Canfd_RxConfig.AttrStruct);
}
//数据发送函数
void CANFD_Send(const CAN_MailboxConfig_t * config)
{
volatile Kf32a_Canfd_Reg* ControllerRegPtr = (Kf32a_Canfd_Reg*)Can_m_ControllersInfo[BODY_CAN_CTRL_INDEX].BaseAddress;
uint8_t delay_num = 0x0;
/* Wait tx complete & tx state idle, or arb lose,we need to resend the data */
if (((ControllerRegPtr->CANFD_CTLR0.B.TCSTA == 0x01) && (ControllerRegPtr->CANFD_CTLR0.B.TXSTA == 0x00)) || (ArbLose_Flag == 1))
{
if(CAN_OK == Can_m_FdMailBox_Write(BODY_CAN_CTRL_INDEX, config->MailBox, config->AttrStruct))
{
Can_m_FdTransmit(BODY_CAN_CTRL_INDEX);
delay_num = 0xFF;
while((ControllerRegPtr->CANFD_CTLR0.B.TXSTA == 0x01) && (delay_num--));
if(Writewrong_Flag > 0)
{
Writewrong_Flag--;
}
else
{
Writewrong_Flag = 0;
}
}
else
{
Can_m_FdTransmit(BODY_CAN_CTRL_INDEX);
}
if(ArbLose_Flag == 1)
{
ArbLose_Flag = 0;
}
}
else
{
Can_m_FdTransmit(BODY_CAN_CTRL_INDEX);
Writewrong_Flag++;
if(Writewrong_Flag == 128)
{
can_init();
}
}
}
//初始化函数
void can_init(void)
{
/* CANFD initialized */
Canfd_Gpio_Init();
Can_m_FdControllerDeInit(BODY_CAN_CTRL_INDEX);
Can_m_FdControllerInit(BODY_CAN_CTRL_INDEX, Canfd_Controller_AllConfig, Initindex_0);
/* CANFD Receive messages structure initialized */
Receive_Mailboxinit(BODY_CAN_CTRL_INDEX);
}
//然后调用下边这两个函数即可成功发送数据
void canfd_send()
{
CANFD_Send(&Canfd_TxConfig);
}
void can_send()
{
CANFD_Send(&ClassicCan_TxConfig);
}