打印

基于GD32A503V EVAL板CAN总线的建立

[复制链接]
1888|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zyj8848|  楼主 | 2023-3-10 23:17 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 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的发送和接受这一基本操作就已经完成了。对于其他复杂的应用场景,可以在该基础上进一步的衍生。

使用特权

评论回复
评论
21小跑堂 2023-3-16 09:50 回复TA
halo 如果是申请原创的话可以看下这个,详细了解下原创要求噢~https://bbs.21ic.com/icview-3279072-1-1.html 
沙发
zzrzzr| | 2024-4-25 11:45 | 只看该作者
你好 可以分享一下源码嘛 谢谢

使用特权

评论回复
板凳
lidi911| | 2024-4-25 19:30 | 只看该作者
现在很少有开发板还这样用双排排针吧GPIO引出来。

使用特权

评论回复
地板
烟雨蒙蒙520| | 2024-7-31 22:54 | 只看该作者
使用的是 GD32A50x_Demo_Suites_V1.0.2 中的 CAN 网络示例代码吗?。

使用特权

评论回复
5
ym0sly| | 2024-8-31 11:51 | 只看该作者
系统时钟的配置非常重要,它会影响到CAN通信的波特率等参数。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

5

主题

7

帖子

3

粉丝