本帖最后由 zyj8848 于 2023-3-10 23:30 编辑
#申请原创# #GD-FAQ#
基于GD32A503V_EVAL板CAN总线的建立
一、环境搭建 1、 软件 GD32A50x_Demo_Suites_V1.0.2\GD32A503V_EVAL_Demo_Suites\Projects\15_CAN_Network\MDK-ARM 2、 硬件 GD32A503V_EVAL(GD32A503VDT3) 3、原理图如下: 开发板上CAN收发器使用的是MCP2561T-ESN,该芯片供电范围在4.5~5.5V,因此在使用开发板CAN功能时,需要将开发板进行5V供电,如下图所示,通过GDLINK供电,将JP14跳线帽跳至5V供电,并将SW1拨至ON,此时板子即为5V供电。 例程是开发板两路CAN进行通讯,因此需要将开发板上JP39和JP41的H和H引脚、L和L引脚连接。 二、软件配置 1、系统时钟 如下图所示,本例程系统时钟使用HXTAL倍频到100MHz,APB2时钟也为100MHz。 /* select a system clock by uncommenting the following line */ /* use IRC8M */ //#define __SYSTEM_CLOCK_IRC8M (uint32_t)(__IRC8M) //#define __SYSTEM_CLOCK_24M_PLL_IRC8M (uint32_t)(24000000) //#define __SYSTEM_CLOCK_48M_PLL_IRC8M (uint32_t)(48000000) //#define __SYSTEM_CLOCK_72M_PLL_IRC8M (uint32_t)(72000000) //#define __SYSTEM_CLOCK_100M_PLL_IRC8M (uint32_t)(100000000)
/* use HXTAL(CK_HXTAL = 8M)*/ //#define __SYSTEM_CLOCK_HXTAL (uint32_t)(__HXTAL) //#define __SYSTEM_CLOCK_24M_PLL_HXTAL (uint32_t)(24000000) //#define __SYSTEM_CLOCK_48M_PLL_HXTAL (uint32_t)(48000000) //#define __SYSTEM_CLOCK_72M_PLL_HXTAL (uint32_t)(72000000) #define __SYSTEM_CLOCK_100M_PLL_HXTAL (uint32_t)(100000000) /*! 2、CAN的引脚和时钟配置 如下图所示,CAN时钟为APB2的二分频,即50MHz,并配置好CAN0和CAN1的发送和接受引脚。 void can_gpio_config(void) { /* enable CAN clock */ rcu_can_clock_config(CAN0,RCU_CANSRC_PCLK2_DIV_2); rcu_can_clock_config(CAN1,RCU_CANSRC_PCLK2_DIV_2); rcu_periph_clock_enable(RCU_CAN0); rcu_periph_clock_enable(RCU_CAN1); /* enable CAN port clock*/ rcu_periph_clock_enable(RCU_GPIOB); rcu_periph_clock_enable(RCU_GPIOD);
/* configure CAN0 GPIO */ gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_13); gpio_mode_set(GPIOB,GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_13); gpio_af_set(GPIOB,GPIO_AF_6, GPIO_PIN_13);
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ, GPIO_PIN_14); gpio_mode_set(GPIOB,GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_14); gpio_af_set(GPIOB,GPIO_AF_6, GPIO_PIN_14);
/* configure CAN1 GPIO */ gpio_output_options_set(GPIOD,GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6); gpio_mode_set(GPIOD,GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_6); gpio_af_set(GPIOD,GPIO_AF_6, GPIO_PIN_6);
gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_7); gpio_mode_set(GPIOD,GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_7); gpio_af_set(GPIOD,GPIO_AF_6, GPIO_PIN_7); }
3、CAN的初始化配置 CAN的初始化配置如下所示,每段语句都有加注释,将CAN0和CAN1配置成正常模式,波特率为125K,并打开CAN0的邮箱0中断。其中需要注意的是,例程中打开了自接收模式,即允许将本节点发送的帧接收到相匹配的描述符中去。一些客户没注意到这点,可能导致节点发送时,会“误入中断”,因此没这个应用场景,可将自接收失能。 void can_config(void) { can_parameter_structcan_parameter;
/* initialize CAN register*/ can_deinit(CAN0); can_deinit(CAN1); /* initialize CAN */ can_struct_para_init(CAN_INIT_STRUCT, &can_parameter);
/* initialize CANparameters */ /* internal time counterincrease 1 when send or receive a bit */ can_parameter.internal_counter_source = CAN_TIMER_SOURCE_BIT_CLOCK; /* receive the frame sendby itself or not*/ can_parameter.self_reception= ENABLE; /* transmit frame priorityby MB priority or MB number*/ can_parameter.mb_tx_order= CAN_TX_HIGH_PRIORITY_MB_FIRST; /* support transmissionabort function or not */ can_parameter.mb_tx_abort_enable= ENABLE; /* MB priority structureincludes local priority value or not*/ can_parameter.local_priority_enable = DISABLE; /* when receive, (filterIDE && RTR bit), or (compare IDE && not compare RTR bit)*/ can_parameter.mb_rx_ide_rtr_type = CAN_IDE_RTR_FILTERED; /* when receive remoterequest frame, store it as data frame or generate a remote response frame*/ can_parameter.mb_remote_frame = CAN_STORE_REMOTE_REQUEST_FRAME; /* use separate filters /a same filter for all received frames*/ can_parameter.rx_private_filter_queue_enable = DISABLE; /* used for bus intergration state,enable to detect two continuous norminal dominant bit for hardware synchronousedge*/ can_parameter.edge_filter_enable = DISABLE; /* enable to detect protocolexception event(when not in FD mode, but receive a FD frame)*/ can_parameter.protocol_exception_enable = DISABLE; /* if RX FIFO is enabled, received frame to match mailbox/FIFO first*/ can_parameter.rx_filter_order = CAN_RX_FILTER_ORDER_MAILBOX_FIRST; /*32*4 words specific RAM memory for mailboxand RX FIO*/ can_parameter.memory_size= CAN_MEMSIZE_32_UNIT; /* filter configuration */ can_parameter.mb_public_filter = 0x0; //configureCAN_RMPUBF register can_parameter.resync_jump_width= 1; //SJW can_parameter.prop_time_segment = 2; //PTS segment can_parameter.time_segment_1 = 4; //PBS1segment can_parameter.time_segment_2= 3; //PBS2 segment /* 125Kbps */ can_parameter.prescaler =40; /*baudrate =fCANCLK/prescaler/(1+PTS+PBS1+PBS2)=50M/40/(1+2+4+3)=125K*/
/* initialize CAN */ can_init(CAN0,&can_parameter); can_init(CAN1,&can_parameter);
/* configure CAN0 NVIC */ nvic_irq_enable(CAN0_Message_IRQn, 0, 0);
/* enable CAN MB0interrupt */ can_interrupt_enable(CAN0,CAN_INT_MB0);
can_operation_mode_enter(CAN1,CAN_NORMAL_MODE); can_operation_mode_enter(CAN0, CAN_NORMAL_MODE); }
4、 CAN邮箱配置 以下是CAN的CAN1发送邮箱和CAN0接受邮箱0的配置,发送邮箱发送的是标准帧,帧ID为0x55,数据为tx_data数组中的数据。 can_struct_para_init(CAN_MDSC_STRUCT,&g_transmit_message); can_struct_para_init(CAN_MDSC_STRUCT,&g_receive_message); /* initialize transmitmessage */ g_transmit_message.rtr =0; g_transmit_message.ide =0; g_transmit_message.code =CAN_MB_TX_STATUS_DATA; g_transmit_message.brs =0; g_transmit_message.fdf =0; g_transmit_message.prio =0; g_transmit_message.data_bytes = 8; /* tx message content */ g_transmit_message.data =(uint32_t *)(tx_data); g_transmit_message.id =0x55;
g_receive_message.rtr = 0; g_receive_message.ide = 0; g_receive_message.code =CAN_MB_RX_STATUS_EMPTY; /* rx mailbox */ g_receive_message.id =0x55; g_receive_message.data =(uint32_t *)(rx_data); can_mailbox_config(CAN0,0, &g_receive_message);
三、运行 按下WAKEUP按键,CAN1的邮箱1会发出报文,如下图所示,此时CAN0会进入邮箱0中断 之后进行报文接收,对接收和发送的报文进行比较,若一致,LED2状态反转。 至此,CAN的发送和接受这一基本操作就已经完成了。对于其他复杂的应用场景,可以在该基础上进一步的衍生。
|
halo 如果是申请原创的话可以看下这个,详细了解下原创要求噢~https://bbs.21ic.com/icview-3279072-1-1.html