can的使用
cubemx配置
中断:
can.h
#ifndef __can_H
#define __can_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
extern CAN_HandleTypeDef hcan;
/* USER CODE BEGIN Private defines */
//发送接收状态宏定义
#define CAN_SEND_OK 0
#define CAN_SEND_FAIL 1
#define CAN_REC_OK 0
#define CAN_REC_FAIL 1
//定义结构体类型
typedef struct
{
uint32_t uiOperate_Mode; //操作模式
__IO uint8_t ucRec_Flag; //接收标志位
uint8_t ucSend_Buf[8]; //发送缓存
uint8_t ucRec_Buf[8]; //接收缓存
// void (*CAN_Init)(void);
// void (*CAN_Config)(void);
// uint8_t (*CAN_Send_Msg)(uint8_t* pSend_Buf,uint8_t LEN);
// uint8_t (*CAN_Rec_Msg)(uint8_t* pRec_Buf);
}CAN_Test_T;
/* USER CODE END Private defines */
void MX_CAN_Init(void);
/* USER CODE BEGIN Prototypes */
void CAN_Config(void);
uint8_t CAN_Send_Msg(uint8_t motor_id, uint8_t* pSend_Buf,uint8_t LEN);
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /*__ can_H */
can.c
CAN_Config()配置函数:
void CAN_Config(void)
{
//CAN过滤器参数配置
CAN_FilterTypeDef CAN_FilterTypeDefSture;
CAN_FilterTypeDefSture.FilterBank = 0; //配置过滤器0(F1共有14个,0-13)
CAN_FilterTypeDefSture.FilterScale = CAN_FILTERSCALE_16BIT; //配置为16位过滤器
CAN_FilterTypeDefSture.FilterMode = CAN_FILTERMODE_IDMASK; //屏蔽位模式
//ID号为0x00,屏蔽位为0x00,说明任何ID都接收
CAN_FilterTypeDefSture.FilterIdLow = 0x00; //FR1
CAN_FilterTypeDefSture.FilterMaskIdLow = 0x00;
CAN_FilterTypeDefSture.FilterIdHigh = 0x00; //FR2
CAN_FilterTypeDefSture.FilterMaskIdHigh = 0x00;
CAN_FilterTypeDefSture.FilterFIFOAssignment = CAN_FILTER_FIFO0; //过滤器0关联到FIFO0
CAN_FilterTypeDefSture.FilterActivation = ENABLE; //激活过滤器0
CAN_FilterTypeDefSture.SlaveStartFilterBank = 14;
//启动过滤器
if(HAL_CAN_ConfigFilter(&hcan,&CAN_FilterTypeDefSture) != HAL_OK)
{
// printf("CAN配置过滤器成功!");
}
//使能FIFO0接收到一个新报文中断,具体为FIFO0的挂起中断
if(HAL_CAN_ActivateNotification(&hcan,CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)
{
// printf("CAN使能FIFO0接收到一个新报文中断");
}
//启动CAN
if(HAL_CAN_Start(&hcan) != HAL_OK)
{
// printf("CAN启动失败!");
}
// printf("配置成功,CAN成功启动!\r\n");
}
CAN_Send_Msg()发送函数
uint8_t CAN_Send_Msg(uint8_t motor_id, uint8_t* pSend_Buf,uint8_t len)
{
uint32_t uiTxMailBox; //接收CAN发送数据成功时返回的邮箱号(0-2)
//定义CAN TX消息头参数
CAN_TxHeaderTypeDef CAN_TxHeaderTypeDefStrue =
{
motor_id, //标准标识符-11位
0x00, //拓展标识符-29位
CAN_ID_STD, //设置为标准格式
CAN_RTR_DATA, //设置为数据帧
len, //发送数据的长度 0 ~ 8
ENABLE //不使用捕获时间戳计数器
};
//将消息添加到第一个空闲的Tx邮箱并激活相应的传输要求
if(HAL_CAN_AddTxMessage(&hcan,&CAN_TxHeaderTypeDefStrue,pSend_Buf,&uiTxMailBox) != HAL_OK)
{
return CAN_SEND_FAIL;
}
//发送成功
return CAN_SEND_OK;
}
HAL_CAN_RxFifo0MsgPendingCallback接收回调函数
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan_)
{
//定义CAN Rx消息头参数
CAN_RxHeaderTypeDef CAN_RxHeaderTypeDefStrue;
//CAN接收消息
if(HAL_CAN_GetRxMessage(&hcan,CAN_RX_FIFO0, &CAN_RxHeaderTypeDefStrue, rx_data.data) == HAL_OK)
{
rx_data.id = CAN_RxHeaderTypeDefStrue.StdId;
rx_data.rx_flag = 1;
}
}
main函数
/* USER CODE BEGIN 2 */
CAN_Config(); //can 配置
/*...*/
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
if (rx_data.rx_flag) //收到信息
{
/*...*/
rx_data.rx_flag = 0;
}
}
typedef struct
{
uint8_t data[8];
uint8_t len;
uint32_t id;
uint8_t rx_flag;
} CanData_TypeDef;