汉台网站制作,广州市官方网站,t和p在一起怎么做网站,免费的外链网站STM32 CUBE Can调试 1、CAN配置2、时钟配置3、手动添加4、回调函数5、启动函数和发送函数6、使用方法(采用消息队列来做缓存)7、数据不多在发送函数中获取空邮箱发送#xff0c;否则循环等待空邮箱 1、CAN配置 2、时钟配置 3、手动添加
需要注意的是STM32CUBE配置的代码需要再… STM32 CUBE Can调试 1、CAN配置2、时钟配置3、手动添加4、回调函数5、启动函数和发送函数6、使用方法(采用消息队列来做缓存)7、数据不多在发送函数中获取空邮箱发送否则循环等待空邮箱 1、CAN配置 2、时钟配置 3、手动添加
需要注意的是STM32CUBE配置的代码需要再手动添加过滤器并且将FIFO关联。
/* CAN init function */
void MX_CAN_Init(void)
{/* USER CODE BEGIN CAN_Init 0 *//* USER CODE END CAN_Init 0 *//* USER CODE BEGIN CAN_Init 1 *//* USER CODE END CAN_Init 1 */hcan.Instance CAN1;hcan.Init.Prescaler 18;hcan.Init.Mode CAN_MODE_NORMAL;hcan.Init.SyncJumpWidth CAN_SJW_1TQ;hcan.Init.TimeSeg1 CAN_BS1_8TQ;hcan.Init.TimeSeg2 CAN_BS2_7TQ;hcan.Init.TimeTriggeredMode DISABLE;hcan.Init.AutoBusOff DISABLE;hcan.Init.AutoWakeUp DISABLE;hcan.Init.AutoRetransmission DISABLE;hcan.Init.ReceiveFifoLocked DISABLE;hcan.Init.TransmitFifoPriority DISABLE;if (HAL_CAN_Init(hcan) ! HAL_OK){Error_Handler();}/* USER CODE BEGIN CAN_Init 2 *//* 手动新增 */CAN_FilterTypeDef CAN1_sFilterConfig;CAN1_sFilterConfig.FilterIdHigh CAN1_ID_H; //32位基础ID设置高16位CAN1_sFilterConfig.FilterIdLow CAN1_ID_L; //32位基础ID设置低16位CAN1_sFilterConfig.FilterMaskIdHigh CAN1_MASK_H; //32位屏蔽MASK设置高16位CAN1_sFilterConfig.FilterMaskIdLow CAN1_MASK_L; //32位屏蔽MASK设置低16位CAN1_sFilterConfig.FilterFIFOAssignment CAN_RX_FIFO0; //接收到的报文放入FIFO0位置CAN1_sFilterConfig.FilterBank 0; //过滤器0CAN1_sFilterConfig.FilterMode CAN_FILTERMODE_IDMASK; //设为IDLIST列表模式/IDMASK屏蔽模式CAN1_sFilterConfig.FilterScale CAN_FILTERSCALE_32BIT; //过滤器位宽度CAN1_sFilterConfig.FilterActivation ENABLE; //ENABLE激活过滤器DISABLE禁止过滤器CAN1_sFilterConfig.SlaveStartFilterBank 0; //过滤器组设置单个CAN总线时无用if (HAL_OK!HAL_CAN_ConfigFilter(hcan, CAN1_sFilterConfig))//判断开启是否成功{/* Filter configuration Error */Error_Handler(); //开启CAN总线失败的处理程序}/* USER CODE END CAN_Init 2 */}4、回调函数
/*** brief CAN FIFO0的中断回调函数在里面完成数据的接收* param hcan CAN的句柄*/uint8_t date_CAN[8];//设为全局变量用于接收CAN数据
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{if(hcan-Instance CAN1){CAN_RxHeaderTypeDef RxHeader; //接受句柄HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, RxHeader, date_CAN); //接收CAN邮箱为0FPGA_Comm_Analysis(RxHeader.ExtId, date_CAN, RxHeader.DLC);return ;}
}5、启动函数和发送函数
启动函数记得添加在while循环之前。
HAL_CAN_ActivateNotification(hcan ,CAN_IT_RX_FIFO0_MSG_PENDING);需要发送时调用发送函数
/*******************************************************
函数名称: Drv_Can_Write
功能描述:
输 入: 无输 出: 无
******************************************************/
uint8_t Drv_Can_Write(CAN_HandleTypeDef* hcan, uint32_t ID, uint8_t *pData,uint16_t Len)
{ uint8_t ret1;HAL_StatusTypeDef res HAL_OK;uint32_t TxMailbox;CAN_TxHeaderTypeDef st_TxHeader;st_TxHeader.StdId0;st_TxHeader.ExtIdID;st_TxHeader.IDECAN_ID_EXT;st_TxHeader.RTR0;st_TxHeader.DLCLen;/*找到空的发送邮箱把数据发送出去*/res HAL_CAN_AddTxMessage(hcan, st_TxHeader, pData, TxMailbox);if(res ! HAL_OK){//printf(HAL_CAN_AddTxMessage TxMailbox %d fail! result %d, TxMailbox, res);ret 0;}return ret;
}/******************************************************
函数名称: Drv_Can_Start
功能描述:
输 入: 无输 出: 无
********************************************************/
void Drv_Can_Start(CAN_HandleTypeDef *hcan)
{HAL_CAN_ActivateNotification(hcan ,CAN_IT_RX_FIFO0_MSG_PENDING);HAL_CAN_Start(hcan);
}6、使用方法(采用消息队列来做缓存)
7、数据不多在发送函数中获取空邮箱发送否则循环等待空邮箱
uint8_t CAN1_SendNormalData(CAN_HandleTypeDef* hcan,uint16_t ID,uint8_t *pData,uint16_t Len)
{HAL_StatusTypeDef HAL_RetVal;//判断状态的枚举uint16_t SendTimes,SendCNT0;uint8_t FreeTxNum0;uint8_t FreeLevelCount0;uint32_t CAN_TX_BOX0;TxMeg.StdIdID;TxMeg.IDE CAN_ID_STD;//扩展帧标识STD标准帧/EXT扩展帧TxMeg.RTR CAN_RTR_DATA;//远程帧标识DATA数据帧/REMOTE远程帧if(!hcan||!pData||!Len){printf(\n\rCAN发送失败\n\r); //串口发送return HAL_ERROR;//如果总线名、数据、数量任何一个为0则返回值为1}SendTimesLen/8(Len%8?1:0);FreeTxNumHAL_CAN_GetTxMailboxesFreeLevel(hcan);//得出空闲邮箱的数量TxMeg.DLC8;while(SendTimes--){//循环判断分批发送是否结束if(0SendTimes){//如果分批发送结束if(Len%8)TxMeg.DLCLen%8;//则加入最后不足8个的数据内容}FreeLevelCount 0;//防止死循环while(0 FreeTxNumFreeLevelCount10){FreeLevelCount;HAL_Delay(1);FreeTxNum HAL_CAN_GetTxMailboxesFreeLevel(hcan);}HAL_Delay(1);//延时防止速度过快导致的发送失败//开始发送数据参数总线名设置参数数据邮箱号HAL_RetValHAL_CAN_AddTxMessage(hcan,TxMeg,pDataSendCNT,CAN_TX_BOX0);if(HAL_RetVal!HAL_OK){printf(\n\rCAN总线忙碌\n\r); //串口发送return HAL_BUSY;//如果发送失败则返回值为2}SendCNT8;}return HAL_OK;//如果发送成功结束返回值为0
}
//CAN总线通信使用CAN1这是CAN专用的printf函数
//调用方法CAN1_printf(123); //向UART8发送字符123
void CAN1_printf (char *fmt, ...)
{char buff[CAN1_REC_LEN1]; //用于存放转换后的数据 [长度]uint16_t i0;va_list arg_ptr;va_start(arg_ptr, fmt);vsnprintf(buff, CAN1_REC_LEN1, fmt, arg_ptr);//数据转换istrlen(buff);//得出数据长度if(strlen(buff)CAN1_REC_LEN)iCAN1_REC_LEN;//如果长度大于最大值则长度等于最大值多出部分忽略CAN1_SendNormalData(hcan,0x11,(uint8_t *)buff,i);//CAN发送数据函数ID为0x11va_end(arg_ptr);
}