STM32_USB

概述

本文是使用HAL庫的USB驅動

因為官方cubeMX生成的hal庫做組合設備時過于繁瑣

所以這里使用某大神的插件,可以集成在cubeMX里自動生成組合設備

有小bug會覆蓋生成文件里自己寫的內容,所以生成一次后注意保存

插件安裝

下載地址 https://github.com/alambe94/I-CUBE-USBD-Composite/releases/tag/V01.00.03

下載pack文件

打開cubeMX

image-20250327112752157

點擊這個 之后選擇下載的文件 安裝

image-20250327112827185

出現這個即為安裝成功

image-20250327113051627

生成代碼

打開USB 設為設備模式,打開中斷

image-20250327143923426

注意設置時鐘樹

USB需要較為精確的時鐘 建議用外部晶振

image-20250327144003378

選擇庫文件

image-20250327150139349

目前打勾的這倆必選

其余根據需要選擇

image-20250327150230465

根據需要選擇,注意要在上步開啟的庫文件中選

image-20250327150308199

在初始化后加入這個函數

MX_USB_DEVICE_Init();

image-20250327161540514

可以去usbd_desc.c里設置VID/PID 某些名稱等參數,不同設備有些許不同

image-20250328203448138

虛擬串口(CDC)

概述

串口名是由PC的驅動來決定的,沒法在STM32端設置

設置

打開這個

可以在這里設置虛擬的串口數量

注意一個串口要占用2個IN端點和一個OUT端點

image-20250328133231954

也可以設置AL94.I-CUBE-USBD-COMPOSITE_conf.h文件中的_USBD_CDC_ACM_COUNT設置虛擬的CDC串口數量

發送

開始發送

類型名稱功能
uint8_tch通道
uint8_t *Buf緩沖區地址
uint16_tLen發送數量
uint8_t輸出已經發送的數量
uint8_t CDC_Transmit(uint8_t ch, uint8_t *Buf, uint16_t Len)

發送完成

類型名稱功能
uint8_tcdc_ch通道
uint8_t *Buf緩沖區地址
uint32_tLen發送數量
uint8_tepnum端點號
uint8_t錯誤碼
int8_t CDC_TransmitCplt(uint8_t cdc_ch, uint8_t *Buf, uint32_t *Len, uint8_t epnum)

接收

類型名稱功能
uint8_tcdc_ch通道
uint8_t *Buf緩沖區地址
uint32_tLen發送數量
int8_t錯誤碼

接收到數據會自動調用這函數

int8_t CDC_Receive(uint8_t cdc_ch, uint8_t *Buf, uint32_t *Len)

在這個函數里調用這倆句,來接收下個數據包

  USBD_CDC_SetRxBuffer(cdc_ch, &hUsbDevice, &Buf[0]);USBD_CDC_ReceivePacket(cdc_ch, &hUsbDevice);

控制函數

類型名稱功能
uint8_tcdc_ch通道
uint8_tcmd命令類型
uint8_t *pbuf命令緩沖區
uint16_tlength長度
int8_t錯誤碼
int8_t CDC_Control(uint8_t cdc_ch, uint8_t cmd, uint8_t *pbuf, uint16_t length)

cmdCDC_SET_LINE_CODING時收到來自主機的命令

具體內容生成的函數中有注釋

人體工學設備(HID)

概述

全部使用自定義HID設備

根據不同設備設置描述符即可

HID間的復合直接復制就行

eg:鼠標+鍵盤 直接把鼠標的描述符和鍵盤的描述符寫到一起即可

建立工程

image-20250329144505389

image-20250329144515151

設置

usbd_customhid.h

名稱功能
CUSTOM_HID_STR_DESCHID描述
CUSTOM_HID_EPIN_SIZE輸入緩沖大小(一般設為64)
CUSTOM_HID_EPOUT_SIZE輸出緩沖大小(一般設為64)
USBD_CUSTOMHID_OUTREPORT_BUF_SIZEHID緩沖區(一般設為64)
CUSTOM_HID_FS_BINTERVAL包間隔時間

usbd_custom_hid_if.c

CUSTOM_HID_ReportDesc 設置HID描述符 USBD_CUSTOM_HID_REPORT_DESC_SIZE 同時也要設置配置符大小

image-20250329154822531

APIs

發送數據
類型名稱功能
USBD_HandleTypeDef *pdevUSB句柄
uint8_t *report緩沖區
uint16_tlen數據長度
uint8_t錯誤碼
  uint8_t USBD_CUSTOM_HID_SendReport(USBD_HandleTypeDef *pdev,uint8_t *report, uint16_t len);
接收數據回調

usbd_custom_hid_if.c

類型名稱功能
uint8_tevent_idx
uint8_tstate
uint8_t錯誤碼
int8_t CUSTOM_HID_OutEvent(uint8_t event_idx, uint8_t state)

在內部調用以獲取數據

USBD_CUSTOM_HID_HandleTypeDef *hhid = (USBD_CUSTOM_HID_HandleTypeDef *)HZ_DAP_USB_Handle.pClassData_HID_Custom;
// hhid->Report_buf;
USBD_CUSTOM_HID_ReceivePacket(&HZ_DAP_USB_Handle);

鼠標

鼠標的配置描述符

0x05, 0x01, 
0x09, 0x02, 
0xa1, 0x01, 0x85, 0x02, // 報告ID (2)0x09, 0x01, 
0xa1, 0x00, 
0x05, 0x09, 
0x19, 0x01, 
0x29, 0x03,
0x15, 0x00, 
0x25, 0x01, 
0x95, 0x03, 
0x75, 0x01,
0x81, 0x02, 
0x95, 0x01, 
0x75, 0x05,
0x81, 0x03, 
0x95, 0x03,
0x75, 0x08,
0x05, 0x01,
0x09, 0x30,
0x09, 0x31,
0x09, 0x38,
0x15, 0x81,
0x25, 0x7f,
0x81, 0x06,
0xc0,
0xc0 

需要發送的命令 含義

位置功能
Bit0報告ID
Bit1[0]左鍵(0未按1按下)
Bit1[1]右鍵(0未按1按下)
Bit1[2]中鍵(0未按1按下)
Bit2x軸(正右負左 -127~127)
Bit3y軸(正下負上 -127~127)
Bit4滾動(正上負下 -127~127)

這個函數是自己封裝的

extern USBD_HandleTypeDef hUsbDevice;/*** @brief 控制鼠標* @param key_l 左鍵(僅bit0 0未按1按下)* @param key_r 右鍵(僅bit0 0未按1按下)* @param key_m 中鍵(僅bit0 0未按1按下)* @param x x軸(正右負左 -127~127)* @param y y軸(正下負上 -127~127)* @param ec 滾動(正上負下 -127~127)* @author HZ12138* @date 2025-03-28 20:17:39*/
void HZ_Mouse_set(uint8_t key_l, uint8_t key_r, uint8_t key_m, int8_t x, int8_t y, int8_t ec)
{uint8_t buf[5];key_l &= 0x01;key_r &= 0x01;key_m &= 0x01;buf[0] = 0x02; // 報告ID 鼠標是0x02buf[1] = (key_m << 2) | (key_r << 1) | (key_l << 0);buf[2] = (uint8_t)x;buf[3] = (uint8_t)y;buf[4] = (uint8_t)ec;USBD_CUSTOM_HID_SendReport(&hUsbDevice, buf, 5);
}

鍵盤

描述符

0x85后面跟的是報告ID 0保留

0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x06, // USAGE (Keyboard)
0xa1, 0x01, // COLLECTION (Application)0x85, 0x01, // 報告ID (1)0x05, 0x07, //   USAGE_PAGE (Keyboard)
0x19, 0xe0, //   USAGE_MINIMUM (Keyboard LeftControl)
0x29, 0xe7, //   USAGE_MAXIMUM (Keyboard Right GUI)
0x15, 0x00, //   LOGICAL_MINIMUM (0)
0x25, 0x01, //   LOGICAL_MAXIMUM (1)
0x75, 0x01, //   REPORT_SIZE (1)
0x95, 0x08, //   REPORT_COUNT (8)
0x81, 0x02, //   INPUT (Data,Var,Abs)
0x95, 0x01, //   REPORT_COUNT (1)
0x75, 0x08, //   REPORT_SIZE (8)
0x81, 0x03, //   INPUT (Cnst,Var,Abs)
0x95, 0x05, //   REPORT_COUNT (5)
0x75, 0x01, //   REPORT_SIZE (1)
0x05, 0x08, //   USAGE_PAGE (LEDs)
0x19, 0x01, //   USAGE_MINIMUM (Num Lock)
0x29, 0x05, //   USAGE_MAXIMUM (Kana)
0x91, 0x02, //   OUTPUT (Data,Var,Abs)
0x95, 0x01, //   REPORT_COUNT (1)
0x75, 0x03, //   REPORT_SIZE (3)
0x91, 0x03, //   OUTPUT (Cnst,Var,Abs)
0x95, 0x06, //   REPORT_COUNT (6)
0x75, 0x08, //   REPORT_SIZE (8)
0x15, 0x00, //   LOGICAL_MINIMUM (0)
0x25, 0x65, //   LOGICAL_MAXIMUM (101)
0x05, 0x07, //   USAGE_PAGE (Keyboard)
0x19, 0x00, //   USAGE_MINIMUM (Reserved (no event indicated))
0x29, 0x65, //   USAGE_MAXIMUM (Keyboard Application)
0x81, 0x00, //   INPUT (Data,Ary,Abs)
0xc0        // END_COLLECTION

數據內容

Bit2~8 發送的是按下的鍵號 如果不按下寫0即可

位置功能
Bit0報告ID
Bit1[0]左CTRL(0未按1按下)
Bit1[1]左SHIFT(0未按1按下)
Bit1[2]左ALT(0未按1按下)
Bit1[3]左GUI(0未按1按下)
Bit1[4]右CTRL(0未按1按下)
Bit1[5]右SHIFT(0未按1按下)
Bit1[6]右ALT(0未按1按下)
Bit1[7]右GUI(0未按1按下)
Bit2保留(0x00)
Bit3按鍵1
Bit4按鍵2
Bit5按鍵3
Bit6按鍵4
Bit7按鍵5
Bit8按鍵6

封裝的發送按鍵函數和單個按鍵按下函數

extern USBD_HandleTypeDef hUsbDevice;
/*** @brief 發送按鍵* @param keys 按鍵* @param key_num 數量最大6個* @param ctrl_l 如名(0未按1按下)* @param shift_l 如名(0未按1按下)* @param alt_l 如名(0未按1按下)* @param gui_l 如名(0未按1按下)* @param ctrl_r 如名(0未按1按下)* @param shift_r 如名(0未按1按下)* @param alt_r 如名(0未按1按下)* @param gui_r 如名(0未按1按下)* @author HZ12138* @date 2025-03-28 22:52:09*/
void HZ_KeyBoard_set(uint8_t *keys, uint8_t key_num,uint8_t ctrl_l, uint8_t shift_l, uint8_t alt_l, uint8_t gui_l,uint8_t ctrl_r, uint8_t shift_r, uint8_t alt_r, uint8_t gui_r)
{uint8_t buf[9];ctrl_l &= 0x01;shift_l &= 0x01;alt_l &= 0x01;gui_l &= 0x01;ctrl_r &= 0x01;shift_r &= 0x01;alt_r &= 0x01;gui_r &= 0x01;buf[0] = 0x01;buf[1] = (gui_r << 7) | (alt_r << 6) | (shift_r << 5) | (ctrl_r << 4) |(gui_l << 3) | (alt_l << 2) | (shift_l << 1) | (ctrl_l << 0);buf[2] = 0x00;for (int i = 0; i < key_num; i++)buf[3 + i] = keys[i];USBD_CUSTOM_HID_SendReport(&hUsbDevice, buf, 9);
}
/*** @brief 發送單個按鍵 * @param key 按鍵值* @author HZ12138* @date 2025-03-28 22:52:12*/
void HZ_KeyBoard_one_key(uint8_t key)
{uint8_t temp[6];temp[0] = key;HZ_KeyBoard_set(temp, 6, 0, 0, 0, 0, 0, 0, 0, 0);
}

鍵碼對應表,使用HID碼

按鍵名稱HID碼虛擬鍵碼
ESC41 [0X29]27 [0x1B]
F158 [0X3a]112 [0x70]
F259 [0X3b]113 [0x71]
F360 [0X3c]114 [0x72]
F461 [0X3d]115 [0x73]
F562 [0X3e]116 [0x74]
F663 [0X3f]117 [0x75]
F764 [0X40]118 [0x76]
F865 [0X41]119 [0x77]
F966 [0X42]120 [0x78]
F1067 [0X43]121 [0x79]
F1168 [0X44]122 [0x7A]
F1269 [0X45]123 [0x7B]
Esc41 [0X29]27 [0x1B]
Back (回退)42 [0X2a]8 [0x08]
Tab43 [0X2b]9 [0x09]
CapLck (大小寫)57 [0X39]20 [0x14]
Enter (回車)40 [0X28]13 [0x0D]
Space (空格)44 [0X2c]32 [0x20]
Scroll71 [0X47]145 [0x91]
Pause(暫停)72 [0X48]19 [0x13]
Insert (插入)73 [0X49]45 [0x2D]
PrintScr (截屏)70 [0X46]44 [0x2C]
Delete (刪除)76 [0X4c]46 [0x2E]
Home (首頁)74 [0X4a]36 [0x24]
End (結尾)77 [0X4d]35 [0x23]
PageUp (上一頁)75 [0X4b]33 [0x21]
PageDn (下一頁)78 [0X4e]34 [0x22]
Left (左)80 [0X50]37 [0x25]
Up (上)82 [0X52]38 [0x26]
Right (右)79 [0X4f]39 [0x27]
Down (下)81 [0X51]40 [0x28]
Num0 (小鍵盤)98 [0X62]96 [0x60]
Num1 (小鍵盤)89 [0X59]97 [0x61]
Num2 (小鍵盤)90 [0X5a]98 [0x62]
Num3 (小鍵盤)91 [0X5b]99 [0x63]
Num4 (小鍵盤)92 [0X5c]100 [0x64]
Num5 (小鍵盤)93 [0X5d]101 [0x65]
Num6 (小鍵盤)94 [0X5e]102 [0x66]
Num7 (小鍵盤)95 [0X5f]103 [0x67]
Num8 (小鍵盤)96 [0X60]104 [0x68]
Num9 (小鍵盤)97 [0X61]105 [0x69]
NumAdd (加號)87 [0X57]107 [0x6B]
NumSub (減號)86 [0X56]109 [0x6D]
NumMult (乘號)85 [0X55]106 [0x6A]
NumDiv (除號)84 [0X54]111 [0x6F]
NumDecim (點)99 [0X63]110 [0x6E]
NumLock (數字鎖定鍵)83 [0X53]144 [0x90]
Ctrl1 [0X01]17 [0x11]
LCtrl (左CTR)1 [0X01]162 [0xA2]
RCtrl16 [0X10]163 [0xA3]
Shift2 [0X02]16 [0x10]
LShift2 [0X02]160 [0xA0]
RShift32 [0X20]161 [0xA1]
Alt4 [0X04]18 [0x12]
LAlt4 [0X04]164 [0xA4]
RAlt64 [0X40]165 [0xA5]
WIN8 [0X08]91 [0x5B]
LWIN8 [0X08]91 [0x5B]
RWIN128 [0X80]92 [0x5C]
A4 [0X04]65 [0x41]
B5 [0X05]66 [0x42]
C6 [0X06]67 [0x43]
D7 [0X07]68 [0x44]
E8 [0X08]69 [0x45]
F9 [0X09]70 [0x46]
G10 [0X0a]71 [0x47]
H11 [0X0b]72 [0x48]
I12 [0X0c]73 [0x49]
J13 [0X0d]74 [0x4A]
K14 [0X0e]75 [0x4B]
L15 [0X0f]76 [0x4C]
M16 [0X10]77 [0x4D]
N17 [0X11]78 [0x4E]
O18 [0X12]79 [0x4F]
P19 [0X13]80 [0x50]
Q20 [0X14]81 [0x51]
R21 [0X15]82 [0x52]
S22 [0X16]83 [0x53]
T23 [0X17]84 [0x54]
U24 [0X18]85 [0x55]
V25 [0X19]86 [0x56]
W26 [0X1a]87 [0x57]
X27 [0X1b]88 [0x58]
Y28 [0X1c]89 [0x59]
Z29 [0X1d]90 [0x5A]
039 [0X27]48 [0x30]
130 [0X1e]49 [0x31]
231 [0X1f]50 [0x32]
332 [0X20]51 [0x33]
433 [0X21]52 [0x34]
534 [0X22]53 [0x35]
635 [0X23]54 [0x36]
736 [0X24]55 [0x37]
837 [0X25]56 [0x38]
938 [0X26]57 [0x39]

大容量存儲(MSC)

建立工程

image-20250404233158298

image-20250404233251426

設置

usbd_msc.h 中的 MSC_MEDIA_PACKET 要設為扇區(sector)大小

w25Qxx為4096 SD卡為512

STORAGE_LUN_NBR為虛擬磁盤卷數量 一般把一個設備設為一個卷 設置這個可以虛擬出多個磁盤

usbd_storage_if.cSTORAGE_BLK_NBR 為最小操作單元數量(一般寫扇區數量)

usbd_storage_if.cSTORAGE_BLK_SIZ 為最小操作單元大小 (一般寫扇區大小) 單位(Byte)

這倆相乘即可得到總大小 單位(Byte)

注意這倆的blk所指的塊與FLASH的不同,也是我寫成最小操作單元的原因

可以修改這個最后三項來更改顯示名稱

usbd_storage_if.cSTORAGE_Inquirydata

image-20250405214854576

APIs

存儲讀取(必寫)

描述名稱功能
uint8_tlun卷標
uint8_t *buf緩沖區
uint32_tblk_addr最小操作單元起始地址(*STORAGE_BLK_SIZ后得到Byte起始地址 )
uint16_tblk_len最小操作單元的數量(*STORAGE_BLK_SIZ后得到Byte數量 )
int8_t輸出錯誤碼

usbd_storage_if.c

需要根據自己內容填寫

int8_t STORAGE_Read(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)

存儲寫入(必寫)

描述名稱功能
uint8_tlun卷標
uint8_t *buf緩沖區
uint32_tblk_addr最小操作單元起始地址(*STORAGE_BLK_SIZ后得到Byte起始地址 )
uint16_tblk_len最小操作單元的數量(*STORAGE_BLK_SIZ后得到Byte數量 )
int8_t輸出錯誤碼

usbd_storage_if.c

需要根據自己內容填寫

int8_t STORAGE_Write(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)

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

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

相關文章

【文獻閱讀】Capabilities of Gemini Models in Medicine

? Google DeepMind Google Research 發表于 2024-04-29 相關鏈接&#xff1a; 數據集&#xff1a;https://huggingface.co/datasets/katielink/med-gemini-medqa-relabeled 注&#xff1a;長EHR是長的電子健康記錄&#xff08;Electronic Health Record&#xff09; 未開…

網絡安全小知識課堂(最終完結版)

網絡安全入門 &#xff1a;從 “小白” 到 “守護者” 的蛻變之旅 寫在完結之際 歷經 13 篇的深度探索&#xff0c;我們從 DDoS 攻擊的 “流量洪水” 一路闖關到 HTTPS 的 “加密堡壘”&#xff0c;揭開了網絡安全世界的層層面紗。感謝每一位讀者的陪伴與互動&#xff0c;你們…

Php laravel 留言板 curd 實戰

1. 項目創建 首先我們用composer創建項目 &#xff0c; composer會根據當前的php版本 幫我們選擇支持的最高版本 composer create-project --prefer-dist laravel/laravel myblog laravel新版本比較激進 &#xff0c;需要最低 php7 支持 2. 項目配置 數據庫配置 &#xff0c…

HTTP 壓力測試工具autocannon(AI)

簡介 autocannon 是一款基于 Node.js 的高性能 HTTP 壓力測試工具&#xff0c;適用于評估 Web 服務的并發處理能力和性能瓶頸。 一、工具特點 高性能?&#xff1a;利用 Node.js 異步非阻塞機制模擬高并發請求?。?實時監控?&#xff1a;測試過程中動態展示請求統計和性能…

LVM 擴容詳解

目錄 一、LVM擴容 1. 查看磁盤分區情況&#xff1a; 2. 查看pv、vg、lv 情況 3. 將新硬盤分區初始化 4. 將初始化后的分區添加到VG中 5. 查看邏輯卷的設備路徑 6. VG分配給lv 二、擴展文件系統 1.確認文件系統類型 三、檢驗 一、LVM擴容 1. 查看磁盤分區情況&#xff1a; …

每日一題(小白)數組娛樂篇21

由于題意可知我們是要將對應的數字轉換為英文&#xff0c;我們要考慮兩點一個是進制的轉換&#xff0c;也就是類似于我們的十進制一到9就多一位&#xff0c;這里的進制就是Z進制也就是27進制一旦到26下一位則進位&#xff1b;另一方面要考慮數字的轉換也就是1~26對應A~Z。解決上…

python爬蟲:喜馬拉雅案例(破解sign值)

聲明&#xff1a; 本文章中所有內容僅供學習交流使用&#xff0c;不用于其他任何目的&#xff0c;嚴禁用于商業用途和非法用途&#xff0c;否則由此產生的一切后果均與作者無關&#xff01; 根據上一篇文章&#xff0c;我們破解了本網站的&#xff0c;手機號和密碼驗證&#x…

深入探討:Spring 如何接入 DeepSeek?

?在當今數字化浪潮中&#xff0c;人工智能&#xff08;AI&#xff09;技術的迅猛發展深刻地改變著各個領域的技術格局。Java 作為一種廣泛應用于企業級開發的編程語言&#xff0c;其生態系統也在不斷演進以適應 AI 技術的融入。Spring 框架&#xff0c;作為 Java 生態中的中流…

VSCode運行,各類操作緩慢,如何清理

VSCode寫代碼&#xff0c;隨著項目逐步進展&#xff0c;代碼量在增加&#xff0c;依賴的第三方頭文件也在增加&#xff0c; 先是發現代碼提示的速度變慢&#xff0c; 后來格式化代碼速度太慢 然后c/c代碼的語法檢查有時候壓根就失敗&#xff0c;來個錯誤提示 還有source contro…

Elasticsearch:加快 HNSW 圖的合并速度

作者&#xff1a;來自 Elastic Thomas Veasey 及 Mayya Sharipova 過去&#xff0c;我們曾討論過搜索多個 HNSW 圖時所面臨的一些挑戰&#xff0c;以及我們是如何緩解這些問題的。當時&#xff0c;我們也提到了一些計劃中的改進措施。本文正是這項工作的成果匯總。 你可能會問…

人事|人事管理系統|基于Springboot+vue的人事管理系統設計與實現(源碼+數據庫+文檔)

人事管理系統 目錄 基于Springboot的人事管理系統設計與實現 一、前言 二、系統功能設計 三、系統實現 1、管理員登錄 2、員工管理 3、公告信息管理 4、公告類型管理 5、培訓管理 6、培訓類型管理 四、數據庫設計 1、實體ER圖 五、核心代碼 六、論文參考 七、最新…

2.4GHz射頻前端噪聲系數優化架構

2.4GHz射頻前端電路架構由信號處理鏈路、硬件模塊及性能規范構成&#xff0c;其系統組成與參數要求如下&#xff1a; 一、信號發射鏈路? 數字基帶信號通過DAC轉換為模擬信號? 調制電路將信號加載至本地振蕩器生成的2.4GHz載波? 功率放大器將信號強度提升至20-25dBm范圍? …

開源 LLM 應用開發平臺 Dify 全棧部署指南(Docker Compose 方案)

開源 LLM 應用開發平臺 Dify 全棧部署指南&#xff08;Docker Compose 方案&#xff09; 一、部署環境要求與前置檢查 1.1 硬件最低配置 組件要求CPU雙核及以上內存4GB 及以上磁盤空間20GB 可用空間 1.2 系統兼容性驗證 ? 官方支持系統&#xff1a; Ubuntu 20.04/22.04 L…

Trae AI 保姆級教程:從安裝到調試全流程指南

Trae AI 保姆級教程&#xff1a;從安裝到調試全流程指南 Trae AI 是字節跳動推出的一款 AI 原生集成開發環境(IDE)&#xff0c;專為中文開發者設計&#xff0c;集成了 Claude 3.5 和 GPT-4o 等先進 AI 模型&#xff0c;支持通過自然語言交互實現代碼生成、項目構建與調試。本教…

博物館小程序怎么做?從0到1打造數字化文化窗口

博物館小程序怎么做&#xff1f;從0到1打造數字化文化窗口 一、行業痛點&#xff1a;傳統博物館的數字化困局 在數字化浪潮下&#xff0c;傳統博物館普遍面臨三大挑戰&#xff1a; ??客流受限??&#xff1a;線下接待能力有限&#xff0c;難以觸達更廣泛人群 ??互動單一…

基于 Netty 框架的 Java TCP 服務器端實現,用于啟動一個 TCP 服務器來處理客戶端的連接和數據傳輸

代碼&#xff1a; package com.example.tpson_tcp;import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; imp…

深入解析原生鴻蒙中的 RN 日志系統:從入門到精通!

全文目錄&#xff1a; 開篇語&#x1f4d6; 目錄&#x1f3af; 前言&#xff1a;鴻蒙日志系統究竟有多重要&#xff1f;&#x1f6e0;? 鴻蒙 RN 日志系統的基礎結構&#x1f4dc; 1. 日志的作用?? 2. 日志分類 &#x1f527; 如何在鴻蒙 RN 中使用日志系統&#x1f58b;? 1…

算法訓練營Day01(二分 雙指針)

704. 二分查找 - 力扣&#xff08;LeetCode&#xff09; 關于二分查找 最重要的是要處理好邊界問題&#xff0c;每次寫完邊界可以帶入特殊值進行測試確定區間的不變量是什么&#xff1f;比如區間的左閉右閉&#xff0c;和左閉右開&#xff0c;每次二分完的新區間&#xff0c;一…

shadcn 使用步驟與注意點

目錄 一、shadcn ui 二、使用流程 1.安裝 2.顏色與主題 3.引用blocks 三、使用注意點 四、推薦搭配工具 五、總結 一、shadcn ui 官網&#xff1a;Build your component library - shadcn/ui 為何選擇它&#xff1f;因為它是一個基于 Tailwind CSS Radix UI 的組件集…

STM32CubeMX-H7-12-IIC讀寫MPU6050模塊(中)-MPU6050模塊詳解以及軟件IIC驅動

前言 上一篇我們已經完成對IIC代碼基本框架的編寫&#xff0c;以及獲取MPU6050的ID&#xff0c;接下來我們逐一分析這個模塊的功能&#xff0c;并用IIC驅動 建議看完上一篇再來看這篇 MPU6050寄存器介紹 1.電源管理寄存器&#xff08;PWR_MGMT_1&#xff0c;地址&#xff1a;0…