TA的每日心情  | 开心 10 小时前 | 
|---|
 
  签到天数: 4271 天 连续签到: 13 天 [LV.Master]伴坛终老 
司徒 
 
 
	- 积分
 - 49059
 
 
      
  
 
 | 
 
 
 本帖最后由 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、按键、串口相关宏定义及参数。- /*!
 
 -     \file  gd32f4xx_eval.h
 
 -     \brief definitions for GD32f4XX_EVAL's leds, keys and COM ports hardware resources
 
 - */
 
  
- /*
 
 -     Copyright (C) 2016 GigaDevice
 
  
-     2016-08-15, V1.0.0, firmware for GD32F4xx
 
 - */
 
  
- #ifndef GD32F4XX_EVAL_H
 
 - #define GD32F4XX_EVAL_H
 
  
- #ifdef cplusplus
 
 -  extern "C" {
 
 - #endif
 
  
- #include "gd32f4xx.h"
 
 -      
 
 - /* exported types */
 
 - typedef enum 
 
 - {
 
 -     LED1 = 0,
 
 -     LED2 = 1,
 
 -     LED3 = 2,
 
 -     LED4 = 3,
 
 -     LED5 = 4,
 
 -     LED6 = 5
 
 - } led_typedef_enum;
 
  
- typedef enum 
 
 - {
 
 -     KEY_WAKEUP = 0,
 
 -     KEY_TAMPER = 1,
 
 -     KEY_USER = 2
 
 - } key_typedef_enum;
 
  
- typedef enum 
 
 - {
 
 -     KEY_MODE_GPIO = 0,
 
 -     KEY_MODE_EXTI = 1
 
 - } keymode_typedef_enum;
 
  
- /* eval board low layer led */
 
 - #define LEDn                             6U        //4U
 
  
- // #define LED1_PIN                         GPIO_PIN_6
 
 - // #define LED1_GPIO_PORT                   GPIOC
 
 - // #define LED1_GPIO_CLK                    RCU_GPIOC
 
  
- //   
 
 - // #define LED2_PIN                         GPIO_PIN_7
 
 - // #define LED2_GPIO_PORT                   GPIOC
 
 - // #define LED2_GPIO_CLK                    RCU_GPIOC
 
 - //   
 
 - // #define LED3_PIN                         GPIO_PIN_8
 
 - // #define LED3_GPIO_PORT                   GPIOC
 
 - // #define LED3_GPIO_CLK                    RCU_GPIOC
 
  
- #define LED1_PIN                         GPIO_PIN_4                // ?LED4
 
 - #define LED1_GPIO_PORT                   GPIOB
 
 - #define LED1_GPIO_CLK                    RCU_GPIOB
 
  
- #define LED2_PIN                         GPIO_PIN_7                // ?LED5
 
 - #define LED2_GPIO_PORT                   GPIOD
 
 - #define LED2_GPIO_CLK                    RCU_GPIOD
 
  
- #define LED3_PIN                         GPIO_PIN_3                // ?LED6
 
 - #define LED3_GPIO_PORT                   GPIOB
 
 - #define LED3_GPIO_CLK                    RCU_GPIOB
 
  
- //   
 
 - // #define LED4_PIN                         GPIO_PIN_9
 
 - // #define LED4_GPIO_PORT                   GPIOC
 
 - // #define LED4_GPIO_CLK                    RCU_GPIOC
 
  
- #define LED4_PIN                         GPIO_PIN_4
 
 - #define LED4_GPIO_PORT                   GPIOB
 
 - #define LED4_GPIO_CLK                    RCU_GPIOB
 
  
- #define LED5_PIN                         GPIO_PIN_7
 
 - #define LED5_GPIO_PORT                   GPIOD
 
 - #define LED5_GPIO_CLK                    RCU_GPIOD
 
  
- #define LED6_PIN                         GPIO_PIN_3
 
 - #define LED6_GPIO_PORT                   GPIOB
 
 - #define LED6_GPIO_CLK                    RCU_GPIOB
 
  
- /*
 
 - #define COMn                             1U
 
 - #define EVAL_COM1                        USART0
 
 - #define EVAL_COM1_CLK                    RCU_USART0
 
  
- #define EVAL_COM1_TX_PIN                 GPIO_PIN_9
 
 - #define EVAL_COM1_RX_PIN                 GPIO_PIN_10
 
  
- #define EVAL_COM_GPIO_PORT               GPIOA
 
 - #define EVAL_COM_GPIO_CLK                RCU_GPIOA
 
 - #define EVAL_COM_AF                      GPIO_AF_7
 
 - */
 
  
- #define COMn                             1U
 
 - #define EVAL_COM1                        USART2
 
 - #define EVAL_COM1_CLK                    RCU_USART2
 
  
- #define EVAL_COM1_TX_PIN                 GPIO_PIN_8
 
 - #define EVAL_COM1_RX_PIN                 GPIO_PIN_9
 
  
- #define EVAL_COM_GPIO_PORT               GPIOD
 
 - #define EVAL_COM_GPIO_CLK                RCU_GPIOD
 
 - #define EVAL_COM_AF                      GPIO_AF_7
 
  
- #define EVAL_COM1_IRQn                                                                    USART2_IRQn
 
  
- #define KEYn                             3U
 
  
- /* tamper push-button */
 
 - // #define TAMPER_KEY_PIN                   GPIO_PIN_13
 
 - // #define TAMPER_KEY_GPIO_PORT             GPIOC
 
 - // #define TAMPER_KEY_GPIO_CLK              RCU_GPIOC
 
 - // #define TAMPER_KEY_EXTI_LINE             EXTI_13
 
 - // #define TAMPER_KEY_EXTI_PORT_SOURCE      EXTI_SOURCE_GPIOC
 
 - // #define TAMPER_KEY_EXTI_PIN_SOURCE       EXTI_SOURCE_PIN13
 
 - // #define TAMPER_KEY_EXTI_IRQn             EXTI10_15_IRQn
 
 - #define TAMPER_KEY_PIN                   GPIO_PIN_1
 
 - #define TAMPER_KEY_GPIO_PORT             GPIOE
 
 - #define TAMPER_KEY_GPIO_CLK              RCU_GPIOE
 
 - #define TAMPER_KEY_EXTI_LINE             EXTI_1
 
 - #define TAMPER_KEY_EXTI_PORT_SOURCE      EXTI_SOURCE_GPIOE
 
 - #define TAMPER_KEY_EXTI_PIN_SOURCE       EXTI_SOURCE_PIN1
 
 - #define TAMPER_KEY_EXTI_IRQn             EXTI1_IRQn
 
  
- /* wakeup push-button */
 
 - #define WAKEUP_KEY_PIN                   GPIO_PIN_0
 
 - #define WAKEUP_KEY_GPIO_PORT             GPIOA
 
 - #define WAKEUP_KEY_GPIO_CLK              RCU_GPIOA
 
 - #define WAKEUP_KEY_EXTI_LINE             EXTI_0
 
 - #define WAKEUP_KEY_EXTI_PORT_SOURCE      EXTI_SOURCE_GPIOA
 
 - #define WAKEUP_KEY_EXTI_PIN_SOURCE       EXTI_SOURCE_PIN0
 
 - #define WAKEUP_KEY_EXTI_IRQn             EXTI0_IRQn  
 
  
- /* user push-button */
 
 - // #define USER_KEY_PIN                     GPIO_PIN_5
 
 - // #define USER_KEY_GPIO_PORT               GPIOC
 
 - // #define USER_KEY_GPIO_CLK                RCU_GPIOC
 
 - // #define USER_KEY_EXTI_LINE               EXTI_5
 
 - // #define USER_KEY_EXTI_PORT_SOURCE        EXTI_SOURCE_GPIOC
 
 - // #define USER_KEY_EXTI_PIN_SOURCE         EXTI_SOURCE_PIN5
 
 - // #define USER_KEY_EXTI_IRQn               EXTI5_9_IRQn
 
 - #define USER_KEY_PIN                     GPIO_PIN_0
 
 - #define USER_KEY_GPIO_PORT               GPIOE
 
 - #define USER_KEY_GPIO_CLK                RCU_GPIOE
 
 - #define USER_KEY_EXTI_LINE               EXTI_0
 
 - #define USER_KEY_EXTI_PORT_SOURCE        EXTI_SOURCE_GPIOE
 
 - #define USER_KEY_EXTI_PIN_SOURCE         EXTI_SOURCE_PIN0
 
 - #define USER_KEY_EXTI_IRQn               EXTI0_IRQn
 
  
- /* function declarations */
 
 - /* configures led GPIO */
 
 - void gd_eval_led_init(led_typedef_enum lednum);
 
 - /* turn on selected led */
 
 - void gd_eval_led_on(led_typedef_enum lednum);
 
 - /* turn off selected led */
 
 - void gd_eval_led_off(led_typedef_enum lednum);
 
 - /* toggle the selected led */
 
 - void gd_eval_led_toggle(led_typedef_enum lednum);
 
 - /* configure key */
 
 - void gd_eval_key_init(key_typedef_enum key_num, keymode_typedef_enum key_mode);
 
 - /* return the selected button state */
 
 - uint8_t gd_eval_key_state_get(key_typedef_enum button);
 
 - /* configure COM port */
 
 - void gd_eval_com_init(uint32_t com);
 
  
 
- #ifdef cplusplus
 
 - }
 
 - #endif
 
  
- #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的文件,分两个包上传。 
 
 
 
 |   
 
  
  
  
 
 
 |