STM32 IIC通信

目錄

  • IIC簡介
  • 硬件電路連接
  • I2C時序基本單元
  • IIC完整數據幀
  • MPU6050封裝
  • 硬件IIC
    • 內部電路

IIC簡介

IIC(Inter-Integrated Circuit)是 IIC Bus 簡稱,中文叫集成電路總線。它是一種串行通信總線,使用多主從架構,由飛利浦公司在1980年代為了讓主板、嵌入式系統或手機用以連接低速周邊設備而發展。自2006年10月1日起,使用I2C協議已經不需要支付專利費,但制造商仍然需要付費以獲取I2C從屬設備地址。
??IIC使用兩根信號線進行通信:一根時鐘線SCL,一根數據線SDA。IIC將SCL處于高時SDA拉低的動作作為開始信號,SCL處于高時SDA拉高的動作作為結束信號;傳輸數據時,SDA在SCL低電平時改變數據,在SCL高電平時保持數據,每個SCL脈沖的高電平傳遞1位數據。

IIC通信時一種同步,半雙工的通信協議,帶數據應答,支持總線掛載多設備(一主多從、多主多從)。

也正是因為IIC是一種同步時序,所有我們可以軟件模擬,串口通信就是一種異步時序,對時序要求很嚴格,所有我們不能模擬,需要硬件短路來實現才會精準收發數據。

硬件電路連接

所有I2C設備的SCL連在一起,SDA連在一起
設備的SCL和SDA均要配置成開漏輸出模式
SCL和SDA各添加一個上拉電阻,阻值一般為4.7KΩ左右

在這里插入圖片描述
任何時候都是主機完全掌控SCL線,只有從機應答和從機發送的時候才會獲得SDA的掌控權。
IIC的設計禁止所有設備輸出強上拉的高電平。采用外置弱上拉的電阻加開漏輸出的電路結構。這么做的原因也是為了防止主機在結束的時候釋放SDA即拉高然后從機立刻拉低響應造成的短路。這個模式也存在“線與”的特性,只要有輸出低,那么最后就輸出低,所有輸出高才輸出高。
CPU和被控IC都是上圖右邊的結構。開漏輸出沒有強上拉,只有強下拉,當輸出高電平的時候,下管斷開,不輸出低,處于浮空狀態,此時就由上拉電阻拉高。

I2C時序基本單元

起始條件:SCL高電平期間,SDA從高電平切換到低電平
終止條件:SCL高電平期間,SDA從低電平切換到高電平

在這里插入圖片描述
發送一個字節:
SCL低電平期間,主機將數據位依次放到SDA線上(高位先行),然后釋放SCL,從機將在SCL高電平期間讀取數據位,所以SCL高電平期間SDA不允許有數據變化,依次循環上述過程8次,即可發送一個字節。
在這里插入圖片描述

接收一個字節:
SCL低電平期間,從機將數據位依次放到SDA線上(高位先行),然后釋放SCL,主機將在SCL高電平期間讀取數據位,所以SCL高電平期間SDA不允許有數據變化,依次循環上述過程8次,即可接收一個字節(主機在接收之前,需要釋放SDA)。
在這里插入圖片描述
發送應答: 主機在接收完一個字節之后,在下一個時鐘發送一位數據,數據0表示應答,數據1表示非應答
接收應答: 主機在發送完一個字節之后,在下一個時鐘接收一位數據,判斷從機是否應答,數據0表示應答,數據1表示非應答(主機在接收之前,需要釋放SDA,從機控制,從機拉低就是從機發送應答)

IIC完整數據幀

IIC的完成數據幀包括指定地址寫,當前地址讀,指定地址讀
IIC是一主多從的通信協議,所以如果要和某個從機進行通信必須選中某個從機,所以每個從機就需要一個地址。主機在起始條件后需要先發送一個字節,所有從機都會收到一個字節和自己的地址比較。如果和自己的地址就響應主機的操作,所有同一個IIC總線必須掛載不一樣的地址設備。從機設備地址在IIC協議標準種分為七位和十位,七位的比較簡單應用也比較廣泛。在出廠的時候,廠商就會為他分配一個七位的地址,在芯片手冊中都能找到。如果有相同的地址芯片掛在在總線上就需要使用地址的可變部分,一般都是地址的后面一位或者幾位。

一個完整的數據幀在起始條件開始,結束條件結束。
指定地址寫:
在起始條件后就要跟一個從機地址+寫標志位,然后從機發送應答。然后發送指定的地址,然后從機再次應答。

當前地址讀:
對于指定設備(Slave Address),在當前地址指針指示的地址下,讀取從機數據(Data)。
當前地址指針上電默認是0,但是當我們指定地址寫后,然后當前地址讀,就是在寫的下一位進行讀取操作。
指定地址讀:
我們使用指定地址寫的指定地址時序,但是不寫入,此時當前地址指針就不會加一。然后再調用當前地址讀的時序,然后就是指定地址讀了。我們可以在指定地址讀前面加一個結束條件,然后再次發送起始條件,在當前地址讀。但是IIC協議官方規定的符合格式是一整個數據幀,就是先起始,再重復起始(在指定地址寫的時序后面再加一個起始條件),然后發當前地址讀,最后結束了再發送結束條件。

當讀取完數據不想再讀取了,就需要主機發送非應答,此時從機知道主機不想再接收了,就會釋放總線,交還給從機。

MPU6050封裝

軟件IIC配置:
總體操作:
1.初始化GPIO,包括打開時鐘,配置結構體,初始化選用的引腳
2.配置IIC開始函數
3.配置IIC結束函數
4.配置IIC發送一個字節函數
5.配置IIC接收一個字節函數
6.配置IIC發送應答函數
7.配置IIC接收應答函數
具體操作:
1.初始化GPIO,例如,選用Pin10為SCL線,Pin11為SDA線,配置IIC的GPIO為開漏輸出

void MyI2C_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_OD;GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10 | GPIO_Pin_11;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOB,&GPIO_InitStructure);GPIO_SetBits(GPIOB,GPIO_Pin_10 | GPIO_Pin_11);
}

1.IIC不論是SDA還是SCL都只有高低兩種狀態,所有使用時就是把GPIO電平配置為高或者低
例如:

	GPIO_WriteBit(GPIOB,GPIO_Pin_10,1);Delay_us(10);GPIO_WriteBit(GPIOB,GPIO_Pin_11,1);Delay_us(10);

延時10微秒為操作時間,實測不延時也可以。
每次都配置GPIO不僅麻煩還不明了
所以就把GPIO封裝起來

void MyI2C_W_SCL(uint8_t BitValue)
{GPIO_WriteBit(GPIOB,GPIO_Pin_10,(BitAction)BitValue);Delay_us(10);
}//對SCL線封裝,便于操作,控制時鐘線
void MyI2C_W_SDA(uint8_t BitValue)
{GPIO_WriteBit(GPIOB,GPIO_Pin_11,(BitAction)BitValue);Delay_us(10);
}//對SDA線封裝,便于操作,發送主機值
uint8_t MyI2C_R_SDA(void)
{uint8_t BitValue;BitValue=GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11);Delay_us(10);return BitValue; 
}//對SDA線封裝,便于操作,讀取從機發送的值

封裝完以后便可以很簡單的配置后面的函數
2.配置開始函數
IIC開啟需要在SCL為高的時候拉低SDA,這樣為開啟IIC信號,從機便知道,IIC開啟,主機要發送或者接收數據了

void MyI2C_Start(void)
{MyI2C_W_SDA(1);/*最好先拉高SDA確定,簡要原因在最后面的讀MPU6050的注釋里面有簡要說明,這樣只是一個以防外一,個人感覺不是特別重要*/MyI2C_W_SCL(1);MyI2C_W_SDA(0);MyI2C_W_SCL(0);//拉低SDA后再把SCL拉低,便可以進行數據傳送

3.配置結束函數 IIC結束需要在SCL為高的時候拉高SDA,這樣為關閉IIC信號,從機便知道,IIC關閉,主機要結束發送或者接收數據了,實際上,在配置的IIC函數里面,只有結束函數里面SCL以高結束,其他的都為低,這樣方便兩個函數銜接。

void MyI2C_Stop(void)
{MyI2C_W_SDA(0);//先拉低SDA確保待會可以產生上升沿MyI2C_W_SCL(1);MyI2C_W_SDA(1);
}

4.配置主機發送函數
主機在SCL低的時候只會發送一位,從機在SCL為高的時候一次也只接收一位,每次都是一位一位進行的

void MyI2C_SentByte(uint8_t Byte)
{uint8_t i;for(i=0;i<8;i++){MyI2C_W_SDA(Byte&(0x80>>i));MyI2C_W_SCL(1);MyI2C_W_SCL(0);}
}

一次發送八位數據也就是一個字節的數據,所以在for循環里面循環8次
在8次數據發送完以后,主機需要釋放SDA,這時從機會自己占據SDA線給主機發送應答后面寫的主機的接收應答就會主動去釋放SDA(所有的發送和接收都是相對主機而言的)
5.配置主機接收函數

uint8_t MyI2C_ReceiveByte(void)//主機接收時,從機在時鐘線拉低的時候只會發送一位數據
{uint8_t i,Byte=0x00;MyI2C_W_SDA(1);for(i=0;i<8;i++){ MyI2C_W_SCL(1);if(MyI2C_R_SDA()==1){Byte |= (0x80>>i);}//高位先行,所以右移MyI2C_W_SCL(0);}return Byte;
}

主機接收的數據要處理,所以要用變量存起來,發送的數據從機會自動處理
6.配置IIC發送應答

void MyI2C_SentAck(uint8_t AckBit)
{MyI2C_W_SDA(AckBit);//當發送完一個數據以后,SCL本身就是低的,所以前面不需要再給SCL低了MyI2C_W_SCL(1);MyI2C_W_SCL(0);
}

發送應答是主機接收了一個數據以后發送個主機的應答,SDA拉高,相當于主機發送1,為非應答,不需要再接收數據時就要發非應答,需要接收數據時,就在SDA拉低,為應答。從機發送完一個字節數據以后,會自動釋放SDA,此時主機應占據SDA,從機便會去讀取SDA的值,接收主機的應答(應答信號在第9個時鐘周期出現,這時發送器必須在這一時鐘位上釋放數據線,由接收設備拉低SDA電平來產生應答信號或非應答信號)
7.配置IIC接收應答

uint8_t MyI2C_ReceiveAck(void)
{uint8_t AckBit;MyI2C_W_SDA(1);//主機主動空出SDA,從機會立刻占據,發送應答或者非應答信號MyI2C_W_SCL(1);//SCL拉高以后,主機便可以去讀取從機給的信號AckBit=MyI2C_R_SDA();MyI2C_W_SCL(0);//此時從機放手SDAreturn AckBit;
}

在主機發送完數據以后,主機應空出SDA線,此時從機會產生應答或者非應答,因為是軟件模擬IIC所以可以選擇讀取也可以不去讀取,選擇讀取便可以根據讀取的值判斷下一步要不要再繼續操作。因為一個時鐘信號只進行一位傳輸,所以從機檢測到電平變化以后如果接下來還是主機操作便不在占據SDA。

以上便是軟件IIC的所有配置

以MPU6050為例,演示IIC的進行
MPU6050初始化即IIC初始化
如果要給MPU6050寫一個字節的數據:

void MPU6050_WriteReg(uint8_t RegAddress, uint8_t Data)
{MyI2C_Start();//打開IIC通信MyI2C_SentByte(0xD0);//選中 MPU6050,最后一位為0為寫操作MyI2C_ReceiveAck();//從機發送應答,主機要接收應答MyI2C_SentByte(RegAddress);//主機繼續發送要寫的寄存器地址MyI2C_ReceiveAck();//主機接收從機的應答MyI2C_SentByte(Data);//主機發送要寫的數據MyI2C_ReceiveAck();//主機接收從機的應答MyI2C_Stop();//停止IIC通信SDA與SCL都為高
}

IIC開始以后,第一次發送的是硬件的地址,每一個硬件都有一個地址,出廠的時候寫好的,發送的數據前七位為地址,最后一位為讀寫位,0為寫,1為讀。
如果要讀MPU6050一個字節的數據:

uint8_t MPU6050_ReadReg(uint8_t RegAddress)//讀指定寄存器
{uint8_t Data;//接收讀出數據的變量MyI2C_Start();MyI2C_SentByte(0xD0);MyI2C_ReceiveAck();MyI2C_SentByte(RegAddress);MyI2C_ReceiveAck();//前面幾步確定地址MyI2C_Start();/*Start里面先SDA置1就是這里在上一步SCL為0的時候趕快為高然后重新開始,避免還沒為高的時候SCL已經拉高了。如果SDA還沒為高的時候SCL已經拉高了,這樣再產生下降沿之前產生的就是上升沿了,就是停止的意思了。但是接收應答后,從機釋放SDA,此時SDA就是高主機沒有進行操作,SDA一直為高,所以個人感覺不重要*/MyI2C_SentByte(0xD1);//對指定地址進行讀MyI2C_ReceiveAck();//從機要回應這個指令Data=MyI2C_ReceiveByte();//從機把指定地址的數據通過SDA線發出來MyI2C_SentAck(1);//主機回應1表示不給應答,從機便會結束發送MyI2C_Stop();//結束通信return Data;
}

因為無法直接指定寄存器讀,但可以指定寄存器寫,指定的地址指針在下一次操作前不變,所以指定地址寫,然后什么都不寫,重新開始讀,便可以指定地址讀。

再MPU5050手冊中,剛上電時是睡眠模式,無法寫入,只能讀出。所有需要解除睡眠模式,此時就需要0x6B上寫,0x6B地址是電源管理寄存器1,其中SLEEP位控制睡眠模式,在這個寄存器寫入0x00,這樣就能解除睡眠模式了。

在真正使用MPU6050之前還需要根據手冊初始化一下,比如電源管理寄存器,時鐘,陀螺儀,加速度計等各種寄存器。

#ifndef __MPU6050_REG_H
#define __MPU6050_REG_H#define SMPLRT_DIV         0x19
#define CONFIG             0x1A
#define GYRO_CONFIG        0x1B
#define ACCEL_CONFIG       0x1C
#define ACCEL_XOUT_H       0x3B
#define ACCEL_XOUT_L       0x3C
#define ACCEL_YOUT_H       0x3D
#define ACCEL_YOUT_L       0x3E
#define ACCEL_ZOUT_H       0x3F
#define ACCEL_ZOUT_L       0x40
#define TEMP_OUT_H         0x41
#define TEMP_OUT_L         0x42
#define GYRO_XOUT_H        0x43
#define GYRO_XOUT_L        0x44
#define GYRO_YOUT_H        0x45
#define GYRO_YOUT_L        0x46
#define GYRO_ZOUT_H        0x47
#define GYRO_ZOUT_L        0x48
#define PWR_MGMT_1         0x6B
#define PWR_MGMT_2         0x6C
#define WHO_AM_I           0x75
extern uint8_t AccX,AccY,AccZ,GyroX,GyroY,GyroZ;
#endif
void MPU6050_GetData(int16_t *AccX,int16_t *AccY,int16_t *AccZ,int16_t*GyroX,int16_t*GyroY,int16_t*GyroZ)
{uint8_t DataH,DataL;DataH=MPU6050_ReadReg(ACCEL_XOUT_H);DataL=MPU6050_ReadReg(ACCEL_XOUT_L);*AccX=(DataH<<8)|DataL;DataH=MPU6050_ReadReg(ACCEL_YOUT_H);DataL=MPU6050_ReadReg(ACCEL_YOUT_L);*AccY=(DataH<<8)|DataL;DataH=MPU6050_ReadReg(ACCEL_ZOUT_H);DataL=MPU6050_ReadReg(ACCEL_ZOUT_L);*AccZ=(DataH<<8)|DataL;DataH=MPU6050_ReadReg(GYRO_XOUT_H);DataL=MPU6050_ReadReg(GYRO_XOUT_L);*GyroX=(DataH<<8)|DataL;DataH=MPU6050_ReadReg(GYRO_YOUT_H);DataL=MPU6050_ReadReg(GYRO_YOUT_L);*GyroY=(DataH<<8)|DataL;DataH=MPU6050_ReadReg(GYRO_ZOUT_H);DataL=MPU6050_ReadReg(GYRO_ZOUT_L);*GyroZ=(DataH<<8)|DataL;
}
void MPU6050_Init(void)
{MyI2C_Init();MPU6050_WriteReg(PWR_MGMT_1,0x01);//電源管理1MPU6050_WriteReg(PWR_MGMT_2,0x00);//電源管理2MPU6050_WriteReg(SMPLRT_DIV,0x09);//采樣率分頻,10分頻MPU6050_WriteReg(CONFIG,0x06);//外部同步(不需要)與低通濾波MPU6050_WriteReg(GYRO_CONFIG,0x18);//陀螺儀配置寄存器MPU6050_WriteReg(ACCEL_CONFIG,0x18);//加速度計
}

硬件IIC

由于IIC是同步時序,所以軟件模擬II從時序,靈活且方便,用的范圍比較廣。
STM32內部集成了硬件IIC的電路,STM32內部集成了硬件I2C收發電路,可以由硬件自動執行時鐘生成、起始終止條件生成、應答位收發、數據收發等功能,用庫函數封裝好,直接讀取寄存器即可。減輕CPU的負擔。
比如:

支持多主機模型
支持7位/10位地址模式
支持不同的通訊速度,標準速度(高達100 kHz),快速(高達400 kHz)
支持DMA
兼容SMBus協議

STM32F103C8T6 硬件I2C資源:I2C1、I2C2

引腳映射:
C8T6的IIC2映射的PB10為SCL,PB11為SDA。IIC1的SCL為PB6,SDA為PB7。

內部電路

在這里插入圖片描述

上半部分是SDA,數據控制部分。數據收發的核心部分是上面的數據寄存器和數據移位寄存器。當需要發送數據時,可以把一個字節數據寫到數據寄存器DR。當移位寄存器沒有數據移位時,DR中的值就會轉到移位寄存器中。在移位的過程中,可以直接把下一個數據放到數據寄存器中等著。當數據由數據寄存器轉到移位寄存器時就會置狀態寄存器的TXE位為 1 ,表示發送寄存器為空。
接收的過程也是這樣,輸入的數據先放進移位寄存器,當一個字節后,數據從移位寄存器轉入DR。同時置標志位RXNE,表示接收寄存器非空。此時就可以將數據從數據寄存器讀出來了。
對于起始條件,終止條件,應答位什么的都由數據控制電路完成。

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

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

相關文章

深入解析 TypeScript 核心配置文件 tsconfig.json

什么是 tsconfig.json&#xff1f; tsconfig.json 是 TypeScript 項目的中樞神經系統&#xff0c;它是 TypeScript 編譯器的配置文件&#xff0c;決定了整個項目的編譯規則、模塊解析方式和類型檢查策略。這個 JSON 文件通常位于項目根目錄&#xff0c;是 TypeScript 工程化開…

debug 筆記:llama 3.2 部署bug 之cutlassF: no kernel found to launch!

1 問題描述 按照官方的寫法 import torch from transformers import pipeline import os os.environ["HF_TOKEN"] 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 model_id "meta-llama/Llama-3.2-3B"pipe pipeline("text-generation", modelmode…

使用ZYNQ芯片和LVGL框架實現用戶高刷新UI設計系列教程(第五講)

在上一講我們講解了按鍵回調函數的自定義函數的用法&#xff0c;這一講繼續講解回調函數的另一種用法。 首先我們將上一講做好的按鍵名稱以及自定義回調事件中的按鍵名稱修改&#xff0c;改為默認模式為“open”當點擊按鍵時進入回調函數將按鍵名稱改為“close”&#xff0c;具…

Hyperliquid 遇襲「拔網線」、Polymarket 遭治理攻擊「不作為」,從雙平臺危機看去中心化治理的進化陣痛

作者&#xff1a;Techub 熱點速遞 撰文&#xff1a;Glendon&#xff0c;Techub News 繼 3 月 12 日「Hyperliquid 50 倍杠桿巨鯨」引發的 Hyperliquid 清算事件之后&#xff0c;3 月 26 日 晚間&#xff0c;Hyperliquid 再次遭遇了一場針對其流動性和治理模式的「閃電狙擊」。…

交換機與路由器的區別:深入解析

在構建和維護現代計算機網絡的過程中&#xff0c;交換機和路由器無疑是兩種不可或缺的設備。盡管它們都在數據的傳輸和轉發中扮演著重要角色&#xff0c;但各自的工作原理、應用場景和功能特性卻大相徑庭。本文將從多個角度&#xff0c;結合最新的技術發展和實際應用&#xff0…

自頂向下學習K8S--部署Agones

本文在本人博客&#xff0c;原文地址&#xff1a;http://viogami.tech/index.php/blog/346/ 我是gopher&#xff0c;離不開云原生&#xff0c;自然也逃不了理解docker和K8S這倆。今天抽空想玩下agones&#xff0c;進而對K8S有實踐性的理解。 學一個新事物從底層理論學肯定是最…

藍橋杯省模擬賽 階乘求值

問題描述 給定 n&#xff0c;求 n! 除以 1000000007的余數。 其中 n! 表示 n 的階乘&#xff0c;值為從 1 連乘到 n 的積&#xff0c;即 n!123…n。 輸入格式 輸入一行包含一個整數 n。 輸出格式 輸出一行&#xff0c;包含一個整數&#xff0c;表示答案。 樣例輸入 3樣…

如何在Webpack中配置別名路徑?

如何在Webpack中配置別名路徑&#xff1f; 文章目錄 如何在Webpack中配置別名路徑&#xff1f;1. 引言2. 配置別名路徑的基本原理3. 如何配置別名路徑3.1 基本配置3.2 結合Babel與TypeScript3.2.1 Babel配置3.2.2 TypeScript配置 3.3 適用場景與最佳實踐 4. 調試與常見問題4.1 …

協作機械臂需要加安全墻嗎? 安全墻 光柵 干涉區

安全墻是什么 文章目錄 安全墻是什么簡介1. 物理安全墻1.1 定義&#xff1a;1.2 作用機制&#xff1a;1.3 應用場景&#xff1a; 2. 虛擬安全墻2.2 定義&#xff1a;2.3 作用機制&#xff1a;2.3 應用場景&#xff1a; 3. 安全毛毯3.1 工作原理&#xff1a;3.2 特點3.3 應用場景…

Promise怎么使用,以及它解決了什么問題?

什么是 Promise&#xff1f; Promise 是一種用于處理異步操作的 JavaScript 對象&#xff0c;它代表了一個可能還未完成但將來會完成的操作的結果。Promise 的目的是解決回調函數&#xff08;callback&#xff09;帶來的問題&#xff0c;比如回調地獄&#xff08;callback hel…

光譜范圍與顏色感知的關系

光譜范圍與顏色感知是光學、生理學及技術應用交叉的核心課題&#xff0c;兩者通過波長分布、人眼響應及技術處理共同決定人類對色彩的認知。以下是其關系的系統解析&#xff1a; ?1.基礎原理&#xff1a;光譜范圍與可見光? ?光譜范圍定義?&#xff1a; 電磁波譜中能被特定…

如何讓DeepSeek-R1在內網穩定運行并實現隨時隨地遠程在線調用

前言&#xff1a;最近&#xff0c;國產AI圈里的新星——Deepseek&#xff0c;簡直是火到不行。但是&#xff0c;你是不是已經對那些千篇一律的手機APP和網頁版體驗感到膩味了&#xff1f;別急&#xff0c;今天就帶你解鎖一個超炫的操作&#xff1a;在你的Windows電腦上本地部署…

leetcode33.搜索旋轉排序數組

思路源于 【小白都能聽懂的算法課】【力扣】【Leetcode33】搜索旋轉排序數組 | 二分查找 | 數組 主要是數組旋轉后分為左右兩個升序區間 &#xff0c;如果mid落在左區間并且目標大小也在left-mid中&#xff0c;那么right右縮 class Solution {public int search(int[] nums, i…

《TypeScript 7天速成系列》第6天:TypeScript裝飾器+混入:高級編程模式揭秘

裝飾器是TypeScript中一項強大的元編程特性&#xff0c;被Angular和Vue3等主流框架廣泛使用。今天我們將深入探討這一高級特性。 裝飾器基礎 裝飾器是一種特殊類型的聲明&#xff0c;可以附加到類聲明、方法、訪問器、屬性或參數上。裝飾器使用expression形式&#xff0c;其中…

YOLO歷代發展 圖像增強方式 架構

YOLO1 YOLOV5 數據增強 mosaic 仿射變換(Affine)、透視變換(Perspective) 網絡搭建

NX二次開發刻字功能——布爾運算

刻字功能在經歷、創建文本、拉伸功能以后就剩下布爾運算了。布爾運算的目的就是實現文本時凸還是凹。這部分內容很簡單。 1、首先識別布爾運算的類型&#xff0c;我這里用到一個枚舉類型的選項&#xff0c;凸就是布爾求和&#xff0c;凹就是布爾求差。 2、其放置位置為創建拉伸…

【MySQL基礎】數據庫及表基本操作

作為運維工程師&#xff0c;掌握MySQL的基礎操作是日常工作的重要技能之一。本文將介紹MySQL中數據庫和表的基本操作&#xff0c;幫助您快速上手或復習這些核心概念。 1 數據庫基本操作 1.1 創建數據庫 create database db_name; -- 指定字符集和排序規則 create database d…

Python貝葉斯分層模型專題|對環境健康、醫學心梗患者、體育賽事數據空間異質性實證分析合集|附數據代碼

全文鏈接&#xff1a;https://tecdat.cn/?p41267 在大數據時代&#xff0c;多水平數據結構廣泛存在于環境健康、醫學研究和體育賽事等領域。本專題合集聚焦貝葉斯分層模型&#xff08;Hierarchical Bayesian Model&#xff09;的創新應用&#xff0c;通過氡氣污染數據與 季后…

基于 Qt / HTTP/JSON 的智能天氣預報系統測試報告

目錄 一、項目概述 1.1項目背景 1.2項目目標 二、功能需求 2.1 用戶界面功能 2.2 后臺功能 三、技術選擇 3.1 開發框架與工具 3.2 第三方 API 四、UI設計 4.1界面展示 4.2stylesheet樣式 五、代碼實現 1.構造函數 2.網絡請求響應處理函數 3.處理json數據 4.更新…

GitLab 中文版17.10正式發布,27項重點功能解讀【三】

GitLab 是一個全球知名的一體化 DevOps 平臺&#xff0c;很多人都通過私有化部署 GitLab 來進行源代碼托管。極狐GitLab 是 GitLab 在中國的發行版&#xff0c;專門為中國程序員服務。可以一鍵式部署極狐GitLab。 學習極狐GitLab 的相關資料&#xff1a; 極狐GitLab 官網極狐…