首先要安裝cubemx跟Keil5兩個編程軟件,然后打開cubemx軟件,新建一個工程項目:
輸入CPU型號:
在右下角雙擊CPU具體型號:
稍等片刻會打開如下對話框:
首先要配置系統的調試方式:我們選擇SW方式,
然后配置晶振源,這里選擇的是外部晶振,8M,
使能看門狗,
使能CAN,
配置完成后可以看到單片機管腳已經做了配置。
切換到Clock Configuration選項卡,配置時鐘周期,這里配置為8M
切換到Configuration選項卡,進入CAN配置選項配置波特率如下為500Kbps。
配置接收中斷。
配置定時器如下為1ms定時器。
配置定時器中斷
配置完成后點擊保存,然后點擊如下按鈕,生成代碼
填寫工程名稱,路徑,編程軟件等等
選擇生成代碼的方式
等待……
之后點擊打開項目。代碼生成部分完成。
添加一些特殊配置和邏輯代碼,添加CAN的配置信息函數。
void Can_Config(void){ hcan.pTxMsg = &TxMessage; hcan.pRxMsg = &RxMessage; /*##-1- Configure CAN1 Transmission Massage #####################################*/ hcan.pTxMsg->StdId = 0x123; hcan.pTxMsg->RTR = CAN_RTR_DATA; hcan.pTxMsg->IDE = CAN_ID_STD; hcan.pTxMsg->DLC = 8; /*##-2- Configure the CAN1 Filter ###########################################*/ sFilterConfig.FilterNumber = 0; sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; sFilterConfig.FilterScale = CAN_FILTERSCALE_16BIT; sFilterConfig.FilterIdHigh = 0; sFilterConfig.FilterIdLow = 0; sFilterConfig.FilterMaskIdHigh = 0; sFilterConfig.FilterMaskIdLow = 0; sFilterConfig.FilterFIFOAssignment = CAN_FIFO0; sFilterConfig.FilterActivation = ENABLE; sFilterConfig.BankNumber = 14; HAL_CAN_ConfigFilter(&hcan, &sFilterConfig);}
在Main函數中while(1)之前調用一下即可,添加定時器啟動函數:
HAL_TIM_Base_Start_IT(&htim2);
CAN接收中斷啟動函數:
HAL_CAN_Receive_IT(&hcan, CAN_FIFO0);/* USER CODE BEGIN 2 */ Can_Config(); //Can配置信息HAL_TIM_Base_Start_IT(&htim2); //定時器啟動HAL_CAN_Receive_IT(&hcan, CAN_FIFO0);//使能Can接收中斷 /* USER CODE END 2 */
打開stm32f1xx_it.c文件,找到如下函數,添加接收中斷啟動函數:
HAL_CAN_Receive_IT(&hcan, CAN_FIFO0);
注意:接收中斷啟動函數使能一次只進一次中斷,所以中斷退出前要再次使能。
void USB_LP_CAN1_RX0_IRQHandler(void){ /* USER CODE BEGIN USB_LP_CAN1_RX0_IRQn 0 */ /* USER CODE END USB_LP_CAN1_RX0_IRQn 0 */ HAL_CAN_IRQHandler(&hcan); /* USER CODE BEGIN USB_LP_CAN1_RX0_IRQn 1 */ HAL_CAN_Receive_IT(&hcan, CAN_FIFO0);//ê1?üCAN?óê? /* USER CODE END USB_LP_CAN1_RX0_IRQn 1 */}
添加CAN接收服務函數:
HAL_CAN_RxCpltCallback
說明:該函數在stm32f1xx_hal_can.c文件中已經有定義,它的定義方式如下:
__weak void HAL_CAN_TxCpltCallback(CAN_HandleTypeDef* hcan)
函數前面的__weak關鍵字意思是如果有同樣的定義,先執行沒有__weak關鍵字的函數,所以當我們定義了HAL_CAN_RxCpltCallback函數后,編譯器會先編譯我們定義的函數,而忽略系統定義的該函數。當我們沒有定義該函數時,系統會編譯帶有__weak關鍵字的函數。
void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan){ unsigned short int speed; switch(hcan->pRxMsg->StdId) {//根據ID處理數據 case 0x123:// /*在此添加數據處理邏輯*/ break; default: break; }}
添加CAN發送函數:
/* USER CODE BEGIN WHILE */ while (1) { HAL_IWDG_Refresh(&hiwdg); //喂狗函數 if(Can_Trans_Timer == 0) {//每100ms發送一次數據 Can_Trans_Timer = 100; hcan.pTxMsg->StdId = 0x123; hcan.pTxMsg->Data[0] = 'C'; hcan.pTxMsg->Data[1] = 'A'; hcan.pTxMsg->Data[2] = 'N'; hcan.pTxMsg->Data[3] = ' '; hcan.pTxMsg->Data[4] = 'T'; hcan.pTxMsg->Data[5] = 'E'; hcan.pTxMsg->Data[6] = 'S'; hcan.pTxMsg->Data[7] = 'T'; HAL_CAN_Transmit(&hcan, 200);//發送一幀數據 } } /* USER CODE END WHILE */
在定時器函數中添加定時器代碼:
void TIM2_IRQHandler(void){ /* USER CODE BEGIN TIM2_IRQn 0 */ if(Can_Trans_Timer > 0) Can_Trans_Timer--; /* USER CODE END TIM2_IRQn 0 */ HAL_TIM_IRQHandler(&htim2); /* USER CODE BEGIN TIM2_IRQn 1 */ /* USER CODE END TIM2_IRQn 1 */}
說明:在往工程中添加代碼時要注意,不要任意往里面添加代碼,要在注釋著USER CODE BEGIN的地方添加代碼,這樣在重新生成代碼時才不至于將已經寫好的代碼覆蓋掉,如下
/* USER CODE BEGIN Includes */
責任編輯:xj
原文標題:STM32-CubeMX-實現CAN通訊
文章出處:【微信公眾號:STM32嵌入式開發】歡迎添加關注!文章轉載請注明出處。
原文標題:STM32-CubeMX-實現CAN通訊
文章出處:【微信號:c-stm32,微信公眾號:STM32嵌入式開發】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論