TA的每日心情 | 开心 昨天 00:01 |
---|
签到天数: 3934 天 连续签到: 5 天 [LV.Master]伴坛终老
|
本帖最后由 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的文件,分两个包上传。
GD32F4xx_Firmware_Library_V1.2-CAN.part1.rar
(8 MB, 下载次数: 152, 售价: 1 与非币)
|
|