一、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
|