829|4

441

帖子

3

TA的资源

纯净的硅(高级)

楼主
 

【兆易GD32H759I-EVAL】 CAN2通信收发测试 [复制链接]

  本帖最后由 TL-LED 于 2024-6-1 17:38 编辑

 

测试开发板上的CAN2接口收发测试。

 

一、硬件部分

 

1.1、芯片手册部分

 

1.1.1、芯片外设框图

CH32H759内部有3个CAN通信接口

 

1.1.2、CAN简介


    CAN(Controller Area Network)总线是一种可以在无主机情况下实现微处理器和设备之间相互通信的总线标准。 CAN 网络接口支持 CAN 总线协议 2.0A/B、 ISO11898-1:2015 规范和
BOSCH CAN-FD 规范。CAN 总线控制器集成了可灵活配置的邮箱系统用于 CAN 帧的发送和接收。邮箱系统包含一组邮箱,用于存储控制数据,时间戳,消息标识符和消息数据,最大支持 32 个邮箱。可将邮箱配置为接收 FIFO,接收 FIFO 具有标识符过滤的功能,可最大支持 104 个扩展标识符的过滤,或者 208 个标准标识符的过滤,或者 416 个对标识符部分 8 位的过滤,最多有 32 个标识符过滤表元素可通过接收 FIFO/邮箱私有过滤寄存器进行配置。
注: GD32H737xx 系列不支持 CAN FD 帧。

 

1.1.3、主要特征
 支持CAN总线协议2.0A/B;
 遵循ISO 11898-1:2015规范;
 支持CAN FD帧,最大64字节数据,通信波特率最大为8 Mbit/s;
 支持CAN常规帧,最大8字节数据,通信波特率最大为1 Mbit/s;
 支持发送和接收时间戳,基于16位内部计数器;
 支持传输延迟补偿,用于CAN FD帧的高速率数据阶段;
 中断可配置屏蔽;
 支持4种通信模式:正常模式,暂停模式,回环静默模式,和监听模式;
 支持2种省电模式: CAN_Disable模式,和虚拟联网模式;
 支持2种从虚拟联网模式唤醒的方式:唤醒匹配事件,和唤醒超时事件;
 最大32个邮箱,此时每个邮箱都配置为8字节数据长度,可灵活配置为发送或接收邮箱;
 支持通过一个特殊帧同步全局网络时间。
发送
 支持发送中止;
 发送邮箱状态可查看;
 发送帧消息的CRC校验;
 支持发送优先级:最小邮箱号优先,或最高优先级优先。
接收
 接收私有过滤寄存器用于每个接收邮箱或者接收FIFO;
 接收邮箱公有过滤寄存器用于接收邮箱,接收FIFO公有过滤寄存器用于接收FIFO;
 支持接收优先级,可配置在匹配阶段的接收邮箱和接收FIFO的优先级;
 接收FIFO的标识符过滤功能支持最大104个扩展标识符的过滤,或者208个标准标识符的
过滤,或者416个对标识符部分8位的过滤;
 深度为6帧的接收FIFO,支持DMA功能

 

1.1.4、CAN模块结构框图

 

1.2、电路图部分

开发板上引出了CAN1和CAN2通道接口。

 

使用CAN1通道时,需要跳线来选择,JP53和JP61来选择CAN1。

 

CAN2不需要跳线,为了不影响LCD接口,下面使用CAN2接口测试

 

二、程序部分

 

2.1、can.c

#include "main.h"

can_mailbox_descriptor_struct transmit_message;
can_mailbox_descriptor_struct receive_message;
FlagStatus can2_receive_flag;

#define  BUFFER_SIZE    8U
const uint8_t tx_data[BUFFER_SIZE] = {0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8};
uint8_t rx_data[BUFFER_SIZE];

void can_gpio_config(void)
{
	/* configure CAN2 clock source */
	rcu_can_clock_config(IDX_CAN2, RCU_CANSRC_APB2_DIV2);
	/* enable CAN clock */
	rcu_periph_clock_enable(RCU_CAN2);
	/* enable CAN port clock */
	rcu_periph_clock_enable(RCU_GPIOD);
	rcu_periph_clock_enable(RCU_GPIOF);

	/* configure CAN2_RX GPIO */
	gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_12);
	gpio_mode_set(GPIOD, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_12);
	gpio_af_set(GPIOD, GPIO_AF_5, GPIO_PIN_12);
	/* configure CAN2_TX GPIO */
	gpio_output_options_set(GPIOF, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_7);
	gpio_mode_set(GPIOF, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_7);
	gpio_af_set(GPIOF, GPIO_AF_2, GPIO_PIN_7);
}

void can_config(void)
{
	can_parameter_struct can_parameter;

	/* initialize CAN register */
	can_deinit(CAN2);
	/* initialize CAN */
	can_struct_para_init(CAN_INIT_STRUCT, &can_parameter);

	/* initialize CAN parameters */
	can_parameter.internal_counter_source = CAN_TIMER_SOURCE_BIT_CLOCK;
	can_parameter.self_reception = DISABLE;
	can_parameter.mb_tx_order = CAN_TX_HIGH_PRIORITY_MB_FIRST;
	can_parameter.mb_tx_abort_enable = ENABLE;
	can_parameter.local_priority_enable = DISABLE;
	can_parameter.mb_rx_ide_rtr_type = CAN_IDE_RTR_FILTERED;
	can_parameter.mb_remote_frame = CAN_STORE_REMOTE_REQUEST_FRAME;
	can_parameter.rx_private_filter_queue_enable = DISABLE;
	can_parameter.edge_filter_enable = DISABLE;
	can_parameter.protocol_exception_enable = DISABLE;
	can_parameter.rx_filter_order = CAN_RX_FILTER_ORDER_MAILBOX_FIRST;
	can_parameter.memory_size = CAN_MEMSIZE_32_UNIT;
	/* filter configuration */
	can_parameter.mb_public_filter = 0U;
	/* baud rate 1Mbps, sample point at 80% */
	can_parameter.resync_jump_width = 1U;
	can_parameter.prop_time_segment = 2U;
	can_parameter.time_segment_1 = 5U;
	can_parameter.time_segment_2 = 2U;
	can_parameter.prescaler = 15U;

	/* initialize CAN */
	can_init(CAN2, &can_parameter);

	/* configure CAN1 NVIC */
	nvic_irq_enable(CAN2_Message_IRQn, 0U, 0U);

	/* enable CAN MB0 interrupt */
	can_interrupt_enable(CAN2, CAN_INT_MB0);

	can_operation_mode_enter(CAN2, CAN_NORMAL_MODE);
}

void init_can(void)
{
	can_struct_para_init(CAN_MDSC_STRUCT, &transmit_message);
	can_struct_para_init(CAN_MDSC_STRUCT, &receive_message);
	can_gpio_config();
	can_config();
	
	/* initialize transmit message */
	transmit_message.rtr = 0U;
	transmit_message.ide = 0U;
	transmit_message.code = CAN_MB_TX_STATUS_DATA;
	transmit_message.brs = 0U;
	transmit_message.fdf = 0U;
	transmit_message.prio = 0U;
	transmit_message.data_bytes = BUFFER_SIZE;
	/* tx message content */
	transmit_message.data = (uint32_t *)(tx_data);
	transmit_message.id = 0x55U;

	receive_message.rtr = 0U;
	receive_message.ide = 0U;
	receive_message.code = CAN_MB_RX_STATUS_EMPTY;
	/* rx mailbox */
	receive_message.id = 0x55U;
	receive_message.data = (uint32_t *)(rx_data);
	can_mailbox_config(CAN2, 0U, &receive_message);
	
}


void can2_rx_hdl(void)
{
	uint8_t i = 0U;
	if(SET == can2_receive_flag) 
	{
		can2_receive_flag = RESET;

		/* check the receive message */
		can_mailbox_receive_data_read(CAN2, 0U, &receive_message);
		printf("\r\nCAN2 receive data: \r\n");
		
		printf("CAN2 ID : %x\r\n",receive_message.id);
		printf("CAN2 RXDAT : ");
		for(i = 0U; i < receive_message.data_bytes; i++) 
		{
				printf("%02x ", rx_data[i]);
		}
		printf("\r\n");
		
		can2_txbuf(receive_message.id+1,receive_message.ide, receive_message.data_bytes, rx_data);
	}
}
void can2_txbuf(uint32_t id, uint8_t ide, uint8_t dlc, uint8_t *txbuf)
{
	uint8_t i=0;
	transmit_message.data = (uint32_t *)(txbuf);
	transmit_message.id = id;
	transmit_message.dlc = dlc;
	transmit_message.ide = ide;
	
	can_mailbox_config(CAN2, 1U, &transmit_message);

	printf("\r\nCAN2 transmit data: \r\n");
	printf("CAN2 ID : %x\r\n",id);
	printf("CAN2 TXDAT : ");
	for(i = 0U; i < transmit_message.data_bytes; i++) {
			printf("%02x ", txbuf[i]);
	}
	printf("\r\n");
}


2.2、can.h

#ifndef _CAN_H
#define _CAN_H

void init_can(void);
void can2_txbuf(uint32_t id, uint8_t ide, uint8_t dlc, uint8_t *txbuf);

void can2_rx_hdl(void);

#endif

 

2.3、main.c

#include "main.h"

void cache_enable(void);

int main(void)
{
	uint8_t x=0;
	uint32_t sd=0;
	uint32_t yd=0;
	
	uint8_t tx_dat[8];
	cache_enable();
	systick_config();
	init_usart(115200);
	init_can();


	while(1)
	{
		can2_rx_hdl();
	}
}

void cache_enable(void)
{
    /* enable i-cache */
    SCB_EnableICache();

    /* enable d-cache */
    SCB_EnableDCache();
}

 

三、测试结果

 

CAN2接收到标准帧或扩展帧后,将接收到的数据,以ID+1的地址发送接收到的数据。

 

 

四、附件

 

程序代码:

gd32h759_prj_can.rar (807.03 KB, 下载次数: 4)

 

最新回复

楼主是用CAN分析仪来做的测试,文章非常优秀!   详情 回复 发表于 2024-6-2 08:31
点赞 关注
 
 

回复
举报

6562

帖子

9

TA的资源

版主

沙发
 

有两个CAN?能够实现自发自收?要不就得搞个CAN接收器才行

点评

两路CAN,可以实现双路收发通信。  详情 回复 发表于 2024-6-1 18:44
个人签名

在爱好的道路上不断前进,在生活的迷雾中播撒光引

 
 
 

回复

441

帖子

3

TA的资源

纯净的硅(高级)

板凳
 
秦天qintian0303 发表于 2024-6-1 18:34 有两个CAN?能够实现自发自收?要不就得搞个CAN接收器才行

两路CAN,可以实现双路收发通信。

 
 
 

回复

755

帖子

5

TA的资源

纯净的硅(高级)

4
 

楼主分享的技术知识非常详细,通俗易懂,值得收藏学习,感谢分享

 
 
 

回复

7063

帖子

11

TA的资源

版主

5
 

楼主是用CAN分析仪来做的测试,文章非常优秀!

 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/6 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表