1、硬件-芯片使用:STM32F103Cx系列
2、MX部分配置--配置波特率为500k---500000bit/s
开启接受中断
3、代码生成后,增加底层代码,完善CAN通讯
3.0、先声明此类结构体句柄
CAN_TxHeaderTypeDef TXHeader;
CAN_RxHeaderTypeDef RXHeader;
3.1、开启CAN过滤器,系统上电后前先运行一次
//CAN过滤器,不开启过滤器CAN不能应用
void CANfilter(void)
{
CAN_FilterTypeDef sFilterConfig;
sFilterConfig.FilterActivation = ENABLE;//打开过滤器
sFilterConfig.FilterBank = 0;//过滤器0 这里可设0-13
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;//采用掩码模式
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;//采用32位掩码模式
sFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0;//采用FIFO0
sFilterConfig.FilterIdHigh = 0x0000; //设置过滤器ID高16位
sFilterConfig.FilterIdLow = 0x0000;//设置过滤器ID低16位
sFilterConfig.FilterMaskIdHigh = 0x0000;//设置过滤器掩码高16位
sFilterConfig.FilterMaskIdLow = 0x0000;//设置过滤器掩码低16位
if(HAL_CAN_ConfigFilter(&hcan,&sFilterConfig) != HAL_OK)//初始化过滤器
{
Error_Handler();
}
if(HAL_CAN_Start(&hcan) != HAL_OK)//打开can
{
Error_Handler();
}
if(HAL_CAN_ActivateNotification(&hcan,CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)//开启接受邮箱0挂起中断
{
Error_Handler();
}
}
3.2、创建CAN中断回调函数,接受到CAN信息后在中断调至此函数中运行
//CAN中断回调函数
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)//接受邮箱0挂起中断回调函数
{
unsigned char RXmessage[8] ;
if(hcan->Instance==CAN1)//CAN1的信息
{
HAL_CAN_GetRxMessage(hcan,CAN_FILTER_FIFO0,&RXHeader,RXmessage);//获取数据
if(RXHeader.StdId==0x123)//CAN的地址
{
//RXmessage[0];
}//CAN地址0x123的读取结束
}//CAN1的信息结束
}
3.3、创建简易CAN发送机制
//CAN数据发送,ID是CAN地址,TX是要发数据的8个数数组,IDE是扩展帧标志
//注意STM32F103只有3个邮箱,所以一次只能发送3个CAN消息
//如果数据多,3个一组错开发送时间
void CAN_send(unsigned int ID,unsigned char *TX,bool IDE)
{
unsigned int pTxMailbox = 0;
if(ID >= 0x7ff)//ID地址大于0x7ff为扩展帧
{
TXHeader.ExtId = ID;
TXHeader.IDE=CAN_ID_EXT;
}
else//ID小于0x7ff为标准帧
{
TXHeader.StdId = ID;
if(IDE==0)
TXHeader.IDE=CAN_ID_STD;
else
TXHeader.IDE=CAN_ID_EXT;
}
TXHeader.DLC=8;
TXHeader.RTR=CAN_RTR_DATA;
TXHeader.TransmitGlobalTime = DISABLE;
HAL_CAN_AddTxMessage(&hcan,&TXHeader,TX,&pTxMailbox);
}
4、整体函数
4.1、添加的c文件
/***********************
*时间:2022.10.12
*CAN通讯函数
***********************/
#include "BasCAN.h"
CAN_TxHeaderTypeDef TXHeader;
CAN_RxHeaderTypeDef RXHeader;
//CAN过滤器,不开启过滤器CAN不能应用
void CANfilter(void)
{
CAN_FilterTypeDef sFilterConfig;
sFilterConfig.FilterActivation = ENABLE;//打开过滤器
sFilterConfig.FilterBank = 0;//过滤器0 这里可设0-13
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;//采用掩码模式
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;//采用32位掩码模式
sFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0;//采用FIFO0
sFilterConfig.FilterIdHigh = 0x0000; //设置过滤器ID高16位
sFilterConfig.FilterIdLow = 0x0000;//设置过滤器ID低16位
sFilterConfig.FilterMaskIdHigh = 0x0000;//设置过滤器掩码高16位
sFilterConfig.FilterMaskIdLow = 0x0000;//设置过滤器掩码低16位
if(HAL_CAN_ConfigFilter(&hcan,&sFilterConfig) != HAL_OK)//初始化过滤器
{
Error_Handler();
}
if(HAL_CAN_Start(&hcan) != HAL_OK)//打开can
{
Error_Handler();
}
if(HAL_CAN_ActivateNotification(&hcan,CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)//开启接受邮箱0挂起中断
{
Error_Handler();
}
}
//MX生成的配置都没有,启动开始代码,要添加上去
void HAL_Can_Startup(void)
{
CANfilter();//CAN过滤器,和CAN启动
}
//CAN数据发送,ID是CAN地址,TX是要发数据的8个数数组,IDE是扩展帧标志
//注意STM32F103只有3个邮箱,所以一次只能发送3个CAN消息
//如果数据多,3个一组错开发送时间
void CAN_send(unsigned int ID,unsigned char *TX,bool IDE)
{
unsigned int pTxMailbox = 0;
if(ID >= 0x7ff)//ID地址大于0x7ff为扩展帧
{
TXHeader.ExtId = ID;
TXHeader.IDE=CAN_ID_EXT;
}
else//ID小于0x7ff为标准帧
{
TXHeader.StdId = ID;
if(IDE==0)
TXHeader.IDE=CAN_ID_STD;
else
TXHeader.IDE=CAN_ID_EXT;
}
TXHeader.DLC=8;
TXHeader.RTR=CAN_RTR_DATA;
TXHeader.TransmitGlobalTime = DISABLE;
HAL_CAN_AddTxMessage(&hcan,&TXHeader,TX,&pTxMailbox);
}
//CAN数据发送函数,最多3个一组错开时间
void SendDataCan(void)
{
unsigned char TXmessage[8] ;
TXmessage[0] = 1;
TXmessage[1] = 2;
TXmessage[2] = 3;
TXmessage[3] = 4;
TXmessage[4] = 5;
TXmessage[5] = 6;
TXmessage[6] = 7;
TXmessage[7] = 8;
CAN_send(0X245,TXmessage,0);//发送ID为0x245的数据
}
//CAN中断回调函数
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)//接受邮箱0挂起中断回调函数
{
unsigned char RXmessage[8] ;
if(hcan->Instance==CAN1)//CAN1的信息
{
HAL_CAN_GetRxMessage(hcan,CAN_FILTER_FIFO0,&RXHeader,RXmessage);//获取数据
if(RXHeader.StdId==0x123)//CAN的地址
{
//RXmessage[0];
}//CAN地址0x123的读取结束
}//CAN1的信息结束
}
4.2、c文件的头文件(.h)
/***********************
*时间:2022.10.12
*CAN通讯函数
***********************/
#ifndef __BASCAN_H__
#define __BASCAN_H__
#include "task.h"
//CAN过滤器,不开启过滤器CAN不能应用
void CANfilter(void);
//MX生成的配置都没有,启动开始代码,要添加上去
void HAL_Can_Startup(void);
//CAN数据发送,ID是CAN地址,TX是要发数据的8个数数组,IDE是扩展帧标志
//注意STM32F103只有3个邮箱,所以一次只能发送3个CAN消息
//如果数据多,3个一组错开发送时间
void CAN_send(unsigned int ID,unsigned char *TX,bool IDE);
//CAN数据发送函数,最多3个一组错开时间
void SendDataCan(void);
#endif