1回答

1收藏

GD32F450 双路CAN数据互传测试

GD32 GD32 11458 人阅读 | 1 人回复 | 2017-06-18

本帖最后由 toofree 于 2017-6-19 00:37 编辑

GD32F450 双路CAN数据互传测试

测试基于GD32F4xx_Firmware_Library_V1.2 库中,“GD32F4xx_Firmware_Library_V1.2 \Examples\CAN\Dual_CAN_communication”工程。
复制“GD32F4xx_Firmware_Library_V1.2\Template\Keil_project”的keil工程模板到“Dual_CAN_communication”文件夹,并对库和头文件路径做相应修改。得到如下图工程:


由于没有外接晶振,修改system_gd32f4xx.c文件是必须的。将第52行,__SYSTEM_CLOCK_200M_PLL_IRC16M 宏定义放开。


对照原理图修改gd32f4xx_eval.h文件中LED、按键、串口相关宏定义及参数。
  1. /*!
  2.     \file  gd32f4xx_eval.h
  3.     \brief definitions for GD32f4XX_EVAL's leds, keys and COM ports hardware resources
  4. */

  5. /*
  6.     Copyright (C) 2016 GigaDevice

  7.     2016-08-15, V1.0.0, firmware for GD32F4xx
  8. */

  9. #ifndef GD32F4XX_EVAL_H
  10. #define GD32F4XX_EVAL_H

  11. #ifdef cplusplus
  12. extern "C" {
  13. #endif

  14. #include "gd32f4xx.h"
  15.      
  16. /* exported types */
  17. typedef enum
  18. {
  19.     LED1 = 0,
  20.     LED2 = 1,
  21.     LED3 = 2,
  22.     LED4 = 3,
  23.     LED5 = 4,
  24.     LED6 = 5
  25. } led_typedef_enum;

  26. typedef enum
  27. {
  28.     KEY_WAKEUP = 0,
  29.     KEY_TAMPER = 1,
  30.     KEY_USER = 2
  31. } key_typedef_enum;

  32. typedef enum
  33. {
  34.     KEY_MODE_GPIO = 0,
  35.     KEY_MODE_EXTI = 1
  36. } keymode_typedef_enum;

  37. /* eval board low layer led */
  38. #define LEDn                             6U        //4U

  39. // #define LED1_PIN                         GPIO_PIN_6
  40. // #define LED1_GPIO_PORT                   GPIOC
  41. // #define LED1_GPIO_CLK                    RCU_GPIOC

  42. //   
  43. // #define LED2_PIN                         GPIO_PIN_7
  44. // #define LED2_GPIO_PORT                   GPIOC
  45. // #define LED2_GPIO_CLK                    RCU_GPIOC
  46. //   
  47. // #define LED3_PIN                         GPIO_PIN_8
  48. // #define LED3_GPIO_PORT                   GPIOC
  49. // #define LED3_GPIO_CLK                    RCU_GPIOC

  50. #define LED1_PIN                         GPIO_PIN_4                // ?LED4
  51. #define LED1_GPIO_PORT                   GPIOB
  52. #define LED1_GPIO_CLK                    RCU_GPIOB

  53. #define LED2_PIN                         GPIO_PIN_7                // ?LED5
  54. #define LED2_GPIO_PORT                   GPIOD
  55. #define LED2_GPIO_CLK                    RCU_GPIOD

  56. #define LED3_PIN                         GPIO_PIN_3                // ?LED6
  57. #define LED3_GPIO_PORT                   GPIOB
  58. #define LED3_GPIO_CLK                    RCU_GPIOB

  59. //   
  60. // #define LED4_PIN                         GPIO_PIN_9
  61. // #define LED4_GPIO_PORT                   GPIOC
  62. // #define LED4_GPIO_CLK                    RCU_GPIOC

  63. #define LED4_PIN                         GPIO_PIN_4
  64. #define LED4_GPIO_PORT                   GPIOB
  65. #define LED4_GPIO_CLK                    RCU_GPIOB

  66. #define LED5_PIN                         GPIO_PIN_7
  67. #define LED5_GPIO_PORT                   GPIOD
  68. #define LED5_GPIO_CLK                    RCU_GPIOD

  69. #define LED6_PIN                         GPIO_PIN_3
  70. #define LED6_GPIO_PORT                   GPIOB
  71. #define LED6_GPIO_CLK                    RCU_GPIOB

  72. /*
  73. #define COMn                             1U
  74. #define EVAL_COM1                        USART0
  75. #define EVAL_COM1_CLK                    RCU_USART0

  76. #define EVAL_COM1_TX_PIN                 GPIO_PIN_9
  77. #define EVAL_COM1_RX_PIN                 GPIO_PIN_10

  78. #define EVAL_COM_GPIO_PORT               GPIOA
  79. #define EVAL_COM_GPIO_CLK                RCU_GPIOA
  80. #define EVAL_COM_AF                      GPIO_AF_7
  81. */

  82. #define COMn                             1U
  83. #define EVAL_COM1                        USART2
  84. #define EVAL_COM1_CLK                    RCU_USART2

  85. #define EVAL_COM1_TX_PIN                 GPIO_PIN_8
  86. #define EVAL_COM1_RX_PIN                 GPIO_PIN_9

  87. #define EVAL_COM_GPIO_PORT               GPIOD
  88. #define EVAL_COM_GPIO_CLK                RCU_GPIOD
  89. #define EVAL_COM_AF                      GPIO_AF_7

  90. #define EVAL_COM1_IRQn                                                                    USART2_IRQn

  91. #define KEYn                             3U

  92. /* tamper push-button */
  93. // #define TAMPER_KEY_PIN                   GPIO_PIN_13
  94. // #define TAMPER_KEY_GPIO_PORT             GPIOC
  95. // #define TAMPER_KEY_GPIO_CLK              RCU_GPIOC
  96. // #define TAMPER_KEY_EXTI_LINE             EXTI_13
  97. // #define TAMPER_KEY_EXTI_PORT_SOURCE      EXTI_SOURCE_GPIOC
  98. // #define TAMPER_KEY_EXTI_PIN_SOURCE       EXTI_SOURCE_PIN13
  99. // #define TAMPER_KEY_EXTI_IRQn             EXTI10_15_IRQn
  100. #define TAMPER_KEY_PIN                   GPIO_PIN_1
  101. #define TAMPER_KEY_GPIO_PORT             GPIOE
  102. #define TAMPER_KEY_GPIO_CLK              RCU_GPIOE
  103. #define TAMPER_KEY_EXTI_LINE             EXTI_1
  104. #define TAMPER_KEY_EXTI_PORT_SOURCE      EXTI_SOURCE_GPIOE
  105. #define TAMPER_KEY_EXTI_PIN_SOURCE       EXTI_SOURCE_PIN1
  106. #define TAMPER_KEY_EXTI_IRQn             EXTI1_IRQn

  107. /* wakeup push-button */
  108. #define WAKEUP_KEY_PIN                   GPIO_PIN_0
  109. #define WAKEUP_KEY_GPIO_PORT             GPIOA
  110. #define WAKEUP_KEY_GPIO_CLK              RCU_GPIOA
  111. #define WAKEUP_KEY_EXTI_LINE             EXTI_0
  112. #define WAKEUP_KEY_EXTI_PORT_SOURCE      EXTI_SOURCE_GPIOA
  113. #define WAKEUP_KEY_EXTI_PIN_SOURCE       EXTI_SOURCE_PIN0
  114. #define WAKEUP_KEY_EXTI_IRQn             EXTI0_IRQn  

  115. /* user push-button */
  116. // #define USER_KEY_PIN                     GPIO_PIN_5
  117. // #define USER_KEY_GPIO_PORT               GPIOC
  118. // #define USER_KEY_GPIO_CLK                RCU_GPIOC
  119. // #define USER_KEY_EXTI_LINE               EXTI_5
  120. // #define USER_KEY_EXTI_PORT_SOURCE        EXTI_SOURCE_GPIOC
  121. // #define USER_KEY_EXTI_PIN_SOURCE         EXTI_SOURCE_PIN5
  122. // #define USER_KEY_EXTI_IRQn               EXTI5_9_IRQn
  123. #define USER_KEY_PIN                     GPIO_PIN_0
  124. #define USER_KEY_GPIO_PORT               GPIOE
  125. #define USER_KEY_GPIO_CLK                RCU_GPIOE
  126. #define USER_KEY_EXTI_LINE               EXTI_0
  127. #define USER_KEY_EXTI_PORT_SOURCE        EXTI_SOURCE_GPIOE
  128. #define USER_KEY_EXTI_PIN_SOURCE         EXTI_SOURCE_PIN0
  129. #define USER_KEY_EXTI_IRQn               EXTI0_IRQn

  130. /* function declarations */
  131. /* configures led GPIO */
  132. void gd_eval_led_init(led_typedef_enum lednum);
  133. /* turn on selected led */
  134. void gd_eval_led_on(led_typedef_enum lednum);
  135. /* turn off selected led */
  136. void gd_eval_led_off(led_typedef_enum lednum);
  137. /* toggle the selected led */
  138. void gd_eval_led_toggle(led_typedef_enum lednum);
  139. /* configure key */
  140. void gd_eval_key_init(key_typedef_enum key_num, keymode_typedef_enum key_mode);
  141. /* return the selected button state */
  142. uint8_t gd_eval_key_state_get(key_typedef_enum button);
  143. /* configure COM port */
  144. void gd_eval_com_init(uint32_t com);


  145. #ifdef cplusplus
  146. }
  147. #endif

  148. #endif /* GD32F4XX_EVAL_H */
复制代码
简单来说,就是按键改到了PA0、PA1、PE0;LED改到了PB4、PD7、PB3,分别对应LED4、LED5、LED6,并将原有LED1到LED3也分别与LED4、LED5、LED6对应。EVAL_COM1改到USART2、PD8、PD9。并多加了一条宏定义“#define EVAL_COM1_IRQn    USART2_IRQn”,这个以后在做UART中断时能用到。

修改gd32f4xx_eval.c文件中相应LED、按键、串口相关函数。
/*!
    \file  gd32f4xx_eval.c
    \brief firmware functions to manage leds, keys, COM ports
*/

/*
    Copyright (C) 2016 GigaDevice

    2016-08-15, V1.0.0, firmware for GD32F4xx
*/

#include "gd32f4xx_eval.h"
#include "gd32f4xx_usart.h"

/* private variables */
static uint32_t GPIO_PORT[LEDn] = {LED1_GPIO_PORT, LED2_GPIO_PORT,
                                                                                                                                         LED3_GPIO_PORT, LED4_GPIO_PORT,
                                   LED5_GPIO_PORT, LED6_GPIO_PORT};
static uint32_t GPIO_PIN[LEDn] = {LED1_PIN, LED2_PIN, LED3_PIN, LED4_PIN, LED5_PIN, LED6_PIN};

static rcu_periph_enum COM_CLK[COMn] = {EVAL_COM1_CLK};
static uint32_t COM_TX_PIN[COMn] = {EVAL_COM1_TX_PIN};
static uint32_t COM_RX_PIN[COMn] = {EVAL_COM1_RX_PIN};

static rcu_periph_enum GPIO_CLK[LEDn] = {LED1_GPIO_CLK, LED2_GPIO_CLK,
                                         LED3_GPIO_CLK, LED4_GPIO_CLK,
                                                                                                                                                                 LED5_GPIO_CLK, LED6_GPIO_CLK};

static uint32_t KEY_PORT[KEYn] = {WAKEUP_KEY_GPIO_PORT,
                                  TAMPER_KEY_GPIO_PORT,
                                  USER_KEY_GPIO_PORT};
static uint32_t KEY_PIN[KEYn] = {WAKEUP_KEY_PIN, TAMPER_KEY_PIN,USER_KEY_PIN};
static rcu_periph_enum KEY_CLK[KEYn] = {WAKEUP_KEY_GPIO_CLK,
                                        TAMPER_KEY_GPIO_CLK,
                                        USER_KEY_GPIO_CLK};
static exti_line_enum KEY_EXTI_LINE[KEYn] = {WAKEUP_KEY_EXTI_LINE,
                                             TAMPER_KEY_EXTI_LINE,
                                             USER_KEY_EXTI_LINE};
static uint8_t KEY_PORT_SOURCE[KEYn] = {WAKEUP_KEY_EXTI_PORT_SOURCE,
                                        TAMPER_KEY_EXTI_PORT_SOURCE,
                                        USER_KEY_EXTI_PORT_SOURCE};
static uint8_t KEY_PIN_SOURCE[KEYn] = {WAKEUP_KEY_EXTI_PIN_SOURCE,
                                       TAMPER_KEY_EXTI_PIN_SOURCE,
                                       USER_KEY_EXTI_PIN_SOURCE};
static uint8_t KEY_IRQn[KEYn] = {WAKEUP_KEY_EXTI_IRQn,
                                 TAMPER_KEY_EXTI_IRQn,
                                 USER_KEY_EXTI_IRQn};

/*!
    \brief      configure led GPIO
    \param[in]  lednum: specify the Led to be configured
      \arg        LED1
      \arg        LED2
      \arg        LED3
      \arg        LED4
    \param[out] none
    \retval     none
*/
void  gd_eval_led_init (led_typedef_enum lednum)
{
    /* enable the led clock */
    rcu_periph_clock_enable(GPIO_CLK[lednum]);
    /* configure led GPIO port */
    gpio_mode_set(GPIO_PORT[lednum], GPIO_MODE_OUTPUT, GPIO_PUPD_NONE,GPIO_PIN[lednum]);
    gpio_output_options_set(GPIO_PORT[lednum], GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN[lednum]);

    GPIO_BC(GPIO_PORT[lednum]) = GPIO_PIN[lednum];
}

/*!
    \brief      turn on selected led
    \param[in]  lednum: specify the Led to be turned on
      \arg        LED1
      \arg        LED2
      \arg        LED3
      \arg        LED4
    \param[out] none
    \retval     none
*/
void gd_eval_led_on(led_typedef_enum lednum)
{
    GPIO_BOP(GPIO_PORT[lednum]) = GPIO_PIN[lednum];
}

/*!
    \brief      turn off selected led
    \param[in]  lednum: specify the Led to be turned off
      \arg        LED1
      \arg        LED2
      \arg        LED3
      \arg        LED4
    \param[out] none
    \retval     none
*/
void gd_eval_led_off(led_typedef_enum lednum)
{
    GPIO_BC(GPIO_PORT[lednum]) = GPIO_PIN[lednum];
}

/*!
    \brief      toggle selected led
    \param[in]  lednum: specify the Led to be toggled
      \arg        LED1
      \arg        LED2
      \arg        LED3
      \arg        LED4
    \param[out] none
    \retval     none
*/
void gd_eval_led_toggle(led_typedef_enum lednum)
{
    GPIO_TG(GPIO_PORT[lednum]) = GPIO_PIN[lednum];
}

/*!
    \brief      configure key
    \param[in]  key_num: specify the key to be configured
      \arg        KEY_TAMPER: tamper key
      \arg        KEY_WAKEUP: wakeup key
      \arg        KEY_USER: user key
    \param[in]  key_mode: specify button mode
      \arg        KEY_MODE_GPIO: key will be used as simple IO
      \arg        KEY_MODE_EXTI: key will be connected to EXTI line with interrupt
    \param[out] none
    \retval     none
*/
void gd_eval_key_init(key_typedef_enum key_num, keymode_typedef_enum key_mode)
{
    /* enable the key clock */
    rcu_periph_clock_enable(KEY_CLK[key_num]);
    rcu_periph_clock_enable(RCU_SYSCFG);

    /* configure button pin as input */
    gpio_mode_set(KEY_PORT[key_num], GPIO_MODE_INPUT, GPIO_PUPD_NONE,KEY_PIN[key_num]);

    if (key_mode == KEY_MODE_EXTI) {
        /* enable and set key EXTI interrupt to the lowest priority */
        nvic_irq_enable(KEY_IRQn[key_num], 2U, 0U);

        /* connect key EXTI line to key GPIO pin */
        syscfg_exti_line_config(KEY_PORT_SOURCE[key_num], KEY_PIN_SOURCE[key_num]);

        /* configure key EXTI line */
        exti_init(KEY_EXTI_LINE[key_num], EXTI_INTERRUPT, EXTI_TRIG_FALLING);
        exti_interrupt_flag_clear(KEY_EXTI_LINE[key_num]);
    }
}

/*!
    \brief      return the selected button state
    \param[in]  button: specify the button to be checked
      \arg        KEY_TAMPER: tamper key
      \arg        KEY_WAKEUP: wakeup key
      \arg        KEY_USER: user key
    \param[out] none
    \retval     the button GPIO pin value
*/
uint8_t gd_eval_key_state_get(key_typedef_enum button)
{
    return gpio_input_bit_get(KEY_PORT[button], KEY_PIN[button]);
}

/*!
    \brief      configure COM port
    \param[in]  COM: COM on the board
      \arg        EVAL_COM1: COM1 on the board
    \param[out] none
    \retval     none
*/
void gd_eval_com_init(uint32_t com)
{
    /* enable GPIO clock */
    uint32_t COM_ID;
    if(EVAL_COM1 == com)
    {
        //COM_ID = 0U;
                                COM_ID = 0U;
    }

    rcu_periph_clock_enable( EVAL_COM_GPIO_CLK);

    /* enable USART clock */
    rcu_periph_clock_enable(COM_CLK[COM_ID]);

    /* connect port to USARTx_Tx */
    gpio_af_set(EVAL_COM_GPIO_PORT, EVAL_COM_AF, COM_TX_PIN[COM_ID]);

    /* connect port to USARTx_Rx */
    gpio_af_set(EVAL_COM_GPIO_PORT, EVAL_COM_AF, COM_RX_PIN[COM_ID]);

    /* configure USART Tx as alternate function push-pull */
    gpio_mode_set(EVAL_COM_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP,COM_TX_PIN[COM_ID]);
    gpio_output_options_set(EVAL_COM_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,COM_TX_PIN[COM_ID]);

    /* configure USART Rx as alternate function push-pull */
    gpio_mode_set(EVAL_COM_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP,COM_RX_PIN[COM_ID]);
    gpio_output_options_set(EVAL_COM_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,COM_RX_PIN[COM_ID]);

    /* USART configure */
    usart_deinit(com);
    usart_baudrate_set(com,115200U);
                /*
    usart_receive_config(USART0, USART_RECEIVE_ENABLE);
    usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);
    usart_enable(USART0);
                */
                usart_receive_config(EVAL_COM1, USART_RECEIVE_ENABLE);
    usart_transmit_config(EVAL_COM1, USART_TRANSMIT_ENABLE);
    usart_enable(EVAL_COM1);
}

main.c文件中main()函数修改。有要是LED和按键的修改。
/*!
    \brief      main function
    \param[in]  none
    \param[out] none
    \retval     none
*/
int main(void)
{
    can0_receive_flag = RESET;
    can1_receive_flag = RESET;
    can0_error_flag = RESET;
    can1_error_flag = RESET;
   
    /* configure GPIO */
    can_gpio_config();
   
    /* configure NVIC */
    nvic_config();
   
    /* configure USART */
    gd_eval_com_init(EVAL_COM1);
   
    /* configure Wakeup key or Tamper key */
    gd_eval_key_init(KEY_WAKEUP, KEY_MODE_GPIO);
    gd_eval_key_init(KEY_TAMPER, KEY_MODE_GPIO);
   
    printf("\r\nGD32F4xx dual CAN test, please press Wakeup key or Tamper key to start communication!\r\n");
    /* configure leds */
    led_config();
//     gd_eval_led_off(LED1);
//     gd_eval_led_off(LED2);
//     gd_eval_led_off(LED3);
    gd_eval_led_off(LED4);
                gd_eval_led_off(LED5);
                gd_eval_led_off(LED6);
   
    /* initialize CAN and filter */
    can_config(can_init_parameter, can_filter_parameter);
    /* enable can receive FIFO0 not empty interrupt */
    can_interrupt_enable(CAN0, CAN_INTEN_RFNEIE0);
    can_interrupt_enable(CAN1, CAN_INTEN_RFNEIE0);
   
    /* initialize transmit message */
    transmit_message.tx_sfid = 0x300>>1;
    transmit_message.tx_efid = 0x00;
    transmit_message.tx_ft = CAN_FT_DATA;
    transmit_message.tx_ff = CAN_FF_STANDARD;
    transmit_message.tx_dlen = 2;

    while(1){
        /* test whether the Tamper key is pressed */
        if(0 == gd_eval_key_state_get(KEY_TAMPER)){
            transmit_message.tx_data[0] = 0x55;
            transmit_message.tx_data[1] = 0xAA;
            printf("\r\n can0 transmit data:%x,%x", transmit_message.tx_data[0], transmit_message.tx_data[1]);
            /* transmit message */
            can_message_transmit(CAN0, &transmit_message);
            /* waiting for the Tamper key up */
            while(0 == gd_eval_key_state_get(KEY_TAMPER));
        }
        /* test whether the Wakeup key is pressed */
        if(0 == gd_eval_key_state_get(KEY_WAKEUP)){
            transmit_message.tx_data[0] = 0xAA;
            transmit_message.tx_data[1] = 0x55;
            printf("\r\n can1 transmit data:%x,%x", transmit_message.tx_data[0], transmit_message.tx_data[1]);
            /* transmit message */
            can_message_transmit(CAN1, &transmit_message);
            /* waiting for the Wakeup key up */
            while(0 == gd_eval_key_state_get(KEY_WAKEUP));
        }
        /* CAN0 receive data correctly, the received data is printed */
        if(SET == can0_receive_flag){
            can0_receive_flag = RESET;
            printf("\r\n can0 receive data:%x,%x", receive_message.rx_data[0], receive_message.rx_data[1]);
            gd_eval_led_toggle(LED6);
        }
        /* CAN1 receive data correctly, the received data is printed */
        if(SET == can1_receive_flag){
            can1_receive_flag = RESET;
            gd_eval_led_toggle(LED4);
            printf("\r\n can1 receive data:%x,%x", receive_message.rx_data[0], receive_message.rx_data[1]);
        }
        /* CAN0 error */
        if(SET == can0_error_flag){
            can0_error_flag = RESET;
            printf("\r\n can0 communication error");
        }
        /* CAN1 error */
        if(SET == can1_error_flag){
            can1_error_flag = RESET;
            printf("\r\n can1 communication error");
        }
    }
}

can_gpio_config()函数修改。CAN0、CAN1对应管脚修改,这是必须的,要不然实现起来会很难受。
CAN1的收发IO改到了PB12、PB13,CAN0改到了PD0、PD1。
/*!
    \brief      configure GPIO
    \param[in]  none
    \param[out] none
    \retval     none
*/
void can_gpio_config(void)
{
    /* enable CAN clock */
    rcu_periph_clock_enable(RCU_CAN0);
    rcu_periph_clock_enable(RCU_CAN1);
    rcu_periph_clock_enable(RCU_GPIOB);
                rcu_periph_clock_enable(RCU_GPIOD);
   
    /* configure CAN1 GPIO */
                /*
    gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_5);
    gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_5);
    gpio_af_set(GPIOB, GPIO_AF_9, GPIO_PIN_5);
   
    gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6);
    gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_6);
    gpio_af_set(GPIOB, GPIO_AF_9, GPIO_PIN_6);
                */
        
                gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_12);
    gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_12);
    gpio_af_set(GPIOB, GPIO_AF_9, GPIO_PIN_12);
   
    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_9, GPIO_PIN_13);
   
    /* configure CAN0 GPIO */
    /*
                gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_8);
    gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_8);
    gpio_af_set(GPIOB, GPIO_AF_9, GPIO_PIN_8);
   
    gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);
    gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_9);
    gpio_af_set(GPIOB, GPIO_AF_9, GPIO_PIN_9);
                */
                gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0);
    gpio_mode_set(GPIOD, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_0);
    gpio_af_set(GPIOD, GPIO_AF_9, GPIO_PIN_0);
   
    gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_1);
    gpio_mode_set(GPIOD, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_1);
    gpio_af_set(GPIOD, GPIO_AF_9, GPIO_PIN_1);
}

can_config()函数相应修改,主要是CAN波特率修改。第165、166行注释掉,改为如下代码。
    //can_parameter.time_segment_1 = CAN_BT_BS1_3TQ;
    //can_parameter.time_segment_2 = CAN_BT_BS2_2TQ;
                /*
                 *        CAN baudrate = 1 / ((1+CAN_BT_BS1_nTQ+CAN_BT_BS2_nTQ)* (BAUDPSC+1) * tpclk1)
                 */
                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 = 5;
    /* 500KBps */
#elif CAN_BAUDRATE == 500
    can_parameter.prescaler = 10;

要问为什么,因为原有pclk1的时钟为30MHz,改变时钟后变为了50MHz。因此原来的 CAN_BT_BS1_3TQ、CAN_BT_BS2_2TQ要改为CAN_BT_BS1_5TQ、CAN_BT_BS2_4TQ。要问为什么是5、4,请对照用户手册第739页内容。

波特率就是 1 / ((1 + CAN_BT_BS1_5TQ + CAN_BT_BS2_4TQ)时钟*can_parameter.prescaler),即50M / ((1+5+4)*5)= 1MHz波特率。

到此程序部分就完成了,完全编译,准备下载执行程序。程序中的printf将通过板载集成USB转TTL串口(usart2)打印信号到到上位机。

硬件连线如下图。

CAN0、CAN1外接两个TJA1050 CAN驱动器,两个驱动器CANL、CANH互连。(左下角OLED屏请忽略,之前测试屏接好线不想改动了,功能预留。)

下载程序,并全速跑。
上位机串口收到信息
“GD32F4xx dual CAN test, please press Wakeup key or Tamper key to start communication!”
按下按键B4、B2,串口将打印CAN通信收发状态信息。如下图。

结果显示,CAN0到CAN1传输数据正常,CAN1到CAN0传输数据正常。

出于好奇,给CAN0、CAN1的TTL端RX、TX挂上逻辑分析仪,看看波形。


注意右下角的协议分析数据,可以看到与我们的预期结果一致。


那么波特率呢,放大来测量一下。以数据0x55的波形为参考来测量,1us周期,波特率1M是没问题的。


到此CAN0、CAN1数据互传测试完成。

打包附上测试工程。权限问题,没办法上传超过10M的文件,分两个包上传。
GD32F4xx_Firmware_Library_V1.2-CAN.part1.rar (8 MB, 下载次数: 154, 售价: 1 与非币)

GD32F4xx_Firmware_Library_V1.2-CAN.part2.rar (7.92 MB, 下载次数: 159)


分享到:
回复

使用道具 举报

回答|共 1 个

倒序浏览

沙发

通宵敲代码

发表于 2022-10-28 17:11:17 | 只看该作者

压缩包中缺少core_cmFunc.h和core_cmInstr.h两个文件,可在最新的官方固件库中找到
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条