FDCAN初始化:
__HAL_RCC_FDCAN_CLK_ENABLE(); //使能 FDCAN 时钟
__HAL_RCC_GPIOB_CLK_ENABLE(); //开启 GPIOB 时钟
//FDCAN1 时钟源配置为 PLL1Q
FDCAN1_PeriphClk.PeriphClockSelection = RCC_PERIPHCLK_FDCAN;
FDCAN1_PeriphClk.FdcanClockSelection = RCC_FDCANCLKSOURCE_PLL;
HAL_RCCEx_PeriphCLKConfig(&FDCAN1_PeriphClk);
GPIO_Initure.Pin = GPIO_PIN_8|GPIO_PIN_9; //PB8,9
GPIO_Initure.Mode = GPIO_MODE_AF_PP; //推挽复用
GPIO_Initure.Pull = GPIO_PULLUP; //上拉
GPIO_Initure.Speed = GPIO_SPEED_FREQ_HIGH; //高速
GPIO_Initure.Alternate = GPIO_AF9_FDCAN1; //复用为 CAN1
HAL_GPIO_Init(GPIOB, &GPIO_Initure); //初始化
HAL_FDCAN_DeInit(&FDCAN1_Handler); //先清除以前的设置
FDCAN1_Handler.Instance = FDCAN1;
FDCAN1_Handler.Init.FrameFormat = FDCAN_FRAME_CLASSIC; //传统模式
FDCAN1_Handler.Init.Mode = FDCAN_MODE_NORMAL; //正常模式
FDCAN1_Handler.Init.AutoRetransmission = DISABLE; //关闭自动重传!
FDCAN1_Handler.Init.TransmitPause = DISABLE; //关闭传输暂停
FDCAN1_Handler.Init.ProtocolException = DISABLE; //关闭协议异常处理
FDCAN1_Handler.Init.NominalPrescaler = FDCAN_CLOCK_DIV10; //分频系数
FDCAN1_Handler.Init.NominalSyncJumpWidth= 0x08; //重新同步跳跃宽度
FDCAN1_Handler.Init.NominalTimeSeg1 = 0x1f; //tsg1 范围:2~256
FDCAN1_Handler.Init.NominalTimeSeg2 = 0x08; //tsg2 范围:2~128
FDCAN1_Handler.Init.MessageRAMOffset = 0; //信息 RAM 偏移
FDCAN1_Handler.Init.StdFiltersNbr = 1; //标准信息 ID 滤波器编号
FDCAN1_Handler.Init.ExtFiltersNbr = 0; //扩展信息 ID 滤波器编号
FDCAN1_Handler.Init.RxFifo0ElmtsNbr = 1; //接收 FIFO0 元素编号
FDCAN1_Handler.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_8; //接收 FIFO0 8 字节
FDCAN1_Handler.Init.RxBuffersNbr = 0; //接收缓冲编号
FDCAN1_Handler.Init.TxEventsNbr = 0; //发送事件编号
FDCAN1_Handler.Init.TxBuffersNbr = 1; //发送缓冲编号
FDCAN1_Handler.Init.TxFifoQueueElmtsNbr = 0; //发送 FIFO 序列元素编号
FDCAN1_Handler.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
FDCAN1_Handler.Init.TxElmtSize = FDCAN_DATA_BYTES_8; //发送大小:8 字节
if(HAL_FDCAN_Init(&FDCAN1_Handler) != HAL_OK) //初始化 FDCAN
{
while(1);
}
//设置滤波器
FDCAN1_RXFilter.IdType = FDCAN_EXTENDED_ID; //扩展 ID
FDCAN1_RXFilter.FilterIndex = 0; //滤波器索引
FDCAN1_RXFilter.FilterType = FDCAN_FILTER_MASK; //滤波器类型
FDCAN1_RXFilter.FilterConfig= FDCAN_FILTER_TO_RXFIFO0; //过滤器 0 关联到 FIFO0
FDCAN1_RXFilter.FilterID1 = 0x0000; //32 位 ID
FDCAN1_RXFilter.FilterID2 = 0x0000; //传统模式的话,这里是 32 位掩码
HAL_FDCAN_ConfigFilter(&FDCAN1_Handler,&FDCAN1_RXFilter); //滤波器初始化
HAL_FDCAN_ActivateNotification(&FDCAN1_Handler,FDCAN_IT_RX_FIFO0_NEW_MESSAGE,0);
HAL_FDCAN_Start(&FDCAN1_Handler); //开启 FDCAN
HAL_NVIC_SetPriority(FDCAN1_IT0_IRQn,1,2);
HAL_NVIC_EnableIRQ(FDCAN1_IT0_IRQn);
发送函数:
/*=============================================================================================
** @name : u8 BSPCANSendMsg(e_CANNUM canNum, t_CANMSG *msg)
** @Input : canNum:通道号 *msg:发送信息结构体
** @output : 发送结果:TRUE-成功 FALSE-失败
** @function : CAN发送信息(直接发送)
** @the notes : 用户调用(尽量少用,会丢帧)
**===========================================================================================*/
u8 BSPCANSendMsg(e_CANNUM canNum, t_CANMSG *msg)
{
FDCAN_TxHeaderTypeDef FDCAN_TxHeader;
u8 i = 0;
u8 TxData[8] = {0};
for(i = 0;i < 8; i++)
{
TxData = msg->Data;
}
FDCAN_TxHeader.Identifier = msg->ID; //32 位 ID
FDCAN_TxHeader.IdType = FDCAN_EXTENDED_ID; //扩展 ID
FDCAN_TxHeader.TxFrameType = FDCAN_DATA_FRAME; //数据帧
FDCAN_TxHeader.DataLength = FDCAN_DLC_BYTES_8; //数据长度
FDCAN_TxHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
FDCAN_TxHeader.BitRateSwitch = FDCAN_BRS_OFF; //关闭速率切换
FDCAN_TxHeader.FDFormat = FDCAN_CLASSIC_CAN; //传统的 CAN 模式
FDCAN_TxHeader.TxEventFifoControl = FDCAN_NO_TX_EVENTS; //无发送事件
FDCAN_TxHeader.MessageMarker = 0;
if(eCAN0 == canNum)
{
//HAL_FDCAN_AddMessageToTxFifoQ(&FDCAN1_Handler, &FDCAN_TxHeader, TxData);
HAL_FDCAN_AddMessageToTxBuffer(&FDCAN1_Handler, &FDCAN_TxHeader, TxData, FDCAN_TX_BUFFER0);
/* Send calibration confirmation message */
HAL_FDCAN_EnableTxBufferRequest(&FDCAN1_Handler, FDCAN_TX_BUFFER0);
}
else
{
HAL_FDCAN_AddMessageToTxFifoQ(&FDCAN2_Handler, &FDCAN_TxHeader, TxData);
}
return(TRUE);
}
连续发送16帧数据之后,不再发送,一直出现该EEOR里面
/* Check that the selected buffer has an allocated area into the RAM */
if (POSITION_VAL(BufferIndex) >= ((hfdcan->Instance->TXBC & FDCAN_TXBC_NDTB) >> FDCAN_TXBC_NDTB_Pos))
{
/* Update error code */
hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PARAM;
return HAL_ERROR;
}
问题已经找了好多天了,项目处于延迟状态,那位大神帮忙看看是什么问题,第一次用ST的单片机,没什么经验,求助各位同行了,谢谢
我的时钟初始化(16M的外置晶振)是这样的,也是用户的也是HAL的库
/* Configure the MPU attributes */
MPU_Config();
/* Enable the CPU Cache */
CPU_CACHE_Enable();
/* STM32H7xx HAL library initialization:
- Systick timer is configured by default as source of time base, but user
can eventually implement his proper time base source (a general purpose
timer for example or other time source), keeping in mind that Time base
duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and
handled in milliseconds basis.
- Set NVIC Group Priority to 4
- Low Level Initialization
*/
HAL_Init();
// /*!< Supply configuration update enable */
// HAL_PWREx_ConfigSupply(PWR_DIRECT_SMPS_SUPPLY);
//
// /* The voltage scaling allows optimizing the power consumption when the device is
// clocked below the maximum system frequency, to update the voltage scaling value
// regarding system frequency refer to product datasheet. */
// __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
//
// while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
/* Enable HSE Oscillator and activate PLL with HSE as source */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSIState = RCC_HSI_OFF;
RCC_OscInitStruct.CSIState = RCC_CSI_OFF;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 2;
RCC_OscInitStruct.PLL.PLLN = 50;
RCC_OscInitStruct.PLL.PLLFRACN = 0;
RCC_OscInitStruct.PLL.PLLP = 2;
RCC_OscInitStruct.PLL.PLLR = 2;
RCC_OscInitStruct.PLL.PLLQ = 10;
RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2;
ret = HAL_RCC_OscConfig(&RCC_OscInitStruct);
if(ret != HAL_OK)
{
while(1) { ; }
}
/* Select PLL as system clock source and configure bus clocks dividers */
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_D1PCLK1 | RCC_CLOCKTYPE_PCLK1 | \
RCC_CLOCKTYPE_PCLK2 | RCC_CLOCKTYPE_D3PCLK1);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
ret = HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4);
if(ret != HAL_OK)
{
while(1) { ; }
}
/*
Note : The activation of the I/O Compensation Cell is recommended with communication interfaces
(GPIO, SPI, FMC, QSPI ...) when operating at high frequencies(please refer to product datasheet)
The I/O Compensation Cell activation procedure requires :
- The activation of the CSI clock
- The activation of the SYSCFG clock
- Enabling the I/O Compensation Cell : setting bit[0] of register SYSCFG_CCCSR
*/
/*activate CSI clock mondatory for I/O Compensation Cell*/
__HAL_RCC_CSI_ENABLE() ;
/* Enable SYSCFG clock mondatory for I/O Compensation Cell */
__HAL_RCC_SYSCFG_CLK_ENABLE() ;
/* Enables the I/O Compensation Cell */
HAL_EnableCompensationCell();
SystemCoreClockUpdate();
|