STM32实战总结:HAL之CAN

can通信基础知识参考:

 

嵌入式常见接口协议总结_路溪非溪的博客-CSDN博客

STM32的can直接查阅数据手册。  

更多解析参考:STM32之CAN通信_韦东山的博客-CSDN博客_stm32can

关键代码

/* Includes ------------------------------------------------------------------*/
#include "MyApplication.h"

/* Private define-------------------------------------------------------------*/

/* Private variables----------------------------------------------------------*/

/* Private function prototypes------------------------------------------------*/ 
static void CAN_Init(void);   //初始化
static void CAN_Config(void); //配置
static uint8_t CAN_Send_Msg(uint8_t*, uint8_t);  //发送信息
static uint8_t CAN_Rec_Msg(uint8_t*);            //接收信息	

/* Public variables-----------------------------------------------------------*/
CAN_TEST_t CAN_TEST = 
{
	CAN_MODE_LOOPBACK,
	
	CAN_Init,
	CAN_Config,
	
	{0},
	{0},
	
	CAN_Send_Msg,
	CAN_Rec_Msg,
	FALSE
};
/* Private function prototypes------------------------------------------------*/      


/*
	* @name   CAN_Init
	* @brief  CAN初始化
	* @param  None
	* @retval None      
*/
static void CAN_Init()
{
	
}

/*
	* @name   CAN_Config
	* @brief  CAN配置
	* @param  None
	* @retval None      
*/
static void CAN_Config()
{
	CAN_FilterTypeDef CAN_Filter;
	
	//设定CAN过滤器参数
	CAN_Filter.FilterBank   = 0;  //配置过滤器0(STM32F1共14个,0-13)
	CAN_Filter.FilterScale  = CAN_FILTERSCALE_16BIT; //16位过滤器
	CAN_Filter.FilterMode   = CAN_FILTERMODE_IDMASK; //标识符屏蔽模式
	CAN_Filter.FilterIdLow      = 0x00; //FR1
	CAN_Filter.FilterMaskIdLow  = 0x00;
	CAN_Filter.FilterIdHigh     = 0x00; //FR2
	CAN_Filter.FilterMaskIdHigh = 0x00;
	CAN_Filter.FilterFIFOAssignment = CAN_RX_FIFO0; //过滤器0关联到FIFO0
	CAN_Filter.FilterActivation = ENABLE;           //激活过滤器0
	CAN_Filter.SlaveStartFilterBank = 14;           
	
	//配置过滤器
	if(HAL_CAN_ConfigFilter(&hcan, &CAN_Filter) != HAL_OK)
	{
		printf("CAN配置函数:配置过滤器!");
		System.Error_Handler();
	}
	
	//使能FIFO0接收到一个新报文中断
	if(HAL_CAN_ActivateNotification(&hcan,CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)
	{
		printf("CAN配置函数:使能FIFO0接收到一个新报文中断!");
		System.Error_Handler();
	}
	
	//启动CAN
	if(HAL_CAN_Start(&hcan) != HAL_OK)
	{
		printf("CAN配置函数错误:CAN启动失败!");
		System.Error_Handler();
	}
	
	printf("配置成功,并成功启动CAN\r\n");
}

/*
	* @name   CAN_Send_Msg
	* @brief  CAN发送信息
	* @param  pSend_Buf     -> 发送缓存指针
  *         LEN           -> 发送长度
	* @retval CAN_Send_ok   -> 发送成功
            CAN_Send_fail -> 发送失败
*/
static uint8_t CAN_Send_Msg(uint8_t* pSend_Buf, uint8_t LEN)
{
	uint8_t                 i = 0;
	static uint8_t ucTestData = 0;
	
	uint32_t TxMailBox; //接收CAN发送成功时返回的邮箱号(0-2)	
	//定义CAN Tx消息头参数
	CAN_TxHeaderTypeDef  CAN_TxHeader = 
	{
		0x88,         //标准标识符 - 11位  
		0x00,         //扩展标识符 - 29位
		CAN_ID_STD,   //使标准帧
		CAN_RTR_DATA, //数据帧
		8,            //发送8位数据 - 范围0-8
		DISABLE      
	};
	
	if(CAN_TEST.Operate_Mode == CAN_MODE_LOOPBACK)
		printf("CAN工作在环回模式 -> 只需1块实战板即可测试\r\n");
	else
		printf("CAN工作在正常模式 -> 至少2块实战板方可测试\r\n");
	
	//设定待发送数据
	printf("CAN发送报文,数据如下:");
	for(i=0;i<8;i++)
	{
		printf("0x%.2x,",ucTestData);
		CAN_TEST.Send_Buf[i] = ucTestData++;
	}
	printf("\r\n");
	
	//将消息添加到第一个免费的Tx邮箱并激活相应的传输要求
	if(HAL_CAN_AddTxMessage(&hcan, &CAN_TxHeader, pSend_Buf, &TxMailBox) != HAL_OK)
	{
		return CAN_Send_fail;
	}
	
	//通过检查空闲邮箱个数确认是否发送完成
	Timer6.usDelay_Timer = 0;
	do
  {
		//超时处理
		if(Timer6.usDelay_Timer >= TIMER6_1S)
		{
			printf("CAN发送超时\r\n");
			return CAN_Send_fail;
		}
	}
	while(HAL_CAN_GetTxMailboxesFreeLevel(&hcan) != 3);
	
	//发送成功
	return CAN_Send_ok;
}

/*
	* @name   CAN_Rec_Msg
	* @brief  CAN接收信息
	* @param  pRec_Buf     -> 接收缓存指针
	* @retval CAN_Rec_ok   -> 接收成功
            CAN_Rec_fail -> 接收失败    
*/
static uint8_t CAN_Rec_Msg(uint8_t* pRec_Buf)
{
	uint8_t i;
	
	printf("CAN接收到报文,数据如下:");
	for(i=0;i<8;i++)
		printf("0x%.2x,",*(pRec_Buf+i));
	printf("\r\n");
	
	return CAN_Rec_ok;
}
/********************************************************
  End Of File
********************************************************/

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值