.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]是我自己定义的结构体,别完全照抄,自己定个数组啥的 替代一下。