GD32F4xx系列CAN通信收发配置

GD32F4xx系列CAN通信收发基础配置:
主要注意2点:
1、波特率的配置:
查找GD32F4xx的用户手册找到CAN外设对应的时钟:
这里可以看到GD32F4xx的时钟在APB1总线上在这里插入图片描述
在GD32F4xx的时钟树上找到APB1外设的时钟频率:在这里插入图片描述
根据GD32F4xx用户手册提供的波特率计算公式来进行CAN的初始化:
在这里插入图片描述
注意:如果不会计算也没关系,看主页上传的资源中有一个CAN波特率计算工具软件,只需要输入频率和波特率就能计算出BS1、BS2和BPR,并且能够计算出出错率和采样的成功率,能够打打提搞开发效率。
在这里插入图片描述
2、CAN通信的出错率:
在通信状态不稳定或者干扰比较大的情况下,CAN通信发送和接收可能出错,此时GD32F4xx会进行出错统计,当统计达到一定数量的时候,CAN功能会进入休眠状态,需要重新唤醒。在手册中能够看到:
在这里插入图片描述

1、在工程中添加gd32f4xx_can.c 和gd32f4xx_dbg.c 两个源文件以及头文件到工程中,如下图所示:在这里插入图片描述
为什么要添加gd32f4xx_dbg.c这个文件,原因是gd32f4xx_can.c文件中调用了调试需要两个函数,为了不修改gd官方提供的库函数我们就直接将两个文件一起添加到工程中。在这里插入图片描述
2、新建一个can.c和can.h文件添加到工程中。并进行can相关开发;
在这里插入图片描述

//can.c文件
/*
can通信初始化
*/
int32_t can_opt_init(void) 
{
	can_trasnmit_message_struct can_frame;
	can_parameter_struct can_parameter;
    can_filter_parameter_struct can_filter;
	can_receive_message_struct can_mes;

	rcu_periph_clock_enable(RCU_CAN0);//使能can时钟
	rcu_periph_clock_enable(RCU_GPIOA);//使能引脚时钟
	gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_11);
	gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_11);
	gpio_af_set(GPIOA,GPIO_AF_9,GPIO_PIN_11);
	gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_12);
	gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_12);
	gpio_af_set(GPIOA,GPIO_AF_9,GPIO_PIN_12);//can通信引脚配置
	nvic_irq_enable(CAN0_RX0_IRQn,1,0);//can中断配置
	/*can通信参数配置*/
	can_struct_para_init(CAN_INIT_STRUCT, &can_parameter);
	can_struct_para_init(CAN_FILTER_STRUCT, &can_filter);
	can_struct_para_init(CAN_RX_MESSAGE_STRUCT, &can_mes);
	can_struct_para_init(CAN_TX_MESSAGE_STRUCT, &can_frame);
    
    /* initialize CAN */
    can_parameter.time_triggered = DISABLE;
    can_parameter.auto_bus_off_recovery = DISABLE;
    can_parameter.auto_wake_up = DISABLE;
    can_parameter.no_auto_retrans = DISABLE;
    can_parameter.rec_fifo_overwrite = DISABLE;
    can_parameter.trans_fifo_order = DISABLE;
    can_parameter.working_mode = CAN_NORMAL_MODE;
    can_parameter.resync_jump_width = CAN_BT_SJW_1TQ;
    can_parameter.time_segment_1 = CAN_BT_BS1_8TQ;
    can_parameter.time_segment_2 = CAN_BT_BS2_1TQ;
can_parameter.prescaler = 20;//配置波特率默认250K
	if(SUCCESS !=can_init(CAN0,&can_parameter))//初始化can
	{
		return -1;
	}
	/* initialize filter */    
    can_filter.filter_mode = CAN_FILTERMODE_MASK;
    can_filter.filter_bits = CAN_FILTERBITS_32BIT;
    can_filter.filter_list_high = 0x0000;
    can_filter.filter_list_low = 0x0000;
    can_filter.filter_mask_high = 0x0000;
    can_filter.filter_mask_low = 0x0000;  
    can_filter.filter_fifo_number = CAN_FIFO0;
    can_filter.filter_enable = ENABLE;
	
	can_filter.filter_number = 0;
	can_filter_init(&can_filter);
	can_interrupt_enable(CAN0, CAN_INTEN_RFNEIE0);
	can_interrupt_enable(CAN0, CAN_INT_TME);//中断使能
	
    return 0;
}

/*
can 数据发送函数
*/
void can_opt_send(can_trasnmit_message_struct can_frame)
{
	can_message_transmit(CAN0,&can_frame);
}

/*
can 错误获取并进行错误清除
在CAN因出错次数过多导致进入休眠状态时可以进行CAN功能唤醒
*/
int32_t can_opt_error(void)
{
	if(	can_flag_get(CAN0, CAN_FLAG_MTE2) != RESET ||
		can_flag_get(CAN0, CAN_FLAG_MTE0) != RESET ||
		can_flag_get(CAN0, CAN_FLAG_MTE1) != RESET || 
		can_flag_get(CAN0, CAN_FLAG_PERR) != RESET ||
		can_flag_get(CAN0, CAN_FLAG_WERR) != RESET)
	{
		can_flag_clear(CAN0, CAN_FLAG_MTE0);
		can_flag_clear(CAN0, CAN_FLAG_MTE1);
		can_flag_clear(CAN0, CAN_FLAG_MTE2);
		can_flag_clear(CAN0, CAN_FLAG_PERR);
		can_flag_clear(CAN0, CAN_FLAG_WERR);
		can_wakeup(CAN0);
can_opt_init();
		return 1;
	}
	return 0;
}
/*
can 停止can功能
*/
void can_opt_stop(void)
{
	can_working_mode_set(CAN0,CAN_MODE_SLEEP);
}


//can.h 文件
#ifndef _CAN_H_ 
#define _CAN_H_

#include "gd32f4xx.h"
#include "gd32f4xx_can.h"
int32_t can_opt_init(void);
void can_opt_send(can_trasnmit_message_struct can_frame);
int32_t can_opt_error(void);
void can_opt_stop(void);
#endif


/*gd32f4xx_it.c文件需要增加CAN接收中断函数,这里只是简单的做数据接收并没有进行数据相关处理,到时候可以设置断点查看接收到的数据即可。*/
can_receive_message_struct can_mes;
void CAN0_RX0_IRQHandler(void)
{
	can_message_receive(CAN0, CAN_FIFO0, &can_mes); 
	if(can_mes.rx_efid == 0x18FFF605)
	{
		can_mes.rx_data[0] = 1;
	}
}

3、在main.c文件main函数中调用初始化以及数据发送;
在这里插入图片描述
4、连接好CAN通信盒和MCU,打开CAN调试工具。将代码编译下载到MCU并运行程序。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
5、设置CAN调试断点在can发送数据完成之后,并等待程序运行到断点处在这里插入图片描述
6.查看CAN调试工具,接收到MCU发送过来的CAN数据,并对比MCU发送过来的数据与接收数据是否一致在这里插入图片描述
在这里插入图片描述
通过对比可以发现数据发送基本无误。

7、使用CAN调试工具给MCU发送数据,并在CAN接收中断中设置断点查看接收数据是否正确。
在这里插入图片描述
在这里插入图片描述
通过对比可以发现CAN调试工具给MCU发送的数据与MCU接收到的数据一致,因此MCU的CAN接收与发送功能正常,代码可以使用。

  • 20
    点赞
  • 73
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 12
    评论
GD32F4 CAN配置包括以下几个步骤: 1. 配置波特率:根据GD32F4xx用户手册提供的波特率计算公式,计算出CAN的初始化参数,包括BS1、BS2和BPR。可以使用CAN波特率计算工具软件来简化计算过程。 2. 处理错误和休眠状态:在通信状态不稳定或干扰较大的情况下,CAN通信可能会出错。GD32F4xx会进行出错统计,当统计数量达到一定值时,CAN功能会进入休眠状态。需要重新唤醒CAN功能。 3. 在main.c文件的main函数中调用初始化函数以及数据发送函数。 4. 连接CAN通信盒和MCU,打开CAN调试工具。将代码编译下载到MCU并运行程序。 5. 设置CAN调试断点在数据发送完成之后,并等待程序运行到断点处。 6. 查看CAN调试工具,接收到MCU发送的CAN数据,并对比发送和接收的数据是否一致。 7. 使用CAN调试工具MCU发送数据,并在CAN接收中断中设置断点查看接收数据是否正确。 通过以上步骤,可以完成GD32F4的CAN配置,确保CAN接收和发送功能正常。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [GD32F4xx系列CAN通信收发配置](https://blog.csdn.net/weixin_43647919/article/details/127405968)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小吴同学啊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值