| 简介 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引脚的配置。
 
 
   
 /**
 *  @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);
 }
 
 
 
 
 结束
 
 
   
 ————————————————
 
 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
 
 原文链接:https://blog.csdn.net/xiaohuanxiong_/article/details/141065083
 
 
 |