php網(wǎng)站后臺(tái)模版重慶seo整站優(yōu)化方案范文
STM32 CUBE Can調(diào)試
- 1、CAN配置
- 2、時(shí)鐘配置
- 3、手動(dòng)添加
- 4、回調(diào)函數(shù)
- 5、啟動(dòng)函數(shù)和發(fā)送函數(shù)
- 6、使用方法(采用消息隊(duì)列來(lái)做緩存)
- 7、數(shù)據(jù)不多在發(fā)送函數(shù)中獲取空郵箱發(fā)送,否則循環(huán)等待空郵箱
1、CAN配置
2、時(shí)鐘配置
3、手動(dòng)添加
需要注意的是STM32CUBE配置的代碼需要再手動(dòng)添加過(guò)濾器,并且將FIFO關(guān)聯(lián)。
/* 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 *//* 手動(dòng)新增 */CAN_FilterTypeDef CAN1_sFilterConfig;CAN1_sFilterConfig.FilterIdHigh = CAN1_ID_H; //32位基礎(chǔ)ID設(shè)置(高16位)CAN1_sFilterConfig.FilterIdLow = CAN1_ID_L; //32位基礎(chǔ)ID設(shè)置(低16位)CAN1_sFilterConfig.FilterMaskIdHigh = CAN1_MASK_H; //32位屏蔽MASK設(shè)置(高16位)CAN1_sFilterConfig.FilterMaskIdLow = CAN1_MASK_L; //32位屏蔽MASK設(shè)置(低16位)CAN1_sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0; //接收到的報(bào)文放入FIFO0位置CAN1_sFilterConfig.FilterBank = 0; //過(guò)濾器0CAN1_sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; //設(shè)為IDLIST列表模式/IDMASK屏蔽模式CAN1_sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; //過(guò)濾器位寬度CAN1_sFilterConfig.FilterActivation = ENABLE; //ENABLE激活過(guò)濾器,DISABLE禁止過(guò)濾器CAN1_sFilterConfig.SlaveStartFilterBank = 0; //過(guò)濾器組設(shè)置(單個(gè)CAN總線時(shí)無(wú)用)if (HAL_OK!=HAL_CAN_ConfigFilter(&hcan, &CAN1_sFilterConfig))//判斷開(kāi)啟是否成功{/* Filter configuration Error */Error_Handler(); //開(kāi)啟CAN總線失敗的處理程序}/* USER CODE END CAN_Init 2 */}
4、回調(diào)函數(shù)
/*** @brief CAN FIFO0的中斷回調(diào)函數(shù),在里面完成數(shù)據(jù)的接收* @param hcan CAN的句柄*/uint8_t date_CAN[8];//設(shè)為全局變量,用于接收CAN數(shù)據(jù)
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、啟動(dòng)函數(shù)和發(fā)送函數(shù)
啟動(dòng)函數(shù)記得添加在while循環(huán)之前。
HAL_CAN_ActivateNotification(hcan ,CAN_IT_RX_FIFO0_MSG_PENDING);
需要發(fā)送時(shí)調(diào)用發(fā)送函數(shù):
/*******************************************************
函數(shù)名稱: Drv_Can_Write
功能描述:
輸 入: 無(wú)輸 出: 無(wú)
******************************************************/
uint8_t Drv_Can_Write(CAN_HandleTypeDef* hcan, uint32_t ID, uint8_t *pData,uint16_t Len)
{ uint8_t ret=1;HAL_StatusTypeDef res = HAL_OK;uint32_t TxMailbox;CAN_TxHeaderTypeDef st_TxHeader;st_TxHeader.StdId=0;st_TxHeader.ExtId=ID;st_TxHeader.IDE=CAN_ID_EXT;st_TxHeader.RTR=0;st_TxHeader.DLC=Len;/*找到空的發(fā)送郵箱,把數(shù)據(jù)發(fā)送出去*/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;
}/******************************************************
函數(shù)名稱: Drv_Can_Start
功能描述:
輸 入: 無(wú)輸 出: 無(wú)
********************************************************/
void Drv_Can_Start(CAN_HandleTypeDef *hcan)
{HAL_CAN_ActivateNotification(hcan ,CAN_IT_RX_FIFO0_MSG_PENDING);HAL_CAN_Start(hcan);
}
6、使用方法(采用消息隊(duì)列來(lái)做緩存)
7、數(shù)據(jù)不多在發(fā)送函數(shù)中獲取空郵箱發(fā)送,否則循環(huán)等待空郵箱
uint8_t CAN1_SendNormalData(CAN_HandleTypeDef* hcan,uint16_t ID,uint8_t *pData,uint16_t Len)
{HAL_StatusTypeDef HAL_RetVal;//判斷狀態(tài)的枚舉uint16_t SendTimes,SendCNT=0;uint8_t FreeTxNum=0;uint8_t FreeLevelCount=0;uint32_t CAN_TX_BOX0;TxMeg.StdId=ID;TxMeg.IDE = CAN_ID_STD;//擴(kuò)展幀標(biāo)識(shí)(STD標(biāo)準(zhǔn)幀/EXT擴(kuò)展幀)TxMeg.RTR = CAN_RTR_DATA;//遠(yuǎn)程幀標(biāo)識(shí)(DATA數(shù)據(jù)幀/REMOTE遠(yuǎn)程幀)if(!hcan||!pData||!Len){printf("\n\rCAN發(fā)送失敗!\n\r"); //串口發(fā)送return HAL_ERROR;//如果總線名、數(shù)據(jù)、數(shù)量任何一個(gè)為0則返回值為1}SendTimes=Len/8+(Len%8?1:0);FreeTxNum=HAL_CAN_GetTxMailboxesFreeLevel(hcan);//得出空閑郵箱的數(shù)量TxMeg.DLC=8;while(SendTimes--){//循環(huán)判斷分批發(fā)送是否結(jié)束if(0==SendTimes){//如果分批發(fā)送結(jié)束if(Len%8)TxMeg.DLC=Len%8;//則加入最后不足8個(gè)的數(shù)據(jù)內(nèi)容}FreeLevelCount = 0;//防止死循環(huán)while(0 == FreeTxNum&&FreeLevelCount<10){FreeLevelCount++;HAL_Delay(1);FreeTxNum = HAL_CAN_GetTxMailboxesFreeLevel(hcan);}HAL_Delay(1);//延時(shí)防止速度過(guò)快導(dǎo)致的發(fā)送失敗//開(kāi)始發(fā)送數(shù)據(jù)(參數(shù):總線名,設(shè)置參數(shù),數(shù)據(jù),郵箱號(hào))HAL_RetVal=HAL_CAN_AddTxMessage(hcan,&TxMeg,pData+SendCNT,&CAN_TX_BOX0);if(HAL_RetVal!=HAL_OK){printf("\n\rCAN總線忙碌!\n\r"); //串口發(fā)送return HAL_BUSY;//如果發(fā)送失敗,則返回值為2}SendCNT+=8;}return HAL_OK;//如果發(fā)送成功結(jié)束,返回值為0
}
//CAN總線通信,使用CAN1,這是CAN專用的printf函數(shù)
//調(diào)用方法:CAN1_printf("123"); //向UART8發(fā)送字符123
void CAN1_printf (char *fmt, ...)
{char buff[CAN1_REC_LEN+1]; //用于存放轉(zhuǎn)換后的數(shù)據(jù) [長(zhǎng)度]uint16_t i=0;va_list arg_ptr;va_start(arg_ptr, fmt);vsnprintf(buff, CAN1_REC_LEN+1, fmt, arg_ptr);//數(shù)據(jù)轉(zhuǎn)換i=strlen(buff);//得出數(shù)據(jù)長(zhǎng)度if(strlen(buff)>CAN1_REC_LEN)i=CAN1_REC_LEN;//如果長(zhǎng)度大于最大值,則長(zhǎng)度等于最大值(多出部分忽略)CAN1_SendNormalData(&hcan,0x11,(uint8_t *)buff,i);//CAN發(fā)送數(shù)據(jù)函數(shù)(ID為0x11)va_end(arg_ptr);
}