兆易GD32F105双CAN通讯

.h文件

/************************************************************

* File Name:		Drvcan.h
* File Instruction: Can通信驱动头文件
* File User:		MXG
* File TIME:		2023-02-03
* File Version:		V1.0  
************************************************************/

#ifndef __DrvCan_H
#define __DrvCan_H


/************************define******************************/
#define CAN0_TX_GPIO_PORT   GPIOA        
#define CAN0_TX_GPIO_PIN    GPIO_PIN_12   

// PA10
#define CAN0_RX_GPIO_PORT   GPIOA        
#define CAN0_RX_GPIO_PIN    GPIO_PIN_11   

#define CAN1_TX_GPIO_PORT   GPIOB        
#define CAN1_TX_GPIO_PIN    GPIO_PIN_6   
// PA10
#define CAN1_RX_GPIO_PORT   GPIOB        
#define CAN1_RX_GPIO_PIN    GPIO_PIN_5   

#define	CAN0_Priority			0
#define	CAN0_SubPriority		1

#define	CAN1_Priority			0
#define	CAN1_SubPriority		1

/************************struct******************************/
typedef enum
{
	can_bps_100k,
	can_bps_125k,
	can_bps_200k,
	can_bps_250k,
	can_bps_400k,
	can_bps_500k,
	can_bps_1000k,
}CanBps;

typedef enum
{
	CANPort0,
	CANPort1,
	CANPortAll,
	
}CANPort;

extern can_receive_message_struct can0_rxmes;
extern can_receive_message_struct can1_rxmes;

/************************function******************************/
void DrvCan_Init(CANPort Port,CanBps bps);
INT8U DrvCan_SendMsg(CANPort Port,INT8U slaver,INT8U cmd,INT8U motor_num,INT8U* msg,INT8U len);

void DrvCAN0_send(uint16_t ID, uint8_t *buf, uint16_t len);
void DrvCAN1_send(uint16_t ID, uint8_t *buf, uint16_t len);


#endif


.c文件

/************************************************************

* File Name:		DrvCan.c
* File Instruction:	该文件为Can驱动文件
* File User:		MXG
* File TIME:		20231-02-03
* File Version:		V1.0  
************************************************************/
#include "include.h"
const INT32U	CANDef[CANPortAll] = {CAN0,CAN1};
const INT32U	CANTxPort[CANPortAll] = {CAN0_TX_GPIO_PORT,CAN1_TX_GPIO_PORT};
const INT32U	CANRxPort[CANPortAll] = {CAN0_RX_GPIO_PORT,CAN1_RX_GPIO_PORT};
const INT32U 	CANTxPin[CANPortAll] = {CAN0_TX_GPIO_PIN,CAN1_TX_GPIO_PIN};
const INT32U 	CANRxPin[CANPortAll] = {CAN0_RX_GPIO_PIN,CAN1_RX_GPIO_PIN};

can_receive_message_struct can0_rxmes;
can_receive_message_struct can1_rxmes;

/*
*********************************************************************************************************
*	函 数 名: DrvCan_Init
*	功能说明: Can初始化
*	形    参: 无
*	返 回 值: 无 波特率=Fpclk1/((tbs1+1+tbs2+1+1)*brp);54M/((8+9+1)*6)=500Kbps
* 	创 建 人: MXG
*	创建时间: 20230203
*********************************************************************************************************
*/
void DrvCan_Init(CANPort Port,CanBps bps)
{
	INT8U tbs1,tbs2;
	INT16U brp;
	can_parameter_struct can_parameter;
    can_filter_parameter_struct can_filter;
	gpio_init(CANTxPort[Port],GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,CANTxPin[Port]);
	gpio_init(CANRxPort[Port],GPIO_MODE_IPU  ,GPIO_OSPEED_50MHZ,CANRxPin[Port]);
	
	switch( Port)
	{
		case CANPort0:
			can_filter.filter_number = 0;
			nvic_irq_enable(CAN0_RX0_IRQn, CAN0_Priority, CAN0_SubPriority);
			break;
		case CANPort1:
			gpio_pin_remap_config(GPIO_CAN1_REMAP,ENABLE);  
			can_filter.filter_number = 14;
			nvic_irq_enable(CAN1_RX0_IRQn, CAN1_Priority, CAN1_SubPriority);
			break;
		default:
			break;
	}
	can_deinit(CANDef[Port]);	
    /* initialize CAN */
    can_parameter.time_triggered = DISABLE;
    can_parameter.auto_bus_off_recovery = DISABLE;
    can_parameter.auto_wake_up = DISABLE;
    can_parameter.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;
	switch(bps)
	{
		case can_bps_100k:
			tbs2 = CAN_BT_BS2_8TQ;
			tbs1 = CAN_BT_BS1_11TQ;
			brp = 27;
			break;
		case can_bps_125k:
			tbs2 = CAN_BT_BS2_3TQ;
			tbs1 = CAN_BT_BS1_5TQ;
			brp = 48;
			break;
		case can_bps_200k:
			tbs2 = CAN_BT_BS2_3TQ;
			tbs1 = CAN_BT_BS1_5TQ;
			brp = 30;
			break;
		case can_bps_250k:
			tbs2 = CAN_BT_BS2_3TQ;
			tbs1 = CAN_BT_BS1_5TQ;
			brp = 24;
			break;
		case can_bps_400k:
			tbs2 = CAN_BT_BS2_3TQ;
			tbs1 = CAN_BT_BS1_5TQ;
			brp = 15;
			break;
		case can_bps_500k:
			tbs2 = CAN_BT_BS2_8TQ;
			tbs1 = CAN_BT_BS1_9TQ;
			brp = 6;
			break;
		case can_bps_1000k:
			tbs2 = CAN_BT_BS2_3TQ;
			tbs1 = CAN_BT_BS1_5TQ;
			brp = 6;
			break;
		default:
			tbs2 = CAN_BT_BS2_3TQ;
			tbs1 = CAN_BT_BS1_5TQ;
			brp = 6;
			break;
	}
	
    can_parameter.time_segment_1 = tbs1;
    can_parameter.time_segment_2 = tbs2;
    /* baudrate 1Mbps  = 54M/ 6 / (5+3+1) */
    can_parameter.prescaler = brp;

	can_init(CANDef[Port], &can_parameter);
	
    /* 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_init(&can_filter);
	can_interrupt_enable(CANDef[Port], CAN_INT_RFNE0);
}	
/*
*********************************************************************************************************
*	函 数 名: CAN0_RX0_IRQHandler
*	功能说明: Can中断接收
*	形    参: 无
*	返 回 值: 无 
* 	创 建 人: MXG
*	创建时间: 20230203
*********************************************************************************************************
*/
void CAN0_RX0_IRQHandler(void)
{
	memset(&can0_rxmes,0,sizeof(can0_rxmes)); 
	can_message_receive(CAN0, CAN_FIFO0, &can0_rxmes);
	DevProtocol_CAN(can0_rxmes);
}
/*
*********************************************************************************************************
*	函 数 名: CAN0_RX0_IRQHandler
*	功能说明: Can中断接收
*	形    参: 无
*	返 回 值: 无 
* 	创 建 人: MXG
*	创建时间: 20230203
*********************************************************************************************************
*/
void CAN1_RX0_IRQHandler(void)
{
	memset(&can1_rxmes,0,sizeof(can1_rxmes)); 
	can_message_receive(CAN1, CAN_FIFO0, &can1_rxmes);
	DevProtocol_CAN(can1_rxmes);
}

/*
*********************************************************************************************************
*	函 数 名: DrvCAN0_send
*	功能说明: CAN0发送
*	形    参: 无
*	返 回 值: 无
*	创 建 人: MXG
*	创建时间: 20230214
*********************************************************************************************************
*/
void DrvCAN0_send(uint16_t ID, uint8_t *buf, uint16_t len){
	INT8U mbox;
	INT16U i=0;
	can_trasnmit_message_struct transmit_message;
	taskENTER_CRITICAL();		// 进入临界区
	transmit_message.tx_sfid = 0x141 + ID;
	transmit_message.tx_ft = CAN_FT_DATA;
	transmit_message.tx_ff = CAN_FF_STANDARD;
	transmit_message.tx_dlen = len;
	for( i=0;i<len; i++)
	{
		transmit_message.tx_data[i] = buf[i];
	}
	mbox = can_message_transmit(CAN0, &transmit_message);
	i= 0;
	while((can_transmit_states(CAN0, mbox)==CAN_TRANSMIT_FAILED)&&(i<0XFFF))i++;	//等待发送结束
	if(i>=0XFFF) 
	{
		taskEXIT_CRITICAL();
	}
	taskEXIT_CRITICAL();
}

/*
*********************************************************************************************************
*	函 数 名: DrvCAN1_send
*	功能说明: CAN1发送
*	形    参: 无
*	返 回 值: 无
*	创 建 人: MXG
*	创建时间: 20230214
*********************************************************************************************************
*/
void DrvCAN1_send(uint16_t ID, uint8_t *buf, uint16_t len){
can_trasnmit_message_struct transmit_message;
	
	uint8_t i;
	transmit_message.tx_sfid = 0x141 + ID;
	transmit_message.tx_ft = CAN_FT_DATA;
	transmit_message.tx_ff = CAN_FF_STANDARD;
	transmit_message.tx_dlen = len;
	for( i=0;i<len; i++)
	{
		transmit_message.tx_data[i] = buf[i];
	}
	can_message_transmit(CAN1, &transmit_message);
}

CAN初始的时候如果遇到时钟问题,参考我另一篇文章,因为懒,所以放在了main函数里面一起声明了。

……

算了,知道你们也懒,贴出来,根据自己的需要放进函数初始之前就可以了。

	rcu_periph_clock_enable(RCU_TIMER1);	
	rcu_periph_clock_enable(RCU_GPIOA);
	rcu_periph_clock_enable(RCU_GPIOB);
	rcu_periph_clock_enable(RCU_GPIOC);
	rcu_periph_clock_enable(RCU_GPIOD);	
	rcu_periph_clock_enable(RCU_USART0);
	rcu_periph_clock_enable(RCU_UART3);
	rcu_periph_clock_enable(RCU_CAN0);
	rcu_periph_clock_enable(RCU_CAN1);	
	rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV12);	
	rcu_periph_clock_enable(RCU_AF);
	DrvCan_Init(CANPort0,can_bps_1000k);
	DrvCan_Init(CANPort1,can_bps_1000k);

CAN发送调用:

DrvCAN0_send(ID,(uint8_t *)&LK_tech_send.ID[id].LK_Speed,8);	
DrvCAN1_send(ID,(uint8_t *)&LK_tech_send.ID[id].LK_Speed,8);	

LK_tech_send.ID[id]是我自己定义的结构体,别完全照抄,自己定个数组啥的 替代一下。

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值