一、对于fdcan配置与使用记录
一、FDCAN配置
FDCAN设置:
hfdcan1.Init.FrameFormat = FDCAN_FRAME_FD_BRS;//FD模式
hfdcan1.Init.Mode = FDCAN_MODE_NORMAL;//普通模式
hfdcan1.Init.AutoRetransmission = DISABLE;//关闭自动重传,传统模式下关闭
hfdcan1.Init.TransmitPause = DISABLE; //关闭传输暂停
hfdcan1.Init.ProtocolException = ENABLE; //打开协议异常处理
hfdcan1.Init.NominalPrescaler = 3; //分频系数
hfdcan1.Init.NominalSyncJumpWidth = 1;//重新同步跳跃宽度
hfdcan1.Init.NominalTimeSeg1 = 29; //采样点之前标志时间段:2~256
hfdcan1.Init.NominalTimeSeg2 = 10; //采样点之后标志时间段:2~128
hfdcan1.Init.DataPrescaler = 3;//数据段预分频
hfdcan1.Init.DataSyncJumpWidth = 1;//数据位同步跳跃宽度
hfdcan1.Init.DataTimeSeg1 = 29; //采样点之前数据时间段
hfdcan1.Init.DataTimeSeg2 = 10; //采样点之后数据时间段
hfdcan1.Init.MessageRAMOffset = 0; //指定消息RAM起始地址
hfdcan1.Init.StdFiltersNbr = 1; //标准信息ID滤波器编号
hfdcan1.Init.ExtFiltersNbr = 0; //扩展信息ID滤波器编号
hfdcan1.Init.RxFifo0ElmtsNbr = 1; //接收FIFO0元素编号
hfdcan1.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_8;//接收FIFO0元素大小:8字节
hfdcan1.Init.RxFifo1ElmtsNbr = 0; //接收FIFO1元素编号
hfdcan1.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_8; //接收FIFO1元素大小:8字节
hfdcan1.Init.RxBuffersNbr = 0; //接收缓冲编号
hfdcan1.Init.RxBufferSize = FDCAN_DATA_BYTES_8; //接收大小:8字节
hfdcan1.Init.TxEventsNbr = 0; //发送事件编号
hfdcan1.Init.TxBuffersNbr = 0; //发送缓冲编号
hfdcan1.Init.TxFifoQueueElmtsNbr = 1; //发送FIFO序列元素编号
hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;//发送FIFO序列模式
hfdcan1.Init.TxElmtSize = FDCAN_DATA_BYTES_8; //发送大小:8字节```
FDCAN_FilterTypeDef sFilterConfig={0};
//配置过滤器
sFilterConfig.IdType = FDCAN_STANDARD_ID; //标准ID
sFilterConfig.FilterIndex = 0; //滤波器索引
sFilterConfig.FilterType = FDCAN_FILTER_MASK;//滤波器类型(传统位过滤模式)
sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0; //过滤器0关联到FIFO0
sFilterConfig.FilterID1 = 0x322;//要过滤的ID位
sFilterConfig.FilterID2 = 0x7FF; //掩码
HAL_FDCAN_ConfigFilter(&hfdcan1, &sFilterConfig);
/* 调用滤波全局设置 */
HAL_FDCAN_ConfigGlobalFilter(&hfdcan1, FDCAN_REJECT, FDCAN_REJECT, FDCAN_REJECT_REMOTE, FDCAN_REJECT_REMOTE);
/* 配置接收 FIFO 0 watermark 为 2 */
HAL_FDCAN_ConfigFifoWatermark(&hfdcan1, FDCAN_CFG_RX_FIFO0, 2);
/* 使能FDCAN接收中断 */
HAL_FDCAN_ActivateNotification(&hfdcan1,FDCAN_IT_RX_FIFO0_NEW_MESSAGE,0);
if (HAL_FDCAN_Start(&hfdcan1) != HAL_OK)
{
/* Start Error */
Error_Handler();
}
/**
* 函数功能: 发送一组数据
* 输入参数: len:数据长度(最大为8)
msg:数据指针,最大为8个字节
* 返 回 值: 0,成功;其它,失败
* 说 明: ID为0X12,标准帧,数据帧
*/
uint8_t FDCAN1_Send_Msg(uint8_t* msg)
{
TxHeader.Identifier = 0x321; //32位ID
TxHeader.IdType = FDCAN_STANDARD_ID; //标准ID
TxHeader.TxFrameType = FDCAN_DATA_FRAME; //数据帧
TxHeader.DataLength = FDCAN_DLC_BYTES_8;//数据长度
TxHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
TxHeader.BitRateSwitch = FDCAN_BRS_OFF;//打开速率切换
TxHeader.FDFormat = FDCAN_CLASSIC_CAN; //FDCAN模式
TxHeader.TxEventFifoControl = FDCAN_NO_TX_EVENTS; //无发送事件
TxHeader.MessageMarker = 1;
printf("date send \n");
/* 将需要发送的数据压入到TX FIFO */
if (HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &TxHeader, msg) != HAL_OK)
{
/* Transmission request Error */
Error_Handler();
}
return 0;
}
uint8_t RxData[8];
/**
* 函数功能: CAN接收回调函数
* 输入参数: RxFifo0ITs:返回标志位
* 返 回 值: 无
* 说 明: 无
*/
void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs)
{
uint8_t i=0;
uint8_t rxdata[8];
if((RxFifo0ITs & FDCAN_IT_RX_FIFO0_WATERMARK) != RESET)
{
/* Retrieve Rx messages from RX FIFO0 */
if (HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &RxHeader, RxData) != HAL_OK)
{
Error_Handler();
}
printf("FDCAN 接收到主机发送来的数据:\n");
printf("id:%#x\r\n",RxHeader.Identifier);
printf("len:0x%0x\r\n",RxHeader.DataLength>>16);
for(i=0;i<8;i++)
printf("rxdata[%d]:0x%0x\r\n",i,RxData[i]);
if (HAL_FDCAN_ActivateNotification(hfdcan, FDCAN_IT_RX_FIFO0_WATERMARK, 0) != HAL_OK)
{
/* Notification Error */
Error_Handler();
}
}
}
//调用
uint8_t txbuf[8]={0};
printf("masert can \n");
uint8_t i=0;
uint8_t rxdata[8];
FDCAN_RxHeaderTypeDef RxHeader;
while (1)
{
if(getchar()=='q')
{
for(uint8_t i=0;i<8;i++)
txbuf[i]=rand()%256+55;
FDCAN1_Send_Msg(txbuf);//发送8个字节
}
else
{
while (HAL_FDCAN_GetRxFifoFillLevel(&hfdcan1, FDCAN_RX_FIFO0) < 2) {}
/* Retrieve Rx messages from RX FIFO0 */
HAL_FDCAN_GetRxMessage(&hfdcan1, FDCAN_RX_FIFO0, &RxHeader, rxdata);
printf("FDCAN 接收到主机发送来的数据:\n");
printf("id:%#x\r\n",RxHeader.Identifier);
printf("len:0x%0x\r\n",RxHeader.DataLength>>16);
for(i=0;i<8;i++)
printf("rxdata[%d]:0x%0x\r\n",i,rxdata[i]);
}
}
static uint32_t BufferCmp8b(uint8_t* pBuffer1, uint8_t* pBuffer2, uint16_t BufferLength)
{
while(BufferLength--)
{
if(*pBuffer1 != *pBuffer2)
{
return 1;
}
pBuffer1++;
pBuffer2++;
}
return 0;
}