stm32:CAN通訊

目錄

介紹

協議層

CAN的 幀/報文 種類

數據幀

遠程幀(遙控幀)

錯誤幀

過載幀

幀間隔

總線仲裁

stm32的CAN外設

工作模式

測試模式

功能框圖

時序

標準時序

例子??環回靜默模式測試

寄存器代碼

HAL版本


介紹

一種功能豐富的車用總線標準。被設計用于在不需要主機(Host)的情況下,允許網絡上的單片機和儀器相互通信

它基于消息傳遞協議,設計之初在車輛上復用通信線纜,以降低銅線使用量,后來也被其他行業所使用

CAN擁有了良好的彈性調整能力,可以在現有網絡中增加節點而不用在軟、硬件上做出調整。除此之外,消息的傳遞不基于特殊種類的節點,增加了升級網絡的便利性

物理層

  • 一個CAN控制器
    • 一般MCU提供,stm32內部提供了一個can控制器
  • 一個CAN收發器
    • 收發器一般需要專門芯片提供,例如PD1050S收發器芯片

can?

協議層

CAN的 幀/報文 種類

特點:

  1. ?CAN總線是廣播類型的總線
  2. 這意味著所有節點都可以偵聽到所有傳輸的報文
  3. 無法將報文單獨發送給指定節點
  4. 所有節點都將始終捕獲所有報文
  5. 但是CAN硬件能夠提供本地過濾功能,讓每個節點對報文有選擇性地做出響應
  6. CAN使用短報文 – 最大實用負載是94位
  7. 可以認為報文是通過內容尋址,也就是說,報文的內容隱式地確定其地址
  8. CAN總線上有5種不同的報文類型
    1. 數據幀,遠程幀,錯誤幀,過載幀,幀間隔

數據幀

  • 數據幀是最常見的報文類型,用于發送單元向接收單元發送數據
  • 有標準格式與擴展格式。標準格式有11位標識符,擴展格式有29位標識符

遠程幀(遙控幀)

  • 遠程幀用于接收單元向具有相同id的發送單元請求發送數據
  • 有標準格式與擴展格式。標準格式有11位標識符,擴展格式有29位標識符
  • 與數據幀相比沒有數據段

錯誤幀

  • 錯誤幀當檢測出錯誤時向其他單元通知錯誤的幀
  • 由硬件自動完成的,沒有辦法用軟件來控制

過載幀

  • 過載幀并不常用,因為當今的CAN控制器會非常智能化地避免使用過載幀
  • 由硬件自動完成的,沒有辦法用軟件來控制

幀間隔

  • 用于將數據幀及遙控幀與前面的幀分離開來的幀
  • 由硬件自動完成的,沒有辦法用軟件來控制

總線仲裁

發送接收特點:

  1. CAN總線處于空閑狀態的時候,最先發送消息的單元獲得發送權
  2. 多個單元同時開始發送時,從仲裁段(報文id)的第一位開始進行仲裁
  3. 連續輸出顯性電平最多的單元可以繼續發送,即首先出現隱形電平的單元失去最總線的占有權變為接收。(即報文id小的優先級高)
  4. 競爭失敗,會自動檢測總線空閑,在第一時間再次嘗試發送

stm32的CAN外設

STM32的芯片中具有bxCAN控制器,它支持CAN協議2.0A 和2.0B Active標準。

  • CAN2.0A只能處理標準數據幀且擴展幀的內容會織別錯誤。
  • 而CAN2.0 B Active可以處理標準數據幀和擴展數據幀。
  • CAN2.0 B Passive只能處理標準數據幀而擴展幀的內容會被忽略
  • 該CAN控制器支持最高的通訊速率為1Mb/s
  • 可以自動地接收和發送CAN報文
  • 外設中具有3個發送郵箱,發送報文的優先級可以使用軟件控制,還可以記錄發送的時間
  • 具有2個3級深度的接收FIFO,可使用過濾功能只接收或不接收某些ID號的報文
  • 可配置成自動重發;不支持使用DMA進行數據收發

工作模式

CAN控制器有3種工作模式:

  • 初始化模式
  • 正常模式
  • 睡眠模式

上電復位后CAN控制器默認會進入睡眠模式,作用是降低功耗。當需要將進行初始的時候(配置寄存器),會進入初始化模式。當需要通訊的時候,就進入正常模式

測試模式

有3種測試模式:

  • 靜默模式
  • 環回模式
  • 環回靜默模式

當控制器進入初始化模式的時候才可以配置測試模式

  • 靜默模式可以用于檢測總線的數據流量
  • 環回模式可以用于自檢(影響總線)
  • 環回靜默也是用于自檢,不會影響到總線

功能框圖

  • 主動內核
    • 含各種控制/狀態/配置寄存器,可以配置模式、波特率等。在STM32CubeMx中可以非常方便的配置
  • 發送郵件
    • 用來緩存待發送的報文,最多可以緩存3個報文。發送調度決定報文的發送順序
  • 接收FIFO
    • 共有2個接收FIFO,每個FIFO都可以存放3個完整的報文。它們完全由硬件來管理。從而節省了CPU的處理負荷,簡化了軟件并保證了數據的一致性。應用程序只能通過讀取FIFO輸出郵箱,來讀取FIFO中最先收到的報文
  • 接收濾波器
    • 做用:對接到的報文進行過濾。最后放入FIFO 0或FIFO 1
    • 當總線上報文數據量很大時,總線上的設備會頻繁獲取報文,占用CPU。過濾器的存在,選擇性接收有效報文,減輕系統負擔
    • 有2種過濾模式
      • 標識符列表模式
        • 它把要接收報文的ID列成一個表,要求報文ID與列表中的某一個標識符完全相同才可以接收,可以理解為白名單管理
      • 掩碼模式(屏蔽位模式)
        • 它把可接收報文ID的某幾位作為列表,這幾位被稱為掩碼,可以把它理解成關鍵字搜索,只要掩碼(關鍵字)相同,就符合要求,報文就會被保存到接收FIFO

時序

標準時序

  • 與我們前面解釋的 CAN 標準時序有一點區別
  • STM32的位時序:把傳播時間段和相位緩沖段1做了合并

例子??環回靜默模式測試

需求:我們使用環回靜默模式測試CAN能否正常工作。把接收到的報文數據發送到串口輸出,看是否可以正常工作

寄存器代碼

main.c

int main(void)
{usart1_init();printf("尚硅谷 CAN 通訊實驗: 靜默回環 寄存器版\r\n");CAN_Init();printf("CAN 初始化配置完成...\r\n");uint16_t stdId = 0x066;uint8_t *tData = "abcdefg";CAN_SendMsg(stdId, tData, strlen((char *)tData));printf("發送完畢...\r\n");tData = "123";CAN_SendMsg(stdId, tData, strlen((char *)tData));printf("發送完畢...\r\n");stdId = 0x067;tData = "xyz";CAN_SendMsg(stdId, tData, strlen((char *)tData));printf("發送完畢...\r\n");/* 1. 接收數據 */RxDataStruct rxDataStruct[8];uint8_t rxMsgCount;CAN_ReceiveMsg(rxDataStruct, &rxMsgCount);printf("接收完畢 rxMsgCount = %d...\r\n", rxMsgCount);/* 2. 輸出消息 */uint8_t i;for (i = 0; i < rxMsgCount; i++){RxDataStruct msg = rxDataStruct[i];printf("stdId = %d, length = %d, msgData = %s\r\n", msg.stdId, msg.length, msg.data);}while (1){}
}

can.h

#ifndef __CAN_H
#define __CAN_H
#include "stm32f10x.h"
#include "usart.h"
#include "string.h"/*** @description: 存儲接收到的數據* @return {*}*/
typedef struct
{uint16_t stdId;uint8_t data[8];uint8_t length;
} RxDataStruct;void CAN_Init(void);
void CAN_SendMsg(uint16_t stdId, uint8_t *data, uint8_t length);
void CAN_ReceiveMsg(RxDataStruct rxDataStruct[], uint8_t *msgCount);#endif

can.c

#include "can.h"/*** @description: CAN 通訊初始化*/
void CAN_Init(void)
{/* 1. 開啟時鐘 CAN時鐘和GPIO時鐘 */RCC->APB1ENR |= RCC_APB1ENR_CAN1EN;RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;RCC->APB2ENR |= RCC_APB2ENR_AFIOEN;/* 2. 重定向PB8和PB9引腳  10:CAN_RX映像到PB8,CAN_TX映像到PB9 */AFIO->MAPR |= AFIO_MAPR_CAN_REMAP_1;AFIO->MAPR &= ~AFIO_MAPR_CAN_REMAP_0;/* 3. 初始化GPIO:PB9(CAN_Tx):復用推挽輸出 mode=11 cnf=10PB8(CAN_Rx): 浮空輸入 mode=00 cnf=01*/GPIOB->CRH |= GPIO_CRH_MODE9;  /* mode = 11 */GPIOB->CRH |= GPIO_CRH_CNF9_1; /* cnf = 10 */GPIOB->CRH &= ~GPIO_CRH_CNF9_0;GPIOB->CRH &= ~GPIO_CRH_MODE8;  /* mode = 00 */GPIOB->CRH &= ~GPIO_CRH_CNF8_1; /* cnf = 01 */GPIOB->CRH |= GPIO_CRH_CNF8_0;/* 4. 初始化 CAN *//* 4.1 進入初始化模式 */CAN1->MCR |= CAN_MCR_INRQ;while ((CAN1->MSR & CAN_MSR_INAK) == 0) /* 等待進入初始化模式 */;/* 4.2 退出睡眠模式 */CAN1->MCR &= ~CAN_MCR_SLEEP;while ((CAN1->MSR & CAN_MSR_SLAK) != 0) /* 等待退出睡眠模式 */;/* 4.3 自動離線管理。 允許自動退出離線狀態 */CAN1->MCR |= CAN_MCR_ABOM;/* 4.4 自動喚醒管理。 檢測到有報文,可以從睡眠模式由硬件自動喚醒。 */CAN1->MCR |= CAN_MCR_AWUM;/* 4.5 配置位時序寄存器 *//* 4.5.1 靜默模式 用于調試 */CAN1->BTR |= CAN_BTR_SILM;/* 4.5.2 回環模式 用于調試 */CAN1->BTR |= CAN_BTR_LBKM;/* 4.5.3 波特率分頻器,定義Tq的長度。配置35表示36分頻,則產生波特率的時鐘位1MHz。Tq = 1us*/CAN1->BTR &= ~CAN_BTR_BRP; /* 相應的位均置0 (9:0) */CAN1->BTR |= 35 << 0;/* 4.5.4 時間段1(3*Tq)和時間段2(6*Tq) */CAN1->BTR &= ~CAN_BTR_TS1;CAN1->BTR &= ~CAN_BTR_TS2;CAN1->BTR |= (3 << 16);CAN1->BTR |= (6 << 20);/* 4.5.5 再同步跳躍寬度 2*Tq*/CAN1->BTR &= ~CAN_BTR_SJW;CAN1->BTR |= (2 << 24);/* 4.6 退出初始化模式 */CAN1->MCR &= ~CAN_MCR_INRQ;while ((CAN1->MSR & CAN_MSR_INAK) != 0) /* 等待退出初始化模式 */;/* 4.7 配置過濾器: 接收所有消息 *//* 4.7.1 進入過濾器初始化模式 */CAN1->FMR |= CAN_FMR_FINIT;/* 4.7.2 過濾器組0工作模式: 掩碼模式 0:掩碼模式  1:標識符模式 */CAN1->FM1R &= ~CAN_FM1R_FBM0;/* 4.7.2 過濾器組0為單個32位配置 0:2給16位  1:單個32位*/CAN1->FS1R |= CAN_FS1R_FSC0;/* 4.7.3 給過濾器組0分配FIFO 0:FIFO0 1:FIFO1. 通過后的報文會放入這個FIFO中*/CAN1->FFA1R &= ~CAN_FFA1R_FFA0;/* 4.7.4 設置過濾器組0 標識符寄存器FR1 */CAN1->sFilterRegister[0].FR1 = 0x00000000; /* id每位都是0 *//* 4.7.5 設置過濾器組0 屏蔽位寄存器FR2 */CAN1->sFilterRegister[0].FR2 = 0x00000000; /* 屏蔽位是0,表示不關心ID對應的位。都是0,表示接收所有消息 *//* 4.7.6 激活過濾器組0 */CAN1->FA1R |= CAN_FA1R_FACT0;/* 4.7.7 退出過濾器初始化模式 */CAN1->FMR &= ~CAN_FMR_FINIT;
}/*** @description: 發送消息* @param {uint16_t} stdId 標準幀id* @param {uint8_t} *data 要發送的數據* @param {uint8_t} length 發送的數據的字節數*/
void CAN_SendMsg(uint16_t stdId,uint8_t *data,uint8_t length)
{if (length > 8){printf("數據長度不能超過8個字節\r\n");return;}/* 1. 等待郵箱0為空 (也可以判斷其他郵箱) 0:非空 1:空*/while ((CAN1->TSR & CAN_TSR_TME0) == 0);/* 2. 使用標準標識符 0:標準標識符 1:擴展標識符 */CAN1->sTxMailBox[0].TIR &= ~CAN_TI0R_IDE;/* 3. 0:數據幀 or 1:遠程幀 */CAN1->sTxMailBox[0].TIR &= ~CAN_TI0R_RTR;/* 4. 設置標準標識符 */CAN1->sTxMailBox[0].TIR &= ~CAN_TI0R_STID;CAN1->sTxMailBox[0].TIR |= (stdId << 21);/* 5. 設置數據長度 */CAN1->sTxMailBox[0].TDTR &= ~CAN_TDT0R_DLC;CAN1->sTxMailBox[0].TDTR |= (length << 0);/* 6. 設置數據 */uint8_t i;CAN1->sTxMailBox[0].TDLR = 0; /* 低位寄存器 */CAN1->sTxMailBox[0].TDHR = 0; /* 高位寄存器 */for (i = 0; i < length; i++){if (i < 4){CAN1->sTxMailBox[0].TDLR |= (data[i] << (8 * i));}else{CAN1->sTxMailBox[0].TDHR |= (data[i] << (8 * (i - 4)));}}/* 7. 請求發送數據 */CAN1->sTxMailBox[0].TIR |= CAN_TI0R_TXRQ;
}/*** @description:* @param {uint16_t} *stdId 讀取數據的標準id* @param {uint8_t} *data 讀取到的數據* @param {uint8_t} *length 讀取到的數據的長度*/
void CAN_ReceiveMsg(RxDataStruct rxDataStruct[], uint8_t *msgCount)
{/* 1. 獲取 FIFO0 中的報文數 */*msgCount = (CAN1->RF0R & CAN_RF0R_FMP0) >> 0;uint8_t i, j;for (i = 0; i < *msgCount; i++){RxDataStruct *msg = &rxDataStruct[i];/* 2. 讀取標準標識符id */msg->stdId = (CAN1->sFIFOMailBox[0].RIR >> 21) & 0x7FF;/* 3. 讀取數據長度 */msg->length = (CAN1->sFIFOMailBox[0].RDTR >> 0) & 0x0F;/* 4. 讀取數據 */memset(msg->data, 0, sizeof((char *)msg->data));uint32_t low = CAN1->sFIFOMailBox[0].RDLR;uint32_t high = CAN1->sFIFOMailBox[0].RDHR;for (j = 0; j < msg->length; j++){if (j < 4){msg->data[j] = (low >> (8 * j)) & 0xFF;}else{msg->data[j] = (high >> (8 * (j - 4))) & 0xFF;}}/* 5. 釋放 FIFO 0. 則報文數減1*/CAN1->RF0R |= CAN_RF0R_RFOM0;}
}

HAL版本

?

main.c

int main(void)
{HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_CAN_Init();MX_USART1_UART_Init();/* USER CODE BEGIN 2 *//* 1. 配置過濾器 */CAN_Filter_Config();/* 2. 啟動CAN總線 */HAL_CAN_Start(&hcan);/* 3. 發送數據 */uint16_t stdId = 0x011;uint8_t *tData = "abcdefg";CAN_SendMsg(stdId, tData, strlen((char *)tData));printf("發送完畢...\r\n");tData = "123";CAN_SendMsg(stdId, tData, strlen((char *)tData));printf("發送完畢...\r\n");/* 4. 接收數據 */RxDataStruct rxDataStruct[8];uint8_t rxMsgCount;CAN_ReceiveMsg(rxDataStruct, &rxMsgCount);printf("接收完畢 rxMsgCount = %d...\r\n", rxMsgCount);/* 5. 輸出消息 */uint8_t i;for (i = 0; i < rxMsgCount; i++){RxDataStruct msg = rxDataStruct[i];printf("stdId = %d, length = %d, msgData = %s\r\n", msg.stdId, msg.length, msg.data);}while (1){}
}

can.h中添加

 /* USER CODE BEGIN Prototypes */typedef struct{uint16_t stdId;uint8_t data[8];uint8_t length;} RxDataStruct;void CAN_Filter_Config(void);void CAN_SendMsg(uint16_t stdId, uint8_t *data, uint8_t length);void CAN_ReceiveMsg(RxDataStruct rxDataStruct[], uint8_t *msgCount);/* USER CODE END Prototypes */

can.c中添加

/* USER CODE BEGIN 1 */
/*** @description: 配置過濾器*/
void CAN_Filter_Config()
{CAN_FilterTypeDef sFilterConfig;sFilterConfig.FilterBank = 0;                      // 過濾器編號, CAN1是0-13, CAN2是14-27sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;  // 采用掩碼模式sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; // 設置篩選器的尺度, 采用32位sFilterConfig.FilterIdHigh = 0X0000;               // 過濾器ID高16位,即CAN_FxR1寄存器的高16位sFilterConfig.FilterIdLow = 0X0000;                // 過濾器ID低16位,即CAN_FxR1寄存器的低16位sFilterConfig.FilterMaskIdHigh = 0X0000;           // 過濾器掩碼高16位,即CAN_FxR2寄存器的高16位sFilterConfig.FilterMaskIdLow = 0X0000;            // 過濾器掩碼低16位,即CAN_FxR2寄存器的低16位sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0; // 設置經過篩選后數據存儲到哪個接收FIFOsFilterConfig.FilterActivation = ENABLE;           // 是否使能本篩選器sFilterConfig.SlaveStartFilterBank = 14;           // 指定為CAN1分配多少個濾波器組HAL_CAN_ConfigFilter(&hcan, &sFilterConfig);
}/*** @description: 發送信息* @param {uint16_t} stdId* @param {uint8_t} *data* @param {uint8_t} length*/
void CAN_SendMsg(uint16_t stdId,uint8_t *data,uint8_t length)
{/* 1. 檢測發送郵箱是否可用 */while (HAL_CAN_GetTxMailboxesFreeLevel(&hcan) == 0);CAN_TxHeaderTypeDef txHeader;txHeader.IDE = CAN_ID_STD;   // 標準幀還是擴展幀txHeader.RTR = CAN_RTR_DATA; // 幀的類型: 數據幀還是遠程幀txHeader.StdId = stdId;      // 標準幀的idtxHeader.DLC = length;       // 發送的數據長度 單位字節uint32_t txMailBox;          // 會把這次使用的郵箱存入到這個變量/* 2. 發送消息 */HAL_CAN_AddTxMessage(&hcan, &txHeader, data, &txMailBox);
}/*** @description: 接收消息* @param {RxDataType} **/
void CAN_ReceiveMsg(RxDataStruct rxDataStruct[], uint8_t *msgCount)
{/* 1. 檢測FIFO0收到的報文個數 */*msgCount = HAL_CAN_GetRxFifoFillLevel(&hcan, CAN_RX_FIFO0);/* 2. 遍歷出所有消息 */uint8_t i;CAN_RxHeaderTypeDef rxHeader;for (i = 0; i < *msgCount; i++){HAL_CAN_GetRxMessage(&hcan, CAN_RX_FIFO0, &rxHeader, rxDataStruct[i].data);rxDataStruct[i].stdId = rxHeader.StdId;rxDataStruct[i].length = rxHeader.DLC;}
}
/* USER CODE END 1 */

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/46327.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/46327.shtml
英文地址,請注明出處:http://en.pswp.cn/web/46327.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

分布式存儲概述

1. 分布式存儲概念 大規模分布式存儲系統的定義如下: “分布式存儲系統是大量普通PC服務器通過Internet互聯&#xff0c;對外作為一個整體提供存儲服務。” 分布式存儲系統具有如下幾個特性: 可擴展。分布式存儲系統可以擴展到幾百臺甚至幾千臺的集群規模&#xff0c;而且&a…

24暑假算法刷題 | Day15 | LeetCode 110. 平衡二叉樹,257. 二叉樹的所有路徑,404. 左葉子之和,222. 完全二叉樹的節點個數

目錄 110. 平衡二叉樹題目描述題解 257. 二叉樹的所有路徑題目描述題解 404. 左葉子之和題目描述題解 222. 完全二叉樹的節點個數題目描述題解 110. 平衡二叉樹 點此跳轉題目鏈接 題目描述 給定一個二叉樹&#xff0c;判斷它是否是平衡二叉樹 平衡二叉樹 是指該樹所有節點的…

Redis-布隆過濾器(Bloom Filter)詳解

文章目錄 什么是布隆過濾器 布隆過濾器的優點&#xff1a;布隆過濾器的缺點&#xff1a;其他問題 布隆過濾器適合的場景布隆過濾器原理 數據結構增加元素查詢元素刪除元素 如何使用布隆過濾器 Google開源的Guava自帶布隆過濾器Redis實現布隆過濾器 Redis中配置布隆過濾器Redis…

【echarts】tooltip 增加單位

單個柱子 const data [{value: 1,per: 2},{value: 22,per: 2},{value: 222,per: 3} ];tooltip: {trigger: axis,show: true,axisPointer: {type: line,lineStyle: {color: rgba(0, 0, 0, 0.03),type: solid,width: 60,},},formatter(params) {return ${params[0].name}: ${par…

歐鵬 數據庫第一次作業

第一次作業題目 1,windows中選擇一種方式安裝mysql 2,新建產品庫(名字自擬)db_mysql_3 3,使用產品庫新建三張表 如下: 表1:employees 列1:id,整型,主鍵 列2:name,字符串,最大長度50,不能為空 列3:age,整型 列4:gender,字符串,最大長度10,不能為空,默認值"…

數據結構歷年考研真題對應知識點(樹、森林)

目錄 5.4.2樹、森林與二叉樹的轉換 1.樹轉換為二叉樹 【樹和二叉樹的轉換及相關性質的推理(2009、2011)】 2.森林轉換為二叉樹 【森林和二叉樹的轉換及相關性質的推理(2014)】 3.二叉樹轉換為森林 【由遍歷序列構造一棵二叉樹并轉換為對應的森林(2020、2021)】 5.4.3樹和…

C# 各版本語法新功能匯總

C# 8.0 以后 官網 C# 7.3 》》in C# 7.2 》》 命名參數、具名參數 》》》 條件 ref 表達式 C# 7.1 》》 default 運算符 default 在C#7.1中得到了改進&#xff0c;不再需要default&#xff08;T&#xff09;了 //變量賦值C#7.0 var s "字符串"; s default(s…

LeetCode 算法:電話號碼的字母組合 c++

原題鏈接&#x1f517;&#xff1a;電話號碼的字母組合 難度&#xff1a;中等???? 題目 給定一個僅包含數字 2-9 的字符串&#xff0c;返回所有它能表示的字母組合。答案可以按 任意順序 返回。 給出數字到字母的映射如下&#xff08;與電話按鍵相同&#xff09;。注意 …

SpringCloud教程 | 第九篇: 使用API Gateway

1、參考資料 SpringCloud基礎篇-10-服務網關-Gateway_springcloud gateway-CSDN博客 2、先學習路由&#xff0c;參考了5.1 2.1、建了一個cloudGatewayDemo&#xff0c;這是用來配置網關的工程&#xff0c;配置如下&#xff1a; http://localhost:18080/aaa/name 該接口代碼如…

git clone命令, 克隆遠程倉庫

這個應該是最簡單的命令&#xff0c;當別人扔給你一個*****.git鏈接&#xff0c;你要知道怎么用&#xff0c;但是還需要注意以下幾點&#xff1a; 1. 你在該網站上是否有賬號 2. 你在該網站上的賬號是否是該項目的成員&#xff0c;如果不是&#xff0c;那可能clone不了 3. 本機…

WSL-Ubuntu20.04部署環境配置

1.更換Ubuntu軟件倉庫鏡像源 為了在WSL上使用TensorRT進行推理加速&#xff0c;需要安裝以下環境&#xff0c;下面將按以下順序分別介紹安裝、驗證以及刪除環境&#xff1a; #1.C環境配置 gcc、gdb、g #2.gpu環境 cuda、cudnn #3.Cmake環境 CMake #4.OpenCV環境 OpenCV #5.Ten…

vxe-grid 實現配置式form搜索條件 form搜索條件框可折疊 配置式table

文章目錄 效果圖代碼 效果圖 代碼 <template><div class"app-container"><vxe-grid refxGrid v-bind"gridOptions" v-if"tableHeight" :height"tableHeight"><template #billDate"{ data }"><e…

Zoom視頻會議軟件使用

Zoom是一款廣受歡迎的視頻會議軟件&#xff0c;使用它可以輕松地進行遠程會議、在線培訓和團隊協作等。要充分利用Zoom軟件的功能&#xff0c;以下是詳細具體的使用方法和步驟&#xff1a; 下載安裝 下載&#xff1a;訪問Zoom官方網站&#xff0c;根據使用的操作系統下載相應的…

ttkefu在線客服系統 機器人+人工客服 全渠道接入客戶咨詢

ttkefu在線客服系統是一種集成了機器人客服與人工客服&#xff0c;并支持全渠道接入客戶咨詢的綜合解決方案。這種系統能夠顯著提升客戶服務效率&#xff0c;優化客戶體驗&#xff0c;同時幫助企業降低運營成本 1. 智能機器人客服 自動回復&#xff1a;機器人客服能夠自…

Java集合框架的內部揭秘:List、Set與Map的深潛之旅

Java集合框架是一套強大的工具&#xff0c;為開發者提供了靈活的數據管理方式。本文將深入剖析List、Set和Map的內部機制&#xff0c;通過詳細的示例和擴展討論&#xff0c;帶你領略這些數據容器的真諦。 一、List&#xff1a;有序序列的深度剖析 List接口是一個可以包含重復…

自制連點器

B站使用教程&#xff1a;https://www.bilibili.com/video/BV1SR85e4EKw/?vd_source47eba1800d831e86d4778a128740fe73 下載鏈接&#xff1a;鏈接&#xff1a;https://pan.baidu.com/s/1Spv_yVPFB3zoS__VL-nhaQ?pwdyxo1 提取碼&#xff1a;yxo1

20.x86游戲實戰-遠線程注入的實現

免責聲明&#xff1a;內容僅供學習參考&#xff0c;請合法利用知識&#xff0c;禁止進行違法犯罪活動&#xff01; 本次游戲沒法給 內容參考于&#xff1a;微塵網絡安全 工具下載&#xff1a; 鏈接&#xff1a;https://pan.baidu.com/s/1rEEJnt85npn7N38Ai0_F2Q?pwd6tw3 提…

Spring Boot 中,監聽應用程序啟動的生命周期事件的4種方法

文章目錄 前言在 Spring Boot 中&#xff0c;監聽應用程序啟動的生命周期事件有多種方法。你可以使用以下幾種方式來實現&#xff1a; 一、使用 ApplicationListener二、使用 EventListener三、實現 CommandLineRunner 或 ApplicationRunner四、使用 SmartLifecycle總結 前言 …

Spring AI 應用開發中設置訪問 Ollama 的超時時間

使用 Spring AI 開發 AI 應用時&#xff0c;Ollama 通常在本地開發和測試時使用&#xff0c;用來在本地運行大模型。由于本地開發機器的資源限制&#xff0c;當使用 Ollama 運行較大的模型時&#xff0c;大模型給出響應的時間會比較長。Spring AI 提供的 OllamaChatModel 與 Ol…

在Mac上免費恢復誤刪除的Word文檔

Microsoft Word for Mac是一個有用的文字處理應用程序&#xff0c;它與Microsoft Office套件捆綁在一起。該軟件的穩定版本包括 Word 2019、2016、2011 等。 Word for Mac 與 Apple Pages 兼容;這允許在不同的操作系統版本中使用Word文檔&#xff0c;而不會遇到任何麻煩。 與…