国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

STM32CubeIDE開發(fā)(二十六), STM32的CAN總線開發(fā)要點(diǎn)

這篇具有很好參考價(jià)值的文章主要介紹了STM32CubeIDE開發(fā)(二十六), STM32的CAN總線開發(fā)要點(diǎn)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

目錄

一、CAN總線簡(jiǎn)介

??????? 1.1 CAN概述

??????? 1.2 CAN總線較其他串行通信優(yōu)勢(shì)

??????? 1.3 CAN總線通信

???????? 1.4 報(bào)文種類及格式

???????? 1.5 CAN應(yīng)用

二、CAN工程創(chuàng)建及配置

??????? 2.1 工程設(shè)計(jì)及原理框圖

???????? 2.2 工程創(chuàng)建接配置

三、代碼設(shè)計(jì)

??????? 3.1 修改輸出源文件can.c

??????? 3.2 自定義can應(yīng)用驅(qū)動(dòng)

?3.3 CAN調(diào)用實(shí)現(xiàn)

四、編譯及測(cè)試

??????? 4.1 編譯及測(cè)試

???????? 4.2 測(cè)試


一、CAN總線簡(jiǎn)介

??????? 1.1 CAN概述

????????CAN是Controller Area Network(控制區(qū)域網(wǎng)絡(luò)) 的縮寫,是ISO國(guó)際標(biāo)準(zhǔn)化的串行通信協(xié)議。由德國(guó)電氣商博世公司在1986年率先提出。此后,CAN通過ISO11898及ISO11519進(jìn)行了標(biāo)準(zhǔn)化?,F(xiàn)在在歐洲已是汽車網(wǎng)絡(luò)的標(biāo)準(zhǔn)協(xié)議。

????????CAN協(xié)議經(jīng)過ISO標(biāo)準(zhǔn)化后有兩個(gè)標(biāo)準(zhǔn):ISO11898標(biāo)準(zhǔn)和ISO11519-2標(biāo)準(zhǔn)。其中ISO11898是針對(duì)通信速率為125Kbps~1Mbps的高速通信標(biāo)準(zhǔn),總線最大長(zhǎng)度達(dá)到40m/1Mbps,連接單元數(shù)最大支持到30;而ISO11519-2是針對(duì)通信速率為125Kbps以下的低速通信標(biāo)準(zhǔn),總線最大長(zhǎng)度達(dá)到1km/40kbps,連接單元數(shù)最大支持到20。

????????CAN 控制器根據(jù)兩根線上的電位差來(lái)判斷總線電平??偩€電平分為顯性電平和隱性電平,二者必居其一。發(fā) 送方通過使總線電平發(fā)生變化,將消息發(fā)送給接收方。只有2個(gè)設(shè)備簡(jiǎn)單通信時(shí),當(dāng)成USART串口使用,多個(gè)設(shè)備同時(shí)通信時(shí),遵循CAN協(xié)議,使用郵箱、識(shí)別符、過濾器功能:總線空閑時(shí),所有單元都可發(fā)送消息,而兩個(gè)以上的單元同時(shí)開始發(fā)送消息時(shí),根據(jù)標(biāo)識(shí)符(ID,非地址)決定優(yōu)先級(jí)。兩個(gè)以上的單元同時(shí)開始發(fā)送消息時(shí),對(duì)各消息ID 的每個(gè)位進(jìn)行逐個(gè)仲裁比較。仲裁獲勝(優(yōu)先級(jí)最高)的單元可繼續(xù)發(fā)送消息,仲裁失利的單元?jiǎng)t立刻停止發(fā)送而進(jìn)行接收工作。

??????? 1.2 CAN總線較其他串行通信優(yōu)勢(shì)

????????CAN總線相比起其他串行通信協(xié)議,具有以下優(yōu)勢(shì):

??????? 【1】由于連接總線的單元,沒有類似“地址”的信息,因此,在總線上添加單元時(shí),已連接的其他單元的軟硬件和應(yīng)用層都不需要做改變。??????

??????? 【2】具有錯(cuò)誤檢測(cè)、錯(cuò)誤通知和錯(cuò)誤恢復(fù)功能:所有單元都可以檢測(cè)錯(cuò)誤(錯(cuò)誤檢測(cè)功能),檢測(cè)出錯(cuò)誤的單元會(huì)立即同時(shí)通知其他所有單元(錯(cuò)誤通知功能),正在發(fā)送消息的單元一旦檢測(cè)出錯(cuò)誤,會(huì)強(qiáng)制結(jié)束當(dāng)前的發(fā)送。強(qiáng)制結(jié)束發(fā)送的單元會(huì)不斷反復(fù)地重新發(fā)送此消息直到成功發(fā)送為止(錯(cuò)誤恢復(fù)功能)。

??????? 【3】故障封閉功能:CAN可以判斷出錯(cuò)誤的類型是總線上暫時(shí)的數(shù)據(jù)錯(cuò)誤(如外部噪聲等)還是持續(xù)的數(shù)據(jù)錯(cuò)誤(如單元內(nèi)部故障、驅(qū)動(dòng)器故障、斷線等)。由此功能,當(dāng)總線上發(fā)生持續(xù)數(shù)據(jù)錯(cuò)誤時(shí),可將引起此故障的單元從總線上隔離出去。

??????? 【4】連接節(jié)點(diǎn)多。CAN 總線是可同時(shí)連接多個(gè)單元的總線。可連接的單元總數(shù)理論上是沒有限制的。但實(shí)際上可連接的單元數(shù)受總線上的時(shí)間延遲及電氣負(fù)載的限制。降低通信速度,可連接的單元數(shù)增加;提高通信速度,則可連接的單元數(shù)減少。

??????? 1.3 CAN總線通信

??????? CAN總線是基于相同波特率通信的,所以設(shè)備接入前要知道總線上的波特率是多少。在STM32CubeMX上,其波特率計(jì)算如下圖所示:波特率=(pclk1/((1+8+7)*9)) = 36Mhz/16/9 = 250Kbits。

STM32CubeIDE開發(fā)(二十六), STM32的CAN總線開發(fā)要點(diǎn)

STM32CubeIDE開發(fā)(二十六), STM32的CAN總線開發(fā)要點(diǎn)

???????? 在數(shù)據(jù)傳輸方面,一次最多只能發(fā)送8個(gè)字節(jié)的數(shù)據(jù),這是由CAN協(xié)議規(guī)定的。多于8個(gè)的需要第二次再發(fā)送,需要開發(fā)者自己實(shí)現(xiàn)連續(xù)多數(shù)據(jù)發(fā)送的函數(shù)來(lái)實(shí)現(xiàn)大于8字節(jié)數(shù)據(jù)量的應(yīng)用。

????????同一條 CAN 總線的不同主機(jī),不能同時(shí)發(fā)送相同 ID 的報(bào)文:如果使用 2 個(gè)及以上驅(qū)動(dòng)器,連接在同一條 CAN 線上,必須設(shè)置為不同的編號(hào),比如 0 組 1 號(hào)和 0 組 2 號(hào),如果不設(shè)置為不同的編號(hào),一旦讓驅(qū)動(dòng)器回傳報(bào)文,報(bào)文 ID 則會(huì)相同,就會(huì)造成總線致命沖突,此時(shí)驅(qū)動(dòng)器會(huì)進(jìn)入硬件錯(cuò)誤狀態(tài)。

??????? CAN接口兼容規(guī)范2.0A和2.0B(主動(dòng)式),可以接收和發(fā)送11位標(biāo)識(shí)符的標(biāo)準(zhǔn)幀,也可以接收和發(fā)送29位標(biāo)識(shí)符的擴(kuò)展幀。具有3個(gè)發(fā)送郵箱和2個(gè)接收FIFO(郵箱及FIFO可以看做是緩存區(qū)域),3級(jí)14個(gè)可調(diào)節(jié)濾波器。

??????? “發(fā)送郵箱”是用于CAN總線數(shù)據(jù)發(fā)送的,總共有3個(gè),每個(gè)郵箱只裝一個(gè)報(bào)文,并且存在優(yōu)先級(jí)關(guān)系。優(yōu)先級(jí)越高表示其里面的數(shù)據(jù)會(huì)被優(yōu)先發(fā)送。數(shù)據(jù)在發(fā)送前都會(huì)被送到優(yōu)先級(jí)最高且空閑的發(fā)送郵箱,然后依次發(fā)送。如果所有郵箱都滿了,會(huì)溢出標(biāo)記為1,需要等待空郵箱。滿郵箱按先后次序排隊(duì)發(fā)送報(bào)文,發(fā)送完成后變成空郵箱。

??????? FIFO:表面的意思是“先入先出”,是指有層級(jí)深度的接收郵箱。一般CAN有2個(gè)FIFO郵箱(FIFO0和FIFO1),每個(gè)FIFO有3層深度,3層深度是指每個(gè)郵箱可以接收3個(gè)報(bào)文,但讀取時(shí)只能讀到最先收到的報(bào)文報(bào)文處理完成后,再讀取時(shí)則是下一個(gè)報(bào)文。

??????? 過濾器:可由硬件判斷報(bào)文中的標(biāo)識(shí)符,過濾掉標(biāo)識(shí)符不匹配的報(bào)文(過濾掉不想要的ID,接收想要的ID)。CAN總線控制器通常提供了14個(gè)或28個(gè)過濾器組,每組2個(gè)32為寄存器。過濾器是由硬件實(shí)現(xiàn)的,只有與過濾器匹配的報(bào)文才需要軟件處理。在接收?qǐng)?bào)文時(shí),數(shù)據(jù)先進(jìn)入過濾器,與過濾器匹配的報(bào)文會(huì)被放入FIFO郵箱。過濾器根據(jù)下列優(yōu)先級(jí)規(guī)則來(lái)確定:
????????1,位寬為32位的過濾器,優(yōu)先級(jí)高于位寬為16位的過濾器
????????2,對(duì)于位寬相同的過濾器,標(biāo)識(shí)符列表模式的優(yōu)先級(jí)高于屏蔽位模式
????????3,位寬和模式都相同的過濾器,優(yōu)先級(jí)由過濾器號(hào)決定,過濾器號(hào)小的優(yōu)先級(jí)高

??????? 最終CAN總線通信如下圖示意:

STM32CubeIDE開發(fā)(二十六), STM32的CAN總線開發(fā)要點(diǎn)

???????? 1.4 報(bào)文種類及格式

??????? CAN報(bào)文包含以下幾種,其中數(shù)據(jù)幀及遙控幀是重點(diǎn)常用格式:

??????? 【1】數(shù)據(jù)幀,用于發(fā)送單元向接收單元傳送數(shù)據(jù)的幀。

??????? 【2】遙控幀或遠(yuǎn)程幀,用于接收單元向具有相同ID的發(fā)送單元請(qǐng)求數(shù)據(jù)的幀。 ???

??????? 【3】錯(cuò)誤幀,用于當(dāng)檢測(cè)出錯(cuò)誤時(shí)向其它單元通知錯(cuò)誤的幀。

??????? 【4】過載幀,用于接收單元通知其尚未做好接收準(zhǔn)備的幀。

??????? 【5】幀間隔,用于將數(shù)據(jù)幀及遙控幀與前面的幀分離開來(lái)的幀。

??????? 每種類型的報(bào)文格式都不相同,數(shù)據(jù)幀和遙控幀格式如下:

STM32CubeIDE開發(fā)(二十六), STM32的CAN總線開發(fā)要點(diǎn)??????? 數(shù)據(jù)幀和遙控幀有標(biāo)準(zhǔn)格式和擴(kuò)展格式兩種格式,類似于I2C協(xié)議里的7位和10位地址。CAN的數(shù)據(jù)幀和遙控幀的標(biāo)識(shí)符(ID)的標(biāo)準(zhǔn)格式有11個(gè)位標(biāo)識(shí)符,擴(kuò)展格式有29個(gè)位標(biāo)識(shí)符。設(shè)備可以用標(biāo)識(shí)符(ID)判斷數(shù)據(jù)是不是發(fā)給自己的。

??????? CAN總線收發(fā)數(shù)據(jù)報(bào)文,根據(jù)標(biāo)示符(也就是 ID)來(lái)決定優(yōu)先級(jí)的。必須注意的是,在同一CAN網(wǎng)絡(luò)中,所有單元必須設(shè)定成統(tǒng)一的通信速度,CAN設(shè)備可通過發(fā)送“遙控幀” 請(qǐng)求其他單元發(fā)送數(shù)據(jù)。CAN支持Normal 正常模式、Silent 靜默模式、Loopback 環(huán)回模式測(cè)試、Silent_loopback 靜默換回模式測(cè)試共四種模式,在CubeMX對(duì)應(yīng)如下:

STM32CubeIDE開發(fā)(二十六), STM32的CAN總線開發(fā)要點(diǎn)

???????? 1.5 CAN應(yīng)用

????????CAN具有很高的可靠性,廣泛應(yīng)用于:汽車電子、工業(yè)自動(dòng)化、船舶、醫(yī)療設(shè)備、工業(yè)設(shè)備等方面。

二、CAN工程創(chuàng)建及配置

??????? 2.1 工程設(shè)計(jì)及原理框圖

????????本文采用STM32L496VGTX+獨(dú)立CAN 收發(fā)器(TJA1050)和STM32F103C8Tx開發(fā)板(已經(jīng)集成了CAN 收發(fā)器-TJA1050)進(jìn)行CAN通信。

STM32CubeIDE開發(fā)(二十六), STM32的CAN總線開發(fā)要點(diǎn)

????????STM32L496VGTX預(yù)留了擴(kuò)展引腳PD0、PD1支持CAN1,然后通過擴(kuò)展引腳接入TJA1050:

STM32CubeIDE開發(fā)(二十六), STM32的CAN總線開發(fā)要點(diǎn)

STM32CubeIDE開發(fā)(二十六), STM32的CAN總線開發(fā)要點(diǎn)STM32CubeIDE開發(fā)(二十六), STM32的CAN總線開發(fā)要點(diǎn)

???????? TJA1050原理框圖,STM32L496VGTX擴(kuò)展口PD0、PD1接下圖的PA11、PA12。

STM32CubeIDE開發(fā)(二十六), STM32的CAN總線開發(fā)要點(diǎn)

???????? STM32F103C8Tx開發(fā)板的CAN組件原理框圖如下,PB8、PB9接MCU:

STM32CubeIDE開發(fā)(二十六), STM32的CAN總線開發(fā)要點(diǎn)

???????? 2.2 工程創(chuàng)建接配置

??????? 現(xiàn)以STM32L496VGTX為例創(chuàng)建CAN工程stm32L496VGT6_can,創(chuàng)建完成后,移植以前已經(jīng)實(shí)現(xiàn)過的lpuart1通信功能、按鍵功能及LED燈功能,請(qǐng)參考:

cubeIDE開發(fā), stm32調(diào)試信息串口通信輸出顯示_py_free的博客-CSDN博客_stm32串口顯示

??????? 假設(shè)已經(jīng)移植了串口調(diào)試功能并能在電腦上通過串口通信實(shí)現(xiàn)調(diào)試信息輸出。

??????? 進(jìn)入CAN配置階段,雙擊.ioc打開CubeMX配置界面,設(shè)置CAN1功能開啟,先在圖形配置界面選擇PD0、PD1為CAN_RX/TX模式,將自動(dòng)開啟CAN1功能,然后進(jìn)入CAN頁(yè)面配置參數(shù),波特率設(shè)置為250Kbits,及本次CAN網(wǎng)絡(luò)的統(tǒng)一波特率。

STM32CubeIDE開發(fā)(二十六), STM32的CAN總線開發(fā)要點(diǎn)

???????? 開啟接收中斷功能

STM32CubeIDE開發(fā)(二十六), STM32的CAN總線開發(fā)要點(diǎn)

???????? 完成后點(diǎn)擊保存輸出生成代碼

三、代碼設(shè)計(jì)

??????? 3.1 修改輸出源文件can.c

??????? 在Core/src目錄下,雙擊打開can.c文件,修改MX_CAN1_Init函數(shù),增加過濾設(shè)置、CAN開啟、中斷支持設(shè)置等功能。

/* USER CODE BEGIN 0 */
//新增
#define CAN1_ID_H      0x0000 //32位基礎(chǔ)ID設(shè)置(高16位)
#define CAN1_ID_L      0x0000 //32位基礎(chǔ)ID設(shè)置(低16位)
#define CAN1_MASK_H    0x0000 //32位屏蔽MASK設(shè)置(高16位)
#define CAN1_MASK_L    0x0000 //32位屏蔽MASK設(shè)置(低16位)
/* USER CODE END 0 */

CAN_HandleTypeDef hcan1;

/* CAN1 init function */
void MX_CAN1_Init(void)
{

  /* USER CODE BEGIN CAN1_Init 0 */
    //新增
	CAN_FilterTypeDef  CAN1_sFilterConfig;
	HAL_StatusTypeDef  HAL_Status;
  /* USER CODE END CAN1_Init 0 */

  /* USER CODE BEGIN CAN1_Init 1 */

  /* USER CODE END CAN1_Init 1 */
  hcan1.Instance = CAN1;
  hcan1.Init.Prescaler = 20;
  hcan1.Init.Mode = CAN_MODE_NORMAL;
  hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
  hcan1.Init.TimeSeg1 = CAN_BS1_8TQ;
  hcan1.Init.TimeSeg2 = CAN_BS2_7TQ;
  hcan1.Init.TimeTriggeredMode = DISABLE;
  hcan1.Init.AutoBusOff = DISABLE;
  hcan1.Init.AutoWakeUp = DISABLE;
  hcan1.Init.AutoRetransmission = DISABLE;
  hcan1.Init.ReceiveFifoLocked = DISABLE;
  hcan1.Init.TransmitFifoPriority = DISABLE;
  if (HAL_CAN_Init(&hcan1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN CAN1_Init 2 */
    //新增
  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_FIFO1;//接收到的報(bào)文放入FIFO1位置
  CAN1_sFilterConfig.FilterBank = 0;//過濾器0
  CAN1_sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;//設(shè)為IDLIST列表模式/IDMASK屏蔽模式
  CAN1_sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;//過濾器位寬度
  CAN1_sFilterConfig.FilterActivation = ENABLE;//ENABLE激活過濾器,DISABLE禁止過濾器
  CAN1_sFilterConfig.SlaveStartFilterBank = 0;//過濾器組設(shè)置(單個(gè)CAN總線時(shí)無(wú)用)
  HAL_Status = HAL_CAN_ConfigFilter(&hcan1, &CAN1_sFilterConfig);
  if ( HAL_Status!= HAL_OK)//判斷開啟是否成功
   {
     /* Filter configuration Error */
     Error_Handler();//開啟CAN總線失敗的處理程序
   }

   /* Start the CAN peripheral */
  HAL_Status = HAL_CAN_Start(&hcan1);
   if ( HAL_Status!= HAL_OK)//這個(gè)函數(shù)和下面的函數(shù)是cubemx沒有給出的,需要手動(dòng)添加
   {
     /* Start Error */
     Error_Handler();//開啟CAN總線失敗的處理程序
   }

   /* Activate CAN RX notification */
   //若不使用CAN中斷,以下不需要
   HAL_Status = HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO1_MSG_PENDING);
   if ( HAL_Status!= HAL_OK)//選擇fifo1中斷
   {
     /* Notification Error */
     Error_Handler();//開啟CAN總線掛起中斷失敗的處理程序
   }

  /* USER CODE END CAN1_Init 2 */

}

??????? 3.2 自定義can應(yīng)用驅(qū)動(dòng)

???????? 在ICore目錄創(chuàng)建文件夾can,并在該文件夾下創(chuàng)建can1.h和can1.c源文件。

??????? can1.h

#ifndef CAN_CAN1_H_
#define CAN_CAN1_H_

#include "stm32l4xx_hal.h" //HAL庫(kù)文件聲明

extern CAN_HandleTypeDef hcan;//聲明的HAL庫(kù)結(jié)構(gòu)體

#define CAN1_REC_LEN  256//定義CAN1最大接收字節(jié)數(shù)

extern uint8_t  CAN1_RX_BUF[CAN1_REC_LEN];//接收緩沖,末字節(jié)為換行符
extern uint16_t CAN1_RX_STA;//接收狀態(tài)標(biāo)記

uint8_t  CAN1_SendNormalData(CAN_HandleTypeDef*  hcan,uint16_t ID,uint8_t *pData,uint16_t  Len);//CAN發(fā)送函數(shù)
void CAN1_printf (char *fmt, ...);//CAN總線通信,使用CAN1,這是CAN專用的printf函數(shù)

#endif /* CAN_CAN1_H_ */

??????? can1.c,該驅(qū)動(dòng)通過CAN1_printf函數(shù)實(shí)現(xiàn)向CAN發(fā)送數(shù)據(jù),通過重寫stm32l4xx_hal_can.h/c文件中的HAL_CAN_RxFifo1MsgPendingCallback函數(shù)實(shí)現(xiàn)CAN數(shù)據(jù)接收。

#include "can1.h" //庫(kù)文件聲明
#include "main.h"
#include <string.h>//用于字符串處理的庫(kù)
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>

CAN_HandleTypeDef hcan;//聲明的HAL庫(kù)結(jié)構(gòu)體

CAN_TxHeaderTypeDef     TxMeg;//CAN發(fā)送設(shè)置相關(guān)結(jié)構(gòu)體
CAN_RxHeaderTypeDef     RxMeg;//CAN接收設(shè)置相關(guān)結(jié)構(gòu)體

uint8_t CAN1_RX_BUF[CAN1_REC_LEN];//接收緩沖,最大CAN1_REC_LEN個(gè)字節(jié).末字節(jié)為換行符
uint16_t CAN1_RX_STA;//接收狀態(tài)標(biāo)記

void  HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan)  //接收回調(diào)函數(shù)(函數(shù)名不可改)
{
    uint8_t  Data[8];//接收緩存數(shù)組
    HAL_StatusTypeDef HAL_RetVal;//判斷狀態(tài)的枚舉
	HAL_RetVal=HAL_CAN_GetRxMessage(hcan,CAN_RX_FIFO1,&RxMeg,Data);//接收郵箱中的數(shù)據(jù)
	if (HAL_OK==HAL_RetVal){//判斷接收是否成功
		//接收成功后的數(shù)據(jù)處理程序,寫在此處。(數(shù)據(jù)在Data數(shù)組中)
		//以下2行是采用簡(jiǎn)單的寄存器查尋方式處理接收數(shù)據(jù),每次只接收1位。在實(shí)際項(xiàng)目中的復(fù)雜接收程序可自行編寫。
		CAN1_RX_BUF[0]=Data[0];//將接收到的數(shù)據(jù)放入緩存數(shù)組(因只用到1個(gè)數(shù)據(jù),所以只存放在數(shù)據(jù)[0]位置)
		CAN1_RX_STA++;//數(shù)據(jù)接收標(biāo)志位加1
	}
}
//CAN發(fā)送數(shù)據(jù)函數(shù)(參數(shù):總線名,ID,數(shù)據(jù)數(shù)組,數(shù)量。返回值:0成功HAL_OK,1參數(shù)錯(cuò)誤HAL_ERROR,2發(fā)送失敗HAL_BUSY)
//示例:CAN1_SendNormalData(&hcan1,0,CAN_buffer,8);//CAN發(fā)送數(shù)據(jù)函數(shù)
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í)防止速度過快導(dǎo)致的發(fā)送失敗
       //開始發(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);
}

?3.3 CAN調(diào)用實(shí)現(xiàn)

??????? 在main.c文件中,加入各驅(qū)動(dòng)文件的頭文件引用

/* USER CODE BEGIN Includes */
#include "../../ICore/key/key.h"
#include "../../ICore/led/led.h"
#include "../../ICore/print/print.h"
#include "../../ICore/usart/usart.h"
#include "../../ICore/can/can1.h"
/* USER CODE END Includes */

???????? 在main函數(shù)中,加入各驅(qū)動(dòng)的初始化化實(shí)現(xiàn),CAN的初始化以及生產(chǎn)代碼自動(dòng)調(diào)用

  /* USER CODE BEGIN 2 */
  ResetPrintInit(&hlpuart1);
  HAL_UART_Receive_IT(&hlpuart1,(uint8_t *)&HLPUSART_NewData, 1); //再開啟接收中斷
  HLPUSART_RX_STA = 0;
  /* USER CODE END 2 */

??????? 在main函數(shù)循環(huán)體中,實(shí)現(xiàn)CAN調(diào)用

  /* USER CODE BEGIN WHILE */
  while (1)
  {
	  if(HLPUSART_RX_STA&0xC000){//溢出或換行,重新開始
		  printf("%.*s\r\n",HLPUSART_RX_STA&0X0FFF, HLPUSART_RX_BUF);
		  HLPUSART_RX_STA=0;//接收錯(cuò)誤,重新開始
		  HAL_Delay(100);//等待
	  }
	  if(CAN1_RX_STA!=0)//CAN判斷中斷接收標(biāo)志位【處理從CAN外部設(shè)備接收的字符】
      {
    	  //CAN1_printf("%c",CAN1_RX_BUF[0]); //CAN總線發(fā)送
    	  printf("CAN1 Receive:%c",CAN1_RX_BUF[0]); //lpuart1總線發(fā)送
    	  CAN1_RX_STA=0;//清除標(biāo)志位
      }
	  if(KEY_1())//按下KEY1判斷
	  {
		  CAN1_printf("A");//向CAN1發(fā)送字符A
	  }
	  if(KEY_2())//按下KEY2判斷
	  {
		  CAN1_printf("B");//向CAN1發(fā)送字符B
	  }
    /* USER CODE END WHILE */

四、編譯及測(cè)試

??????? 4.1 編譯及測(cè)試

???????? 編譯工程,STM32L496VGx支持ST-Link,直接在CubeIDE配置運(yùn)行及下載程序。

STM32CubeIDE開發(fā)(二十六), STM32的CAN總線開發(fā)要點(diǎn)

???????? 同樣方法基于STM32F103C8Tx芯片創(chuàng)建工程、配置CAN及代碼編譯,其CAN配置如下

STM32CubeIDE開發(fā)(二十六), STM32的CAN總線開發(fā)要點(diǎn)

???????? 完成工程編譯后,加載測(cè)試

STM32CubeIDE開發(fā)(二十六), STM32的CAN總線開發(fā)要點(diǎn)

???????? 4.2 測(cè)試

??????? 打開串口工具,連接STM32L496芯片的工程lpuart1串口,在STM32F103C8Tx開發(fā)板上按鍵KEY1、KEY2,查看串口輸出情況。

STM32CubeIDE開發(fā)(二十六), STM32的CAN總線開發(fā)要點(diǎn)文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-414359.html

到了這里,關(guān)于STM32CubeIDE開發(fā)(二十六), STM32的CAN總線開發(fā)要點(diǎn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • STM32 基礎(chǔ)知識(shí)(探索者開發(fā)板)--159講 CAN總線

    CAN基礎(chǔ)知識(shí):ISO國(guó)際標(biāo)準(zhǔn)化的串行通信協(xié)議,為了減少線束的數(shù)量 a.多主控制? 每個(gè)設(shè)備都可以主動(dòng)發(fā)送數(shù)據(jù) b.通信速度較快,通信距離遠(yuǎn)。最高1Mbps(距離小于40M),最遠(yuǎn)可達(dá)10KM(速率低于5Kbps) c.具有錯(cuò)誤檢測(cè)、錯(cuò)誤通知和錯(cuò)誤恢復(fù)功能 d.故障封閉功能? 能發(fā)現(xiàn)故障,且可以把故

    2024年01月17日
    瀏覽(31)
  • CAN總線詳解及STM32的CAN通信編程指南

    CAN總線詳解及STM32的CAN通信編程指南

    對(duì)于CAN通信而言,本人之前也未接觸了解過,由于實(shí)習(xí)的技術(shù)要求,因此也花費(fèi)了一段時(shí)間對(duì)CAN通信進(jìn)行學(xué)習(xí),并且實(shí)現(xiàn)了基于STM32的CAN環(huán)回靜默模式通信,因此寫一遍比較詳細(xì)的文章對(duì)該內(nèi)容進(jìn)行總結(jié)。本文的參考資料有STM32的中文參考手冊(cè)、協(xié)議手冊(cè)等。話不多說(shuō)開始吧!

    2024年02月11日
    瀏覽(27)
  • STM32 CAN總線過濾器設(shè)置

    STM32 CAN總線過濾器設(shè)置

    ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?CAN過濾器配置以及常見問題總結(jié) 過濾器組 在具有兩個(gè)CAN的產(chǎn)品中,CAN1和CAN2分享28個(gè)過濾器組,只有一個(gè)CAN的系列產(chǎn)品中有14個(gè)過濾器組,用以對(duì)接收到的幀進(jìn)行過

    2024年01月17日
    瀏覽(89)
  • STM32的CAN總線調(diào)試經(jīng)驗(yàn)分享

    STM32的CAN總線調(diào)試經(jīng)驗(yàn)分享

    CAN總線簡(jiǎn)易入門教程 CAN總線顯性電平和隱性電平詳解 STM32的CAN總線調(diào)試經(jīng)驗(yàn)分享 最近負(fù)責(zé)的一個(gè)項(xiàng)目用的主控芯片是 STM32F407IGT6 ,需要和幾個(gè)電機(jī)控制器進(jìn)行通訊,有很多參數(shù)需要進(jìn)行監(jiān)控。負(fù)責(zé)固件開發(fā)的同事一直搞不定一個(gè)問題。就是開啟 CAN 的接收中斷,接收不到數(shù)據(jù)

    2024年01月20日
    瀏覽(20)
  • CAN總線基礎(chǔ)詳解以及stm32的CAN控制器

    CAN總線基礎(chǔ)詳解以及stm32的CAN控制器

    目錄 CAN簡(jiǎn)介 CAN總線拓?fù)鋱D CAN總線特定 CAN應(yīng)用場(chǎng)景 CAN的物理層 CAN的協(xié)議層 CAN數(shù)據(jù)幀介紹 CAN位時(shí)序介紹 數(shù)據(jù)同步過程 硬件同步 再同步 CAN總線仲裁 stm32的CAN控制器 CAN控制器介紹 CAN控制器模式 CAN控制器框圖 接收過濾器 CAN控制器波特率計(jì)算 CAN相關(guān)寄存器 CAN主控制寄存器(

    2024年01月25日
    瀏覽(52)
  • CAN總線學(xué)習(xí)筆記 | STM32CubeMX配置CAN環(huán)回測(cè)試

    CAN總線學(xué)習(xí)筆記 | STM32CubeMX配置CAN環(huán)回測(cè)試

    CAN基礎(chǔ)知識(shí)介紹文中介紹了CAN協(xié)議的基礎(chǔ)知識(shí),以及STM32F4芯片的CAN控制器相關(guān)知識(shí),下面將通過實(shí)例,利用STM32CubeMX圖形化配置工具,來(lái)實(shí)現(xiàn)CAN通訊的環(huán)回測(cè)試 CAN是掛載在APB1總線上,設(shè)置PCLK1時(shí)鐘頻率到最大45MHz 激活CAN1,配置位時(shí)序參數(shù),其他基本參數(shù)以及工作模式(此處

    2024年02月11日
    瀏覽(42)
  • STM32+收發(fā)器實(shí)現(xiàn)CAN和485總線

    STM32+收發(fā)器實(shí)現(xiàn)CAN和485總線

    RS485總線是一種常見的(Recommended Standard)串行總線標(biāo)準(zhǔn)(485是它的標(biāo)識(shí)號(hào)),采用平衡發(fā)送與差分接收的方式,因此具有抑制共模干擾的能力。CAN是控制器局域網(wǎng)絡(luò)(Controller Area Network, CAN)的簡(jiǎn)稱,是一種能夠?qū)崿F(xiàn)分布式實(shí)時(shí)控制的串行通信網(wǎng)絡(luò),屬于CSMA(多路載波偵聽)/CD(沖突檢測(cè)

    2024年02月05日
    瀏覽(24)
  • STM32基于CAN總線協(xié)議控制步進(jìn)電機(jī)

    STM32基于CAN總線協(xié)議控制步進(jìn)電機(jī)

    如上圖所示,實(shí)現(xiàn)了以下功能: 1.兩塊stm32單片機(jī)通過CAN控制器與收發(fā)器進(jìn)行半雙工通信; 2.stm32主機(jī)通過檢測(cè)按鍵,切換不同的模式,將不同模式的case值發(fā)送給stm32從機(jī); 3.stm32從機(jī)根據(jù)收到的case值,控制步進(jìn)電機(jī)進(jìn)行不同的運(yùn)動(dòng)操作; 4.OLED用于顯示收發(fā)內(nèi)容與按鍵狀態(tài)等

    2024年01月19日
    瀏覽(21)
  • CAN總線(五)STM32的CAN波特率設(shè)置方法(完整版)

    CAN總線(五)STM32的CAN波特率設(shè)置方法(完整版)

    ?①HSI是高速內(nèi)部時(shí)鐘,RC振蕩器,頻率為8MHz。 ? ②HSE是高速外部時(shí)鐘,可接石英/陶瓷諧振器,或者接外部時(shí)鐘源,頻率范圍為4MHz~16MHz。 ③LSI是低速內(nèi)部時(shí)鐘,RC振蕩器,頻率為40kHz。 ④LSE是低速外部時(shí)鐘,接頻率為32.768kHz的石英晶體。 ⑤PLL為鎖相環(huán)倍頻輸出,其時(shí)鐘輸入

    2024年02月07日
    瀏覽(16)
  • stm32專題二十六:高級(jí)定時(shí)器介紹

    stm32專題二十六:高級(jí)定時(shí)器介紹

    高級(jí)定時(shí)器 STM32F103有 2 個(gè)高級(jí)定時(shí)器 TIM1 和 TIM8,高級(jí)定時(shí)器的功能主要有定時(shí)、輸入捕獲、輸出比較、互補(bǔ)輸出等。 高級(jí)定時(shí)器簡(jiǎn)介: 計(jì)數(shù)器16bit,上 / 下 / 兩邊 計(jì)數(shù),TIM1和TIM8,還有一個(gè)重復(fù)計(jì)數(shù)器RCR,獨(dú)有; 有4個(gè)GPIO,其中通道1 ~ 3還有互補(bǔ)輸出GPIO; 時(shí)鐘來(lái)自PCLK2,為

    2024年02月20日
    瀏覽(21)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包