STM32CubeMX学习--(4)CAN使用

CUBE配置

CAN参数配置

  • 配置引脚PD0 PD1为CAN功能。
  • 在Connectivity->CAN1中勾选Master Mode。
  • 在ParameterSettings中配置:
    在这里插入图片描述
  • NVIC Settings中勾选RX0中断
  • 在NVIC中配置CAN1中断组为2 2在这里插入图片描述
  • 点击生成代码

修改代码

  • 添加bsp_can.c文件,代码如下:
#include "bsp_can.h" 
#include "main.h"

#define CAN1FIFO CAN_RX_FIFO0
#define CAN1FIF1 CAN_RX_FIFO1
CAN_TxHeaderTypeDef TxMeg;
CAN_RxHeaderTypeDef RxMeg;

void bsp_can_init(CAN_HandleTypeDef *hcan)
{
    uint16_t std_id;
    uint32_t ext_id=0x1800F001;
    uint32_t mask;

    CAN_FilterTypeDef  sFilterConfig;
    HAL_StatusTypeDef  HAL_Status;
    if(hcan->Instance == CAN1)
    {
        sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; //工作在标识符屏蔽位模式
        sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;//滤波器位宽为单个32位
 
        sFilterConfig.FilterIdHigh =0X0000;
        sFilterConfig.FilterIdLow =0X0000;
        //过滤屏蔽码
        sFilterConfig.FilterMaskIdHigh = 0X0000;
        sFilterConfig.FilterMaskIdLow = 0X0000;

        sFilterConfig.FilterFIFOAssignment=CAN_FilterFIFO0;
        sFilterConfig.FilterBank=0x00;
        sFilterConfig.SlaveStartFilterBank=0x14;
        sFilterConfig.FilterActivation=ENABLE;
        HAL_Status = HAL_CAN_ConfigFilter(hcan, &sFilterConfig);
        HAL_Status = HAL_CAN_Start(hcan); //开启CAN
        if(HAL_Status != HAL_OK)
        {
//            PRINTF("开启CAN失败\r\n");
        }
        HAL_Status = HAL_CAN_ActivateNotification(hcan,CAN_IT_RX_FIFO0_MSG_PENDING);
    }
}


void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)  //接收回调函数
{
    uint8_t  recvData[8],j;
    HAL_StatusTypeDef  HAL_Status;
    if(hcan->Instance == CAN1)
    {
        HAL_Status = HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &RxMeg,  recvData);
        if ( HAL_Status == HAL_OK)                                                    //在这里接收数据
        {
			/*
					接受回调函数
						
			*/
        }
    }
}

extern __IO uint32_t uwTick;
void CanDelay(uint16_t cnt)
{
	uint32_t curCnt=uwTick;
	while(uwTick>=curCnt && (uwTick-curCnt)/2>cnt)
	{
		
	}
}
//发送数据函数
uint8_t CANx_SendNormalData(CAN_HandleTypeDef *hcanX, uint16_t ID, uint8_t *pData, uint16_t Len)
{
    HAL_StatusTypeDef   HAL_RetVal;
    uint16_t SendTimes, SendCNT = 0;
    uint8_t  FreeTxNum = 0;
    TxMeg.StdId = ID;
    if(!hcanX || ! pData || !Len)  return 1;
    SendTimes = Len / 8 + (Len % 8 ? 1 : 0);
    FreeTxNum = HAL_CAN_GetTxMailboxesFreeLevel(hcanX);
    TxMeg.DLC = 8;
    while(SendTimes--)
    {
        if(0 == SendTimes)
        {
            if(Len % 8)
				TxMeg.DLC = Len % 8;
        }
		FreeTxNum = HAL_CAN_GetTxMailboxesFreeLevel(hcanX);
        while(0 == FreeTxNum)
        {
			CanDelay(1);
            FreeTxNum = HAL_CAN_GetTxMailboxesFreeLevel(hcanX);
			if(0 == FreeTxNum)
			{
//				PRINTF("?");
				return 2;
			}
        }
        //HAL_Delay(1);   //没有延时很有可能会发送失败 
		CanDelay(1);		
		HAL_RetVal = HAL_CAN_AddTxMessage(hcanX, &TxMeg, pData + SendCNT, (uint32_t *)CAN_TX_MAILBOX0);
        if(HAL_RetVal != HAL_OK)
        {
            return 2;
        }
        SendCNT += 8;
    }
    return 0;
}

  • 使用发送函数发送数据
	 CANx_SendNormalData(&hcan1, 0x01, buf, 8); 
发布了10 篇原创文章 · 获赞 2 · 访问量 315

猜你喜欢

转载自blog.csdn.net/weixin_43482414/article/details/103974900