| 一、CAN0 
 查看芯片手册,CAN0的初始化,IO口需要重映射。
 
 
  
 
 #define CAN_BAUDRATE  500
 
 //CAN0引脚定义
 #define   CAN0_CLOCK                    RCU_GPIOB
 #define   CAN0_GPIO                     GPIOB
 #define   CAN0_TX_GPIO_PIN              GPIO_PIN_9
 #define   CAN0_RX_GPIO_PIN              GPIO_PIN_8
 
 
 can_trasnmit_message_struct transmit_message;
 can_receive_message_struct receive_message;
 
 
 void CAN0_Init(void)
 {
 can_parameter_struct can_parameter;
 can_filter_parameter_struct can_filter;
 
 u32 filter_list_id = 0x1f8040fe;//过滤器列表数字(用不到可以不用)
 u32 filter_mask_id = 0x1f000000;//过滤掩码数
 
 //打开时钟
 rcu_periph_clock_enable(CAN0_CLOCK);
 rcu_periph_clock_enable(RCU_CAN0);
 rcu_periph_clock_enable(RCU_AF);
 
 /* configure CAN0 GPIO */
 gpio_pin_remap_config(GPIO_CAN0_PARTIAL_REMAP,ENABLE);       //重映射配置
 gpio_init(GPIOB,GPIO_MODE_IPU,GPIO_OSPEED_50MHZ,CAN0_RX_GPIO_PIN);
 gpio_init(GPIOB,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,CAN0_TX_GPIO_PIN);
 
 
 /* initialize transmit message */
 can_struct_para_init(CAN_INIT_STRUCT, &can_parameter);
 can_struct_para_init(CAN_INIT_STRUCT, &can_filter);
 
 /* initialize CAN register */
 can_deinit(CAN0);
 /* initialize CAN parameters */
 can_parameter.time_triggered = DISABLE;            //时间出发通信发送使能
 can_parameter.auto_bus_off_recovery =ENABLE;       //bus off自动恢复使能
 can_parameter.auto_wake_up = DISABLE;              //自动唤醒恢复使能
 can_parameter.no_auto_retrans = DISABLE;           //关闭自动重传模式
 can_parameter.rec_fifo_overwrite = DISABLE;        //接收FIFO覆盖模式使能
 can_parameter.trans_fifo_order = DISABLE;          //发送FIFO命令使能
 can_parameter.working_mode = CAN_NORMAL_MODE;      //正常工作模式
 can_parameter.resync_jump_width = CAN_BT_SJW_1TQ;
 can_parameter.time_segment_1 = CAN_BT_BS1_5TQ;
 can_parameter.time_segment_2 = CAN_BT_BS2_4TQ;
 
 /* 1MBps */
 #if CAN_BAUDRATE == 1000
 can_parameter.prescaler = 6;
 /* 500KBps */
 #elif CAN_BAUDRATE == 500
 can_parameter.prescaler = 12;
 /* 250KBps */
 #elif CAN_BAUDRATE == 250
 can_parameter.prescaler = 24;
 /* 125KBps */
 #elif CAN_BAUDRATE == 125
 can_parameter.prescaler = 48;
 /* 100KBps */
 #elif  CAN_BAUDRATE == 100
 can_parameter.prescaler = 60;
 /* 50KBps */
 #elif  CAN_BAUDRATE == 50
 can_parameter.prescaler = 120;
 /* 20KBps */
 #elif  CAN_BAUDRATE == 20
 can_parameter.prescaler = 300;
 #endif
 
 can_init(CAN0, &can_parameter);
 
 /* initialize filter */
 can_filter.filter_number=0;     //
 can_filter.filter_mode = CAN_FILTERMODE_MASK;  //掩码过滤模式
 can_filter.filter_bits = CAN_FILTERBITS_32BIT; //过滤长度
 can_filter.filter_list_high = ((filter_list_id << 3) >> 16) & 0xffff; //过滤器列表数字高位
 can_filter.filter_list_low = (filter_list_id << 3) & 0xffff;  //过滤器列表数字低位
 can_filter.filter_mask_high = ((filter_mask_id << 3)>>16) & 0xffff; //过滤掩码数高位
 can_filter.filter_mask_low = ((filter_mask_id << 3)&0xffff);  //过滤掩码数低位
 can_filter.filter_fifo_number = CAN_FIFO0; //与过滤器关联的FIFO
 can_filter.filter_enable = ENABLE; //过滤使能
 
 can_filter_init(&can_filter);
 
 /* configure CAN0 NVIC */
 nvic_irq_enable(CAN0_RX0_IRQn,1,2);
 
 /* enable can receive FIFO0 not empty interrupt */
 can_interrupt_enable(CAN0, CAN_INT_RFNE0);
 
 //发送消息配置
 can_struct_para_init(CAN_TX_MESSAGE_STRUCT, &transmit_message);
 transmit_message.tx_sfid = 0x321;           //标准帧ID
 transmit_message.tx_efid = 0x13456734;      //扩展帧ID,29bits
 transmit_message.tx_ft = CAN_FT_DATA;
 transmit_message.tx_ff = CAN_FF_EXTENDED;
 
 //接收消息配置
 can_struct_para_init(CAN_RX_MESSAGE_STRUCT, &receive_message);
 }
 
 
 
 /************************************************************************************************
 **函数名:Can0_SendData(u8* pstr,u16 length)
 **功能  :CAN0数据发送
 **其他  :
 ************************************************************************************************/
 void Can0_SendData(u8* pstr,u16 length)
 {
 u32 i =0;
 if(length > 8) return;
 transmit_message.tx_dlen = length;
 for(i=0;i<length;i++)
 {
 transmit_message.tx_data = pstr;
 }
 can_message_transmit(CAN0, &transmit_message);  //CAN发送函数
 }
 
 /************************************************************************************************
 **函数名:CAN0_RX0_IRQHandler(void)
 **功能  :CAN0中断接收处理
 **其他  :
 ************************************************************************************************/
 void CAN0_RX0_IRQHandler(void)
 {
 /* check the receive message */
 can_message_receive(CAN0, CAN_FIFO0, &receive_message);
 CAN0_Receice_Analysis(&receive_message);
 }
 
 
 
 二、CAN1
 
 查看了一下芯片手册,IO初始化配置不需要重映射。
 
 
  
 
 //GD32F305系列要使用CAN1必须打开这个宏
 #define GD32F30X_CL 1
 
 #define CAN1_BAUDRATE 250
 
 //CAN1引脚定义
 #define   CAN1_CLOCK                    RCU_GPIOB
 #define   CAN1_GPIO                     GPIOB
 #define   CAN1_TX_GPIO_PIN              GPIO_PIN_13
 #define   CAN1_RX_GPIO_PIN              GPIO_PIN_12
 
 
 
 can_trasnmit_message_struct Can1_transmit_message;
 can_receive_message_struct Can1_receive_message;
 
 void CAN1_Init(void)
 {
 can_parameter_struct can_parameter1;
 can_filter_parameter_struct can_filter1;
 
 //打开时钟
 rcu_periph_clock_enable(RCU_GPIOB);
 rcu_periph_clock_enable(RCU_CAN1);
 rcu_periph_clock_enable(RCU_AF);
 
 /* configure CAN0 GPIO */
 gpio_init(CAN1_GPIO,GPIO_MODE_IPU,GPIO_OSPEED_50MHZ,CAN1_RX_GPIO_PIN);   //CANRX
 gpio_init(CAN1_GPIO,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,CAN1_TX_GPIO_PIN); //CANTX
 
 /* initialize transmit message */
 can_struct_para_init(CAN_INIT_STRUCT, &can_parameter1);
 can_struct_para_init(CAN_INIT_STRUCT, &can_filter1);
 
 /* initialize CAN register */
 can_deinit(CAN1);
 
 /* initialize CAN parameters */
 can_parameter1.time_triggered = DISABLE;            //时间出发通信发送失能
 can_parameter1.auto_bus_off_recovery =ENABLE;       //bus off自动恢复失能
 can_parameter1.auto_wake_up = DISABLE;              //自动唤醒恢复失能
 can_parameter1.no_auto_retrans = DISABLE;           //关闭自动重传模式
 can_parameter1.rec_fifo_overwrite = DISABLE;        //接收FIFO覆盖模式失能
 can_parameter1.trans_fifo_order = DISABLE;          //发送FIFO命令失能
 can_parameter1.working_mode = CAN_NORMAL_MODE;      //正常工作模式
 can_parameter1.resync_jump_width = CAN_BT_SJW_1TQ;
 can_parameter1.time_segment_1 = CAN_BT_BS1_5TQ;
 can_parameter1.time_segment_2 = CAN_BT_BS2_4TQ;
 
 /* 1MBps */
 #if CAN1_BAUDRATE == 1000
 can_parameter1.prescaler = 6;
 /* 500KBps */
 #elif CAN1_BAUDRATE == 500
 can_parameter1.prescaler = 12;
 /* 250KBps */
 #elif CAN1_BAUDRATE == 250
 can_parameter1.prescaler = 24;
 /* 125KBps */
 #elif CAN1_BAUDRATE == 125
 can_parameter1.prescaler = 48;
 /* 100KBps */
 #elif  CAN1_BAUDRATE == 100
 can_parameter1.prescaler = 60;
 /* 50KBps */
 #elif  CAN1_BAUDRATE == 50
 can_parameter1.prescaler = 120;
 /* 20KBps */
 #elif  CAN1_BAUDRATE == 20
 can_parameter1.prescaler = 300;
 #endif
 
 if(can_init(CAN1, &can_parameter1) != SUCCESS) {
 // 初始化失败处理
 printf("can1 init error!\r\n");
 }
 
 /* initialize filter */
 can_filter1.filter_number = 15;     //CAN1使用过滤器因该为14-27
 can_filter1.filter_mode = CAN_FILTERMODE_MASK;  //掩码过滤模式
 can_filter1.filter_bits = CAN_FILTERBITS_32BIT; //过滤长度
 can_filter1.filter_list_high = 0x0000; //过滤器列表数字高位
 can_filter1.filter_list_low = 0x0000;  //过滤器列表数字低位
 can_filter1.filter_mask_high = 0x0000; //过滤掩码数高位
 can_filter1.filter_mask_low = 0x0000;  //过滤掩码数低位
 can_filter1.filter_fifo_number = CAN_FIFO0; //与过滤器关联的FIFO
 can_filter1.filter_enable = ENABLE; //过滤使能
 
 can_filter_init(&can_filter1);
 
 /* configure CAN0 NVIC */
 nvic_irq_enable(CAN1_RX0_IRQn,1,2);
 
 /* enable can receive FIFO0 not empty interrupt */
 can_interrupt_enable(CAN1, CAN_INT_RFNE0);
 //发送消息配置
 can_struct_para_init(CAN_TX_MESSAGE_STRUCT, &Can1_transmit_message);
 Can1_transmit_message.tx_sfid = 0x321;           //标准帧ID
 Can1_transmit_message.tx_efid = 0x13456734;      //扩展帧ID,29bits
 Can1_transmit_message.tx_ft = CAN_FT_DATA;
 Can1_transmit_message.tx_ff = CAN_FF_EXTENDED;
 //接收消息配置
 can_struct_para_init(CAN_RX_MESSAGE_STRUCT, &Can1_receive_message);
 }
 
 
 
 /************************************************************************************************
 **函数名:Can1_SendData(u8* pstr,u16 length)
 **功能  :CAN1数据发送
 **其他  :
 ************************************************************************************************/
 void Can1_SendData(uint8_t* pstr,uint16_t length)
 {
 u32 i =0;
 if(length > 8) return;
 transmit_message.tx_dlen = length;
 for(i=0;i<length;i++)
 {
 transmit_message.tx_data = pstr;
 }
 can_message_transmit(CAN1, &transmit_message);  //CAN发送函数
 }
 
 
 /************************************************************************************************
 **函数名:CAN1_RX0_IRQHandler(void)
 **功能  :CAN1中断接收处理
 **其他  :
 ************************************************************************************************/
 void CAN1_RX0_IRQHandler(void)
 {
 /* check the receive message */
 can_message_receive(CAN1, CAN_FIFO0, &receive_message);
 CAN1_Receice_Analysis(&receive_message);
 }
 
 
 
 三、调试
 
 配置完了,可以烧录代码试试看,能不能跑通。
 
 如果不行。首先排除软件问题:
 
 1、把正常工作模式换成回环模式
 
 
  
 
 //can_parameter1.working_mode = CAN_NORMAL_MODE;      //正常工作模式
 
 can_parameter1.working_mode = CAN_LOOPBACK_MODE;      //回环工作模式
 
 
 2、换成后就能去调试了,按我这一套配置的话,应该是没有问题的。可以正常收发。在接收中断中打个断点看能不能接收到。
 
 排除完软件问题还是不行。那么,有请硬件同事登场。哈哈哈哈~
 ————————————————
 版权声明:本文为CSDN博主「一叶舞澎湃」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
 原文链接:https://blog.csdn.net/p467616/article/details/148222890
 
 
 |