toofree 发表于 2017-6-18 23:35:03

GD32F450 双路CAN数据互传测试

本帖最后由 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、按键、串口相关宏定义及参数。/*!
    \filegd32f4xx_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、按键、串口相关函数。
/*!
    \filegd32f4xx_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 = {LED1_GPIO_PORT, LED2_GPIO_PORT,
                                                                                                                                       LED3_GPIO_PORT, LED4_GPIO_PORT,
                                 LED5_GPIO_PORT, LED6_GPIO_PORT};
static uint32_t GPIO_PIN = {LED1_PIN, LED2_PIN, LED3_PIN, LED4_PIN, LED5_PIN, LED6_PIN};

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

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

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

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

    GPIO_BC(GPIO_PORT) = GPIO_PIN;
}

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

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

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

/*!
    \brief      configure key
    \paramkey_num: specify the key to be configured
      \arg      KEY_TAMPER: tamper key
      \arg      KEY_WAKEUP: wakeup key
      \arg      KEY_USER: user key
    \paramkey_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 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);
    rcu_periph_clock_enable(RCU_SYSCFG);

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

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

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

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

/*!
    \brief      return the selected button state
    \parambutton: specify the button to be checked
      \arg      KEY_TAMPER: tamper key
      \arg      KEY_WAKEUP: wakeup key
      \arg      KEY_USER: user key
    \param 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, KEY_PIN);
}

/*!
    \brief      configure COM port
    \paramCOM: COM on the board
      \arg      EVAL_COM1: COM1 on the board
    \param 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);

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

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

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

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

    /* 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
    \paramnone
    \param 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 = 0x55;
            transmit_message.tx_data = 0xAA;
            printf("\r\n can0 transmit data:%x,%x", transmit_message.tx_data, transmit_message.tx_data);
            /* 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 = 0xAA;
            transmit_message.tx_data = 0x55;
            printf("\r\n can1 transmit data:%x,%x", transmit_message.tx_data, transmit_message.tx_data);
            /* 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, receive_message.rx_data);
            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, receive_message.rx_data);
      }
      /* 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
    \paramnone
    \param 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的文件,分两个包上传。



通宵敲代码 发表于 2022-10-28 17:11:17

压缩包中缺少core_cmFunc.h和core_cmInstr.h两个文件,可在最新的官方固件库中找到
页: [1]
查看完整版本: GD32F450 双路CAN数据互传测试