【STM32單片機】#11 I2C通信(軟件讀寫)

主要參考學習資料:

B站@江協科技

STM32入門教程-2023版 細致講解 中文字幕

開發資料下載鏈接:https://pan.baidu.com/s/1h_UjuQKDX9IpP-U1Effbsw?pwd=dspb

單片機套裝:STM32F103C8T6開發板單片機C6T6核心板 實驗板最小系統板套件科協

實驗:

  • 軟件I2C讀寫MPU6050

目錄

  • I2C通信
    • 硬件電路
    • I2C時序基本單元
    • I2C時序
  • MPU6050簡介
    • MPU6050參數
    • 硬件電路
    • MPU6050框圖
    • MPU6050寄存器
  • 實驗24 軟件I2C讀寫MPU6050
    • 接線圖
    • I2C協議層
    • MPU6050驅動層
    • 主程序應用層

I2C通信

  • I2C總線(Inter IC BUS)是由Philips公司開發的一種通用數據總線。
  • 兩根通信線:SCL(Serial Clock)、SDA(Serial Data)
  • 同步半雙工通信:同步時序降低對硬件的依賴,時序穩定性更高;半雙工一根線兼具發送與接收,最大化利用資源。
  • 帶數據應答
  • 支持總線掛載多設備(一主多從,多主多從)

硬件電路

左圖為I2C典型的一主多從電路模型,CPU(單片機)為主機。主機完全掌控SCL,且在空閑狀態可以主動發起對SDA的控制。只有在從機發送數據和應答時,主機才會轉交SDA控制權給主機。被控IC為從機,可以是姿態傳感器、OLED、存儲器、時鐘模塊等。從機對于SCL在任何時刻只能被動讀取,并不允許主動發起對SDA的控制。只有在主機發送讀取從機的命令后或從機應答時,從機才能短暫地取得SDA的控制權。

所有I2C設備的SCL連在一起,SDA連在一起。由于SDA對于不同設備會在輸入和輸出之間反復切換,如果總線時序協調不當,極有可能出現兩個引腳同時輸出的狀態,若一個輸出高電平,另一個輸出低電平,會引起電源短路。為了避免該問題,I2C禁止所有設備輸出強上拉的高電平,采用外置弱上拉電阻加開漏輸出的結構,設備的SCL和SDA均須配置成開漏輸出模式。右圖為設備的引腳內部結構圖,輸入正常,輸出去掉強上拉開關管,輸出低電平時下管導通為強下拉,輸出高電平時下管斷開為浮空狀態,由外置電阻弱上拉為高電平。此時一旦有一個設備輸出低電平,則線路為低電平,只有所有設備均輸出高電平或空閑時,線路才為高電平。

I2C時序基本單元

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

起始條件和終止條件相當于串口通信的起始位和停止位,由主機發出作為數據傳輸的開始和結束。起始信號產生之后總線處于占用狀態,終止信號產生之后總線處于空閑狀態。

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

由于有時鐘線進行同步,因此即使數據傳輸中斷,SCL和SDA電平都暫停變化,時序會在中斷的位置保持不變,中斷結束后繼續傳輸也不會出現問題。

  • 接收一個字節:SCL低電平期間,從機將數據位依次放到SDA線上(高位先行)。然后主機釋放SCL,在SCL高電平期間讀取數據位,因此SCL高電平期間SDA不允許有數據變化。依次循環上述過程8次即可接收一個字節(主機在接收之前需要釋放SDA)。

  • 發送應答:主機在接收完一個字節之后,在下一個時鐘發送一位數據,數據0表示應答,數據1表示非應答。如果從機得到應答,則會繼續發送數據。
  • 接收應答:主機在發送完一個字節之后,在下一個時鐘接收一位數據,判斷從機是否應答,數據0表示應答,數據1表示非應答(主機在接收之前需要釋放SDA)。如果主機得到應答,則說明從機接收到數據并回應。

I2C時序

I2C通過給每個從設備確定一個唯一的設備地址來實現一主多從。主機在起始條件之后會先發送一個字節的從機地址,所有的從機都會收到第一個字節與自己的地址比較,如果一樣則響應主機后續讀寫操作。在同一條I2C總線中,掛載的每個設備地址必須不一樣。從機設備地址在I2C協議標準中分為7位地址和10位地址,本文只講7位地址模式,因為7位地址比較簡單且應用范圍最廣。

每個I2C設備出廠時,廠商都會為其分配一個7位地址,可以在芯片手冊中找到。一般設備地址的最后幾位可以通過指定引腳的高低電平在電路中改變,以應對相同的芯片掛載在同一條總線的情況。

  • 指定地址寫:對于指定設備(Slave Address,從設備地址)在指定地址(Reg Address,從設備內部寄存器地址)下寫入指定數據(Data)。
  • 起始條件→7位地址位+1位讀寫位(寫為0)→應答位(主機釋放,從機應答)→寄存器地址/指令控制字(由從設備定義)→應答位→寫入到寄存器的數據→應答位→停止位

  • 當前地址讀:對于指定設備(Slave Address),在當前地址指針指示的地址下,讀取從機數據(Data)。
  • 起始條件→7位地址位+1位讀寫位(讀為1)→應答位→主機釋放,從機在SCL低電平期間寫入,主機在SCL高電平期間讀取→非應答位(主機不釋放,從機得到非應答后交還控制權,否則會繼續發送下一個數據影響停止位的生成)→停止位
  • 地址指針:I2C在讀寫標志位給1后立馬轉為讀時序,主機沒有時間指定寄存器地址。在從機中,所有寄存器會被分配到一個線性區域中,并且有一個單獨的指針變量指示其中一個寄存器。該指針一般上電默認指向0地址,在對應寄存器每寫入或讀出一個字節后會自動自增一次,移動到下一個位置,從機返回當前指針指向的寄存器的值。

  • 指定地址讀:對于指定設備(Slave Address)在指定地址(Reg Address)下讀取從機數據(Data)。
  • 起始條件→7位地址位+1位讀寫位(寫)→應答位→寄存器地址→應答位→(終止條件可選)重復起始條件(切換讀寫方向)→7位地址位+1位讀寫位(讀)→應答位→讀取數據→非應答位→停止位
  • 相當于指定地址寫(只指定地址,不寫數據)→當前地址讀

如需一次性寫入多字節數據,則在指定地址寫的終止條件前繼續重復寫入數據、應答位的過程,但寄存器地址會隨著指針自增,因此該功能為從指定的位置開始,按順序連續寫入多個字節。讀取多字節數據同理。

MPU6050簡介

  • MPU6050是一個六軸姿態傳感器,可以測量芯片自身X、Y、Z軸的加速度、角速度參數,通過數據融合可進一步得到姿態角,常應用于平衡車、飛行器等需要檢測自身姿態的場景。
  • 三軸加速度計(Accelerometer):測量X、Y、Z軸的加速度。
  • 三軸陀螺儀傳感器(Gyroscope):測量X、Y、Z軸的角速度。
  • 另外,若芯片再集成一個三軸磁場傳感器則為九軸姿態傳感器,再集成一個氣壓傳感器(海拔)則為十軸姿態傳感器。

MPU6050參數

  • 16位ADC采集傳感器的模擬信號,量化范圍:-32768~32767
  • 加速度計滿量程選擇:±2/4/8/16(g)
  • 陀螺儀滿量程選擇:±250/500/1000/2000( ° ^\circ °/sec)
  • 滿量程越大,測量范圍越廣;滿量程越小,測量精度越高。
  • 可配置的數字低通濾波器/時鐘源/采樣分頻
  • I2C從機地址:1101000(AD0=0)或1101001(AD0=1)

硬件電路

MPU6050芯片中有很多引腳我們用不到,還有一些引腳為芯片最小系統的固定連接。芯片引出的排針中,XCL和XDA用于擴展芯片功能,通常外接磁力計或氣壓計,此時MPU6050的主機接口可以直接訪問并讀取這些擴展芯片的數據,由其中的DMP單元進行數據融合和姿態解算。AD0在懸空狀態下默認弱下拉為低電平。INT可以通過配置芯片內部的一些事件觸發其跳變產生中斷信號,例如數據準備完成、I2C主機錯誤等,以及芯片內置的自由落體\運動\零運動檢測功能。低壓差線性穩壓器LDO為芯片的供電邏輯,將芯片3.3V供電限制擴展到3.3~5V供電,LED為電源指示燈。

本實驗只用到VCC和GND供電,SCL和SDA接上I2C通信的GPIO口。

MPU6050框圖

框圖左上角為時鐘系統(CLOCK),灰色部分為芯片內部加速度和陀螺儀傳感器,還內置了一個溫度傳感器(Temp Sensor)。傳感器通過分壓輸出模擬電壓,并通過ADC進行模數轉換,轉換完成后的數據通過DMA統一轉移到數據寄存器(Sensor Registers)中,讀取數據寄存器即可得到傳感器測量的值。最左側的自測單元(Self test)用于驗證芯片好壞,啟動自測時,芯片內部會向傳感器施加模擬外力使值偏大,將其與關閉自測時的值相減得到的數據為自測響應。如果自測響應在芯片手冊給出的范圍內則芯片完好。電荷泵(Charge Pump)和CPOUT引腳外接電容組成升壓電路支持陀螺儀運行,其原理是先將電池與電容并聯為其充電,再將電池與電容串聯得到兩倍電壓,通過串并聯的高頻切換和電源濾波實現平穩升壓。

右側中斷狀態寄存器(Interrupt Status Register)控制內部連接中斷引腳輸出的事件,先入先出寄存器(FIFO)對數據流進行緩存,配置寄存器(Config Registers)對內部的各個電路進行配置,工廠校準(Factory Calibratior)對內部傳感器件進行校準,數字運動處理器(DMP)為芯片內部自帶的姿態解算硬件算法。幀同步(FSYNC)暫時用不到,其上方為通信接口部分,分為從機I2C通信接口和主機I2C通信接口,接口旁路選擇器(Serial Interface Bypass Mux)可以將兩路總線合并,此時STM32可以控制包括擴展功能在內的所有設備。框圖右下角為供電部分。

MPU6050寄存器

表格列1為地址,列3為寄存器名稱,列4為讀寫權限,后8列為每位功能。

功能介紹時已標明實驗所用配置。

電源管理寄存器1(默認)

765432/1/0
設備復位
(不需要)
睡眠模式
(不需要)
循環模式
(不需要)
溫度傳感器失能
(不需要)
內部時鐘000
陀螺儀時鐘001(官方推薦)

電源管理寄存器2

7/65~0
循環模式喚醒頻率
(不需要)
每個軸的待機位
(不需要)

采樣率分頻:決定數據輸出快慢,值越小越快。

配置寄存器

7/65/4/32/1/0
外部同步
(不需要)
數字低通濾波器
(110最平滑)

陀螺儀配置寄存器

7/6/54/32/1/0
自測使能
(不需要)
滿量程
(11最大)
高通濾波器
(不需要)

加速度計配置寄存器

7/6/54/32/1/0
自測使能
(不需要)
滿量程
(11最大)

每個軸的數據寄存器均分為高八位H和低八位L。

實驗24 軟件I2C讀寫MPU6050

接線圖

I2C協議層

MyI2C.h

#ifndef __MYI2C_H
#define __MYI2C_Hvoid MyI2C_Init(void);
void MyI2C_Start(void);
void MyI2C_Stop(void);
void MyI2C_SendByte(uint8_t Byte);
uint8_t MyI2C_ReceiveByte(void);
void MyI2C_SendAck(uint8_t AckBit);
uint8_t MyI2C_ReceiveAck(void);#endif

MyI2C.c

#include "stm32f10x.h"
#include "Delay.h"//封裝釋放/拉低SCL函數
void MyI2C_W_SCL(uint8_t BitValue)
{GPIO_WriteBit(GPIOB, GPIO_Pin_10, (BitAction)BitValue);//若單片機主頻過高,需要延時以滿足芯片時序性能Delay_us(10);
}//封裝釋放/拉低SDA函數
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;
}void MyI2C_Init(void)
{//配置模擬SCL、SDA的GPIO口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);
}//起始條件
void MyI2C_Start(void)
{MyI2C_W_SDA(1);MyI2C_W_SCL(1);MyI2C_W_SDA(0);MyI2C_W_SCL(0);
}//終止條件
void MyI2C_Stop(void)
{//SCL在應答位后默認低電平無需拉低MyI2C_W_SDA(0);MyI2C_W_SCL(1);MyI2C_W_SDA(1);
}//除了終止條件,其余時序單元SCL都以低電平結束
//除了起始條件,其余時序單元SCL都以高電平開始
//便于拼接//發送單字節
void MyI2C_SendByte(uint8_t Byte)
{uint8_t i;for(i = 0;i < 8;i++){//與運算和右移提取從高到低的第i位MyI2C_W_SDA(Byte & (0x80 >> i));//驅動SCL走一個脈沖MyI2C_W_SCL(1);MyI2C_W_SCL(0);}
}//接收單字節
uint8_t MyI2C_ReceiveByte(void)
{uint8_t i, Byte = 0x00;//釋放SDAMyI2C_W_SDA(1);for(i = 0;i < 8;i++){MyI2C_W_SCL(1);if(MyI2C_R_SDA())//或運算和右移將1寫入從高到低的第i位Byte |= (0x80 >> i);MyI2C_W_SCL(0);}return Byte;
}//發送應答(相當于發送一位)
void MyI2C_SendAck(uint8_t AckBit)
{MyI2C_W_SDA(AckBit);MyI2C_W_SCL(1);MyI2C_W_SCL(0);
}//接收應答(相當于接收一位)
uint8_t MyI2C_ReceiveAck(void)
{uint8_t AckBit;MyI2C_W_SDA(1);MyI2C_W_SCL(1);AckBit = MyI2C_R_SDA();MyI2C_W_SCL(0);return AckBit;
}

MPU6050驅動層

MPU6050.h

#ifndef __MPU6050_H
#define __MPU6050_Hvoid MPU6050_WriteReg(uint8_t RegAddress, uint8_t Data);
uint8_t MPU6050_ReadReg(uint8_t RegAddress);
void MPU6050_Init(void);
uint8_t MPU6050_GetID(void);
void MPU6050_GetData(int16_t *AccX, int16_t *AccY, int16_t *AccZ,int16_t *GyroX, int16_t *GyroY, int16_t *GyroZ);#endif

MPU6050.c

#include "stm32f10x.h"
#include "MyI2C.h"
#include "MPU6050_Reg.h"//宏定義從機地址(寫地址)
#define MPU6050_ADDRESS 0xD0//指定地址寫
void MPU6050_WriteReg(uint8_t RegAddress, uint8_t Data)
{MyI2C_Start();MyI2C_SendByte(MPU6050_ADDRESS);MyI2C_ReceiveAck();MyI2C_SendByte(RegAddress);MyI2C_ReceiveAck();MyI2C_SendByte(Data);MyI2C_ReceiveAck();MyI2C_Stop();
}//指定地址讀
uint8_t MPU6050_ReadReg(uint8_t RegAddress)
{uint8_t Data;MyI2C_Start();MyI2C_SendByte(MPU6050_ADDRESS);MyI2C_ReceiveAck();MyI2C_SendByte(RegAddress);MyI2C_ReceiveAck();MyI2C_Start();//變為讀地址MyI2C_SendByte(MPU6050_ADDRESS | 0x01);MyI2C_ReceiveAck();Data = MyI2C_ReceiveByte();//讀取最后一個字節后給非應答MyI2C_SendAck(1);MyI2C_Stop();return Data;
}void MPU6050_Init(void)
{MyI2C_Init();//配置MPU6050寄存器,詳見其介紹部分MPU6050_WriteReg(MPU6050_PWR_MGMT_1, 0x01);MPU6050_WriteReg(MPU6050_PWR_MGMT_2, 0x00);MPU6050_WriteReg(MPU6050_SMPLRT_DIV, 0x09);MPU6050_WriteReg(MPU6050_CONFIG, 0x06);MPU6050_WriteReg(MPU6050_GYRO_CONFIG, 0x18);MPU6050_WriteReg(MPU6050_ACCEL_CONFIG, 0x18);
}//獲取芯片ID
uint8_t MPU6050_GetID(void)
{return MPU6050_ReadReg(MPU6050_WHO_AM_I);
}//獲取數據寄存器
//使用指針傳遞地址實現多參數返回
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(MPU6050_ACCEL_XOUT_H);DataL = MPU6050_ReadReg(MPU6050_ACCEL_XOUT_L);//高八位左移八位與低八位合并*AccX = (DataH << 8) | DataL;DataH = MPU6050_ReadReg(MPU6050_ACCEL_YOUT_H);DataL = MPU6050_ReadReg(MPU6050_ACCEL_YOUT_L);*AccY = (DataH << 8) | DataL;DataH = MPU6050_ReadReg(MPU6050_ACCEL_ZOUT_H);DataL = MPU6050_ReadReg(MPU6050_ACCEL_ZOUT_L);*AccZ = (DataH << 8) | DataL;DataH = MPU6050_ReadReg(MPU6050_GYRO_XOUT_H);DataL = MPU6050_ReadReg(MPU6050_GYRO_XOUT_L);*GyroX = (DataH << 8) | DataL;DataH = MPU6050_ReadReg(MPU6050_GYRO_YOUT_H);DataL = MPU6050_ReadReg(MPU6050_GYRO_YOUT_L);*GyroY = (DataH << 8) | DataL;DataH = MPU6050_ReadReg(MPU6050_GYRO_ZOUT_H);DataL = MPU6050_ReadReg(MPU6050_GYRO_ZOUT_L);*GyroZ = (DataH << 8) | DataL;
}

主程序應用層

#include "stm32f10x.h" 
#include "Delay.h"
#include "OLED.h"
#include "MPU6050.h"uint8_t ID;
int16_t AX, AY, AZ, GX, GY, GZ;int main(void)
{OLED_Init();MPU6050_Init();OLED_ShowString(1, 1, "ID:");ID = MPU6050_GetID();OLED_ShowHexNum(1, 4, ID, 2);while(1){MPU6050_GetData(&AX, &AY, &AZ, &GX, &GY, &GZ);OLED_ShowSignedNum(2, 1, AX, 5);OLED_ShowSignedNum(3, 1, AY, 5);OLED_ShowSignedNum(4, 1, AZ, 5);OLED_ShowSignedNum(2, 8, GX, 5);OLED_ShowSignedNum(3, 8, GY, 5);OLED_ShowSignedNum(4, 8, GZ, 5);}
}

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

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

相關文章

每天一道面試題@第一天

1&#xff1a;TCP和UDP的區別&#xff0c;TCP為什么是三次握手&#xff0c;不是兩次&#xff1f; 因為TCP是全雙工協議&#xff0c;區別在于TCP可靠&#xff0c;UDP不可靠&#xff0c;效率更高。 詳解&#xff1a; TCP&#xff08;傳輸控制協議&#xff09;和 UDP&#xff08;…

一款強大的實時協作Markdown工具 | CodiMD 9.6K ?

CodiMD 介紹 CodiMD 是一個開源的實時協作 Markdown 筆記工具&#xff0c;它允許用戶在任何平臺上共同編輯 Markdown 文檔。核心功能是實時協作&#xff0c;它允許多個用戶同時編輯同一個文檔&#xff0c;并實時看到彼此的更改。支持實時渲染預覽&#xff0c;支持超多的富文本格…

若依如何切換 tab 不刷新

方法 如上圖配置 菜單中選是否緩存&#xff1a;緩存 資料 前端手冊 |RuoYi:

【浙江大學DeepSeek公開課】回望AI三大主義與加強通識教育

回望AI三大主義與加強通識教育 一、人工智能三大主義二、人工智能發展歷程三、從 ChatGPT 到 DeepSeek四、人工智能通識教育五、人工智能的挑戰與未來 一、人工智能三大主義 符號主義 &#xff1a;邏輯推理&#xff0c;將推理視為計算過程。如蘇格拉底三段論&#xff0c;通過前…

邊緣計算全透視:架構、應用與未來圖景

邊緣計算全透視&#xff1a;架構、應用與未來圖景 一、產生背景二、本質三、特點&#xff08;一&#xff09;位置靠近數據源&#xff08;二&#xff09;分布式架構&#xff08;三&#xff09;實時性要求高 四、關鍵技術&#xff08;一&#xff09;硬件技術&#xff08;二&#…

C++——多態、抽象類和接口

目錄 多態的基本概念 如何實現多態 在C中&#xff0c;派生類對象可以被當作基類對象使用 編程示例 關鍵概念總結 抽象類 一、抽象類的定義 基本語法 二、抽象類的核心特性 1. 不能直接實例化 2. 派生類必須實現所有純虛函數才能成為具體類 3. 可以包含普通成員函數和…

初級達夢dba的技能水準

在x86環境&#xff08;windows、linux&#xff09;安裝單機軟件&#xff0c;安裝客戶端創建過至少20套數據庫&#xff0c;優化參數并更新過正式許可會用邏輯導出導入以及dmrman備份了解manager工具的使用配置sqllog日志&#xff0c;并能解釋輸出內容能夠分析因磁盤空間不足、內…

監控頁面卡頓PerformanceObserver

監控頁面卡頓PerformanceObserver 性能觀察器掘金 const observer new PerformanceObserver((list) > {}); observer.observe({entryTypes: [longtask], })

智能座艙測試內容與步驟

智能座艙的測試步驟通常包括以下環節&#xff1a; 1.測試環境搭建與準備 ? 硬件需求分析&#xff1a;準備測試車輛、服務器與工作站、網絡設備以及傳感器和執行器模擬器等硬件設備。 ? 軟件需求分析&#xff1a;選擇測試管理軟件、自動化測試工具、模擬軟件和開發調試工具等。…

Redis——網絡模型

目錄 前言 1.用戶空間和內核空間 1.2用戶空間和內核空間的切換 1.3切換過程 2.阻塞IO 3.非阻塞IO 4.IO多路復用 4.1.IO多路復用過程 4.2.IO多路復用監聽方式 4.3.IO多路復用-select 4.4.IO多路復用-poll 4.5.IO多路復用-epoll 4.6.select poll epoll總結 4.7.IO多…

電力系統中為什么采用三相交流電?

電力系統中為什么采用三相交流電 電力系統中采用三相交流電&#xff0c;主要是因為它在輸電效率、設備使用、能量傳輸平穩性等方面相比單相交流或直流電具有顯著優勢。下面我詳細解釋一下原因&#xff1a; &#x1f31f; 1. 提高輸電效率&#xff08;節省電纜材料&#xff09;…

python簡介與入門

目錄 python初始 python的優勢 python的特性 python的應用領域 Linux環境中安裝python 下載python3.11.6 安裝依賴包 解壓python壓縮包 安裝python 編譯及安裝 建立軟連接 測試python3運行 設置國內pip更新源 更新pip版本&#xff08;必須更新&#xff09; wind…

Web內網滲透知識大全

內網滲透 端口轉發 需要三個主機&#xff0c;Windows7、Windows2016、kali Windows7為內網主機 Windows2016為跳板機 kali為攻擊機 使用到的工具 netsh、MSF 我們先在Windows7上開啟一個80服務&#xff0c;而這個80服務只能由Windows2016訪問&#xff0c;kali不能訪問 我們…

ffmpeg av_buffer_unref的邏輯實現; av_freep 和 av_freep函數的區別

av_buffer_unref 是 FFmpeg 中用于管理引用計數和內存釋放的核心函數&#xff0c;其內部實現機制如下&#xff1a; ?一、核心流程? ?引用計數遞減? 函數首先對 AVBufferRef 的 buffer->refcount 進行原子遞減操作&#xff08;通過 atomic_fetch_add_explicit 等機制保證…

從 GPS 數據中捕捉城市休閑熱點:空間異質性視角下的新框架

從 GPS 數據中捕捉城市休閑熱點&#xff1a;空間異質性視角下的新框架 原文&#xff1a;Capturing urban recreational hotspots from GPS data: A new framework in the lens of spatial heterogeneity 1. 背景與意義 城市娛樂活動的重要性&#xff1a; 娛樂活動是城市生活…

rk3568main.cc解析

rk3568main.cc解析 前言解析前言 正點原子rk3568學習,rk官方RKNN_MODEL_ZOO文件中 rknn_model_zoo-main/examples/mobilenet/cpp/main.cc 從執行命令:./build-linux.sh -t rk3568 -a aarch64 -d mobilenet 到: cmake ../../examples/mobilenet/cpp \-DTARGET_SOC=rk356x\…

【實驗數據處理matlab程序】程序1:繪制figure文件中曲線的RMS值

立意 在本課題所涉及的實驗中&#xff0c;需要將2個拉線式位移傳感器中的數據收集并處理&#xff0c;在此基礎上求解相應的速度 主要功能 針對一個figure文件中僅包含一個plot&#xff0c;且該plot中包含指定數目的曲線&#xff0c;求這些曲線的RMS值&#xff1b;針對一個fi…

kotlin的kmp編程中遇到Unresolved reference ‘java‘問題

解決辦法 打開 File → Project Structure → Project 確保 Project SDK 是 與你的 jvmToolchain 保持一致 如果沒有&#xff0c;點擊右上角 Add SDK 添加 JDK 路徑 同步Sync 然后就正常了。 package org.example.projectimport androidx.compose.animation.AnimatedVi…

靜電放電測試中垂直和水平耦合板的作用

在靜電放電&#xff08;ESD&#xff0c;Electrostatic Discharge&#xff09;測試中&#xff0c;垂直耦合板&#xff08;Vertical Coupling Plane, VCP&#xff09;和水平耦合板&#xff08;Horizontal Coupling Plane, HCP&#xff09;是模擬設備在實際環境中因靜電放電產生的…

Web開發-JavaEE應用JNDI注入RMI服務LDAP服務DNS服務高版本限制繞過

知識點&#xff1a; 1、安全開發-JavaEE-JNDI注入-LADP&RMI&DNS等 2、安全開發-JavaEE-JNDI注入-項目工具&手工原理等 演示案例-WEB開發-JavaEE-JNDI注入&LDAP&RMI服務&DNS服務&高版本限制繞過 JNDI全稱為 Java Naming and DirectoryInterface&am…