STM32中斷(NVIC和EXIT)

CM3 內核支持 256 個中斷,其中包含了 16 個內核中斷和 240個外部中斷,并且具有 256 級的可編程中斷設置。但STM32 并沒有使用CM3內核的全部東西,而是只用了它的一部分。STM32有 76 個中斷,包括16 個內核中斷和 60 個可屏蔽中斷,具有 16 級可編程的中斷優先級。而常用的就是這 60個可屏蔽中斷。

?NVIC 即嵌套向量中斷控制器,全稱 Nested vectored interrupt controller。屬于是內核的器件,其作用是對STM32中的中斷進行管理,因為M3內核中的中斷數量很多,當同時出現多個中斷時,優先處理哪個中斷?以及那些中斷不處理等,都要靠NVIC 進行控制。

在 MDK 內,與 NVIC 相關的寄存器,MDK 為其定義了如下的結構體:

typedef struct
{
vu32 ISER[2];
U32 RESERVEDO[30];
vu32 ICER[2];
u32 RSERVEDI[30];
vu32 ISPR[2];
u32 RESERVED2[30];
vu32 ICPR[2];
u32 RESERVED3[30];
vu32 IABR[2];
u32 RESERVED4[62];
vu32 IPR[15];
} NVIC TypeDef;

ISER[2]:ISER 全稱是:Interrupt Set-En able Registers ,這是一個中斷使能寄存器組上面說了 STM32 的可屏蔽中斷只有 60個,這里用了2個32 位的寄存器,總共可以表示64 個中斷。而 STM32 只用了其中的前 60 位。ISER[0]的 bit0~bit31 分別對應中斷 0~31。
ISER[1]的 bit0~27 對應中斷 32~59 ;這樣總共 60 個中斷就分別對應上了。你要使能某個中斷,必須設置相應的 ISER位為1,使該中斷被使能(這里僅僅是使能,還要配合中斷分組、屏蔽、I0 口映射等設置才算是一個完整的中斷設置)。

ICER[2]:全稱是:Interrupt Clear-Enable Registers ,是一個中斷除能寄存器組。該寄存器組與ISER 的作用恰好相反,是用來清除某個中斷的使能的。其對應位的功能,也和ICER 一樣。這里要專門設置一個ICER 來清除中斷位,而不是向 ISER 寫0來清除,是因為 NVIC的這些寄存器都是寫1有效的,寫0是無效的。

ISPR[2]:全稱是:Interrupt Set-Pending Registers ,是一個中斷掛起控制寄存器組。每個位對應的中斷和ISER 是一樣的。通過置1,可以將正在進行的中斷掛起,而執行同級或更高級別的中斷。寫0是無效的。


ICPR[2]:全稱是:Interrupt Clear-Pending Registers ,是一個中斷解掛控制寄存器組其作用與ISPR 相反,對應位也和 ISER 是一樣的。通過設置1,可以將掛起的中斷接掛寫 0無效。

IABR[2]:全稱是:Active Bit Registers,是一個中斷激活標志位寄存器組。對應位所代表的中斷和 ISER 一樣,如果為1,則表示該位所對應的中斷正在被執行。這是一個只讀寄存器,通過它可以知道當前在執行的中斷是哪一個。在中斷執行完了由硬件自動清零。

IPR[15]:全稱是:Interrupt Priority Registers ,是一個中斷優先級控制的寄存器組。這個寄存器組相當重要!STM32的中斷分組與這個寄存器組密切相關。IPR 寄存器組由15 個32bit 的寄存器組成,每個可屏蔽中斷占用 8bit,這樣總共可以表示 15*4-60 個可屏蔽中斷剛好和 STM32 的可屏蔽中斷數相等。IPR[0]的[31~24],[23~16],[15~8],[7~0]分別對應中中斷 3~0 ,依次類推,總共對應 60 個外部中斷。而每個可屏蔽中斷占用的 8bit 并沒有全部使用,而是只用了高4位。這 4位,又分為搶占優先級和子優先級。搶占優先級在前,子優先級在后。而這兩個優先級各占幾個位又要根據 SCB->AIRCR 中中斷分組的設置來決定。

STM32 將中斷分為5個組,組0~4 。該分組的設置是由 SCB->AIRCR 寄存器的 bit10~8來定義的。具體的分配關系如下表所示:

通過這個表,可以清楚的看到組 0~4 對應的配置關系,例如組設置為 4,那么此時所有的 60個中斷,每個中斷的中斷優先寄存器的高四位中的最高 4 位是搶占優先級,低 0位是響應優先級。每個中斷,你可以設置搶占優先級為0~15,響應優先級為0。搶占優先級的級別高于響應優先級。而數值越小所代表的優先級就越高。

假定設置中斷優先級組為 2,然后設置中斷 3(RTC 中斷)的搶占優先級為3,響應優先級為1。中斷6(外部中斷0)的搶占優先級為4,響應優先級為0。中斷7(外部中斷1)的搶占優先級為3,響應優先級為0。那么這 3 個中斷的優先級順序為:中斷 7>中斷 3>中斷 6。

如果兩個中斷的響應優先級和響應優先級都是一樣的話,則看哪個中斷先發生就先執高優先級的搶占優先級是可以打斷正在進行的低搶占優先級中斷的。

而搶占優先級相同的中斷,高優先級的響應優先級不可以打斷低響應優先級的中斷。上面例子中的中斷3 和中斷 7 都可以打斷中斷6 的中斷。而中斷 7 和中斷3 卻不可以相互打斷!

第一個介紹的是 NVIC 的分組函數 MY_NVIC_PriorityGroupConfig,該函數的參數NVIC_Group 為要設置的分組號,可選范圍為0~4 ,總共5 組。如果參數非法,將可能導致不可預料的結果。MY_NVIC_PriorityGroupConfig函數代碼如下:

MY_NVIC_PriorityGroupConfig(3);
void MY_NVIC_PriorityGroupConfig(u8 NVIC_Group)
{u32 temp, templ;temp1=(~NVIC_Group)&0x07;//取后三位templ<<=8;temp=SCB->AIRCR;/讀取先前的設置temp&=0X0000F8FF;//清空先前分組temp|=0X0SFA0000;//寫入鑰匙temp|-templ;SCB->AIRCR=temp;//設置分組
}

通過前面的介紹,我們知道 STM32的5 個分組是通過設置 SCB->AIRCR 的BITT[10:8]來實現的,而我們知道 SCB->AIRCR 的修改需要通過在高 16 位寫入0XO5FA 這個密鑰才能修改的,故在設置 AIRCR 之前,應該把密鑰加入到要寫入的內容的高 16 位,以保證能正常的寫入 AIRCR。在修改 AIRCR 的時候,我們一般采用讀-> 改-> 寫的步驟,來實現不改變 AIRCR 原來的其他設置。以上就是 MY_NVIC_PriorityGroupConfig函數設置中斷優先級分組的思路。

第二個函數是 NVIC 設置函數 MY_NVIC_Init,該函數有 4 個參數,分別為:

NVIC _PreemptionPriority 、NVIC_SubPriority 、NVIC_Channel、NVIC_Group。第一個參數NVIC_PreemptionPriority 為中斷搶占優先級數值,第二個參數 NVIC_SubPriority 為中斷子優先級數值,前兩個參數的值必須在規定范圍內,否則也可能產生意想不到的錯誤。第三個參數 NVIC _Channel 為中斷的編號(范圍為 0~59),最后一個參數 NVIC_Group 為中斷分組設置(范圍為0~4)。該函數代碼如下:

void MY_NVIC_Init(u8 NVIC__PreemptionPriority
u8 NVIC_SubPriority
u8 NVIC_Channel , u8 NVIC_Group)
{u32 temp;u8 IPRADDR=NVIC_Channel/4;/每組只能存4個,得到組地址u8 IPROFFSET=NVIC_Channel%4;//在組內的偏移IPROFFSET=IPROFFSET*8+4;// 得到偏移的確切位置MY_NVIC_PriorityGroupConfig(NVIC_Group)://設置分組temp=NVIC_PreemptionPriority<<(4-NVIC_Group);temp|=NVIC_SubPriority&(0x0f>>NVIC_Grup);temp&=0經//取低四位if(NVIC Channel<32)NVIC->ISER[0]=1<<NVIC_Channel;//使能中斷位(要清除的話,相反操作就 OK)else NVIC->ISER[1]|=1<<(NVIC_Channel-32);NVIC->IPR[IPRADDR]|=temp<<IPROFFSET;//設置響應優先級和搶斷優先級
}

通過前面的介紹,我們知道每個可屏蔽中斷的優先級的設置是在IPR寄存器組里面的,每個中斷占8位,但只用了其中的4個位,以上代碼就是根據中斷分組情況,來設置每個中斷對應的高4位的數值的。當然在該函數里面還引用MY_NVIC_PriorityGroupConfg 這個函數來設置分組。其實這個分組函數在每個系統里面只要設置一次就夠了,設置多次,則是以最后的那一次為準。但是只要多次設置的組號都是一樣,就沒事。否則前面設置的中斷會因為后面組的變化優先級會發生改變,這點在使用的時候要特別注意!

一個系統代碼里面,所有的中斷分組都要統一!!

以上代碼對要配置的中斷號默認是開啟中斷的。也就是ISER中的值設置為1了

通過上面兩個函數就實現了對 NVIC 的管理和配置。但是外部中斷的設置,還需要配相關寄存器才可以。下面就介紹

外部中斷的配置和使用。

中斷和事件的理解

中斷:要進入NVIC,有相應的中斷服務函數,需要CPU處理;

事件:不進入NVIC,僅用內部硬件自動控制,TIM,DMA,ADC等

STM32 的 EXTI控制器支持19個外部中斷/事件請求。每個中斷設有狀態位,每個中事件都有獨立的觸發和屏蔽設置。

STM32的19個外部中斷為(EXIT線說明):

線 0~15:對應外部 I0 口的輸入中斷。
線 16:連接到 PV 輸出。
線 17:連接到 RTC 鬧鐘事件。
線 18:連接到 USB 喚醒事件。
對于外部中斷 EXTI控制 MDK 定義了如下結構體:

ypedef struct
{
vu32 IMR;
vu32 EMR;
vu32 RTSR;
vu32 FTSR;
vu32 SWIER;
vu32 PR;
}EXTI TypeDef;

IMR :中斷屏蔽寄存器。這是一個 32 寄存器。但是只有前 19 位有效。當位 x 設置為1時,則開啟這個線上的中斷,否則關閉該線上的中斷。


該寄存器的主要作用只有一個,就是是否允許來自中斷線上的中斷信號進入NVIC中斷控制器。?

EMR:事件屏蔽寄存器,同IMR,只是該寄存器是針對事件的屏蔽和開啟。

RTSR:上升沿觸發選擇寄存器。該寄存器同IMR ,也是一個32為的寄存器,只有前 19 位有效。位 x 對應線x 上的上升沿觸發,如果設置為 1,則是允許上升沿觸發中斷/事件。否則,不允許。

?該寄存器主要用于控制輸入線進來的輸入信號,上升沿時是否在邊沿檢測電路被檢測出,20位共控制20條EXIT線;


FTSR:下降沿觸發選擇寄存器。同PTSR,不過這個寄存器是設置下降沿的。下降沿和上升沿可以被同時設置,這樣就變成了任意電平觸發了。

?該寄存器主要用于控制輸入線進來的輸入信號,下升沿時是否在邊沿檢測電路被檢測出,20位共控制20條EXIT線;?


SWIER:軟件中斷事件寄存器。通過向該寄存器的位x寫入1,在未設置 IMR 和EMR 的時候,將設置 PR 中相應位掛起。如果設置了IMR 和EMR 時將產生一次中斷。被設置的 SWIER 位,將會在 PR 中的對應位清除后清除。

PR:掛起寄存器。當外部中斷線上發生了選擇的邊沿事件,該寄存器的對應位會被置為1。0,表示對應線上沒有發生觸發請求。通過向該寄存器的對應位寫入1可以清除該位。在中斷服務函數里面經常會要向該寄存器的對應位寫1來清除中斷請求。

該寄存器的作用主要有兩個:

1、檢測外部中斷線上是否發生了選擇的邊沿事件,如果發生了,該位置1,并將信號傳遞給?與門電路,進而進入NVIC中;

2、在該位手動(軟件)寫入1,可以清除之前中斷信號的1,主要作用是進入中斷后,清除中斷位,防止多次進入中斷;

但是對于外部中斷來說,我們只需要掌握其中四個寄存器:上升沿觸發選擇寄存器(EXTI_RTSR)、下降沿觸發選擇寄存器(EXTI_FTSR)、掛起寄存器(EXTI_PR)與中斷屏蔽寄存器(EXTI_IMR)

通過以上配置就可以正常設置外部中斷了,但是外部I0 口的中斷,還需要一個寄存器配置,也就是 I0 復用里的外部中斷配置寄存器 EXTICR 。這是因為 STM32 任何一個 IO 口都可以配置成中斷輸入口,但是 10 口的數目遠大于中斷線數(16 個)。于是 STM32 就這樣設計,GPIOA~GPIOG 的[15:0]分別對應中斷線 15~0。這樣每個中斷線對應了最多 7個IO口,以線0為例:它對應了 GPIOA.0 、PIOB.0、GPIOC0 、GPIOD.0 、GPIOE.0、GPIOF.0、GPIOG.0。而中斷線每次只能連接到1個IO口上,這樣就需要 EXTICR 來決定對應的中斷線配置到哪個 GPIO 上了EXTICR 在 AFIO 的結構體中定義,如下:

typedef struct
{
vu32 EVCR;
vu32 MAPR;
vu32 EXTICR[4];
}AFIO TypeDef;

EXTICR 寄存器組,大小為4。每個 EXTICR 只用了其低 16 位。

比如我要設置 GPIOD.1 映射到1,則只要設置 EXTICR[0]的 bit[7:4] 為0011 即可。
默認都是 0000 即映射到 GPIOA。

void Ex_NVIC_Config(u8 GPIOx , u8 BITx, u8 TRIM)
{u8 EXTADDR;u8 EXTOFFSET;EXTADDR=BITx/4://得到中斷寄存器組的編號EXTOFFSET=(BITx%4)*4;RCC->APB2ENR|=0x01;//使能 io 復用時鐘AFIO->EXTICR[EXTADDR]|=GPIOx<<EXTOFFSET;//EXTI.BITx 映射到 GPIOx.BITx//自動設置EXTI->IMR|=1<<BITx;// 開啟 line BITx 上的中斷EXTI->EMR|=1<<BITx;//不屏蔽 line BITx 上的事件if(TRIM&0x01)EXTI->FTSR|=1<<BITx;//line BITx 上事件下降沿觸發if(TRIM&0x02)EXTI->RTSR|=1<<BITx://ine BITx 上事件上升降沿觸發
}

該函數有3 個參數:GPIOx 為 GPIOA~G(0~6 ),在 sys.h 里面有定義。代表要配置的 IO口。BITx則代表這個 IO 口的第幾位。TRIM 為觸發方式,低 2 位有效(0x01 代表下降觸發;0x02 代表上升沿觸發:0x03 代表意電平觸發)。


外部中斷配置函數只針對 GPIOA~G;不包括 fVD ,RTC 和 USB喚醒這三個;


參數:GPIOx:0~6 ,代表 GPIOA~G;BITx:需要使能的位;TRIM:觸發模式,1,下升沿;2 ,上降沿:3 ,任意電平觸發


該函數一次只能配置1個IO口,多個IO口,需多次調用 該函數會自動開啟對應中斷,以及屏蔽線.?

Ex_NVIC_Confg 完全是按照我們之前的分析來編寫的,首先根據 GPIOx 的位得到中斷寄存器組的編號,即 EXTICR 的編號,在 EXTICR 里面配置中斷線應該配置到 GPIOx的哪個位。然后使能該位的中斷及事件,最后配置觸發方式。這樣就完成了外部中斷的的配置了。從代碼中可以看到該函數默認是開啟中斷和事件的。其次還要注意的一點就是該函數一次只能配置一個 10 口,如果你有多個IO口需要配置,則多次調用這個函數就可以了。

STM32 的每個 IO 口都可以作為中斷輸入。要把 IO 口作為外部中斷輸入,有以下幾個步驟:


第一步 初始化 IO 口為輸入。

這一步設置你要作為外部中斷輸入的 IO 口的狀態,可以設置為上拉/下拉輸入,也可以設置為浮空輸入,但浮空的時候外部一定要帶上拉,或者下拉電阻。否則可能導致中斷不停的觸發。在干擾較大的地方,就算使用了上拉/下拉,也建議使用外部上拉/下拉電阻,這樣可以一定程度防止外部干擾帶來的影響。

第二步 開啟 IO 口復用時鐘,設置 IO 口與中斷線的映射關系。

STM32 的 IO 口與中斷線的對應關系需要配置外部中斷配置寄存器 EXTICR,這樣我們要先開啟復用時鐘,然后配置IO口與中斷線的對應關系。才能把外部中斷與中斷線連接起來。

第三步 開啟與該 IO 口相對的線上中斷/ 事件,設置觸發條件。

這一步,我們要配置中斷產生的條件,STM32可以配置成上升沿觸發,下降沿觸發,或者任意電平變化觸發,但是不能配置成高電平觸發和低電平觸發。這里根據自己的實際情況來配置。

第四步 配置中斷組(NVIC),并使能中斷。

這一步,我們就是配置中斷的分組,以及使能,對STM32的中斷來說,只有配置了NVIC的設置,并開啟才能被執行,否則是不會執行到中斷服務函數里面去的。

第五步 編寫中斷服務函數。

這是中斷設置的最后一步,中斷服務函數,是必不可少的,如果在代碼里面開啟了中斷,但是沒編寫中斷服務函數,就可能引起硬件錯誤,從而導致程序崩潰!所以在開啟了某個中斷后,一定要記得為該中斷編寫服務函數。在終端服務函數里面編寫你要執行的中斷后的操作。

點亮一個LED燈,按一下亮,按一下滅

通過寄存器實現

Void Exti_Init(void)
{RCC->APB2ENRI=1<<5;//使能PORTD時鐘
//第一步 初始化 IO 口為輸入GPIOD->CRH&=0XFFFFFOFF;//PD10設置成輸入GPIOD->CRHI=0X00000800;GPIOD->ODR|=1<<10;//PD10上拉
//第二、三步 開啟 IO 口復用時鐘,開啟與該 IO 口相對的線上中斷/ 事件,設置觸發條件Ex_NVIC_Config(GPIO_D,10,FTIR);//下降沿觸發
//第四步 配置中斷組(NVIC),并使能中斷。MY_NVIC_Init(2,1,EXTI15_10_IRchannel,2);//搶占2,子優先
}
//第五步 編寫中斷服務函數
void EXTI15_10_IRHandler(void)
{delay_ms(10);if(KEY5==0)LEDO=!LEDO;EXTI->PR=1<<10;//清除LINE10上的中斷標志位
}

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

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

相關文章

Dify中的RAG和知識庫

一.RAG 基本架構 當用戶提問 “美國總統是誰&#xff1f;” 時&#xff0c;系統并不是將問題直接交給大模型來回答&#xff0c;而是先將用戶問題在知識庫中進行向量搜索&#xff0c;通過語義相似度匹配的方式查詢到相關的內容&#xff08;拜登是美國現任第46屆總統…&#xff0…

對比多種方法執行命令行命令

在這兩種方法中&#xff0c;一種是使用argparse模塊來模擬命令行參數的解析&#xff0c;另一種是使用subprocess模塊來直接執行一個命令行命令。下面是對兩種方法的詳細比較&#xff1a; 使用argparse模擬命令行參數 這種方法主要用于在Python腳本內部測試或集成其他使用argp…

深入剖析C++的 “屬性“(Attribute specifier sequence)

引言 在閱讀開源項目源代碼是&#xff0c;發現了一個有趣且特殊的C特性&#xff1a;屬性。 屬性&#xff08;attribute specifier sequences&#xff09;是在C11標準引入的。在C11之前&#xff0c;編譯器特有的擴展被廣泛用來提供額外的代碼信息。例如&#xff0c;GNU編譯器&…

AcWing 3587:連通圖 ← dfs(鄰接矩陣 or 鏈式前向星)

【題目來源】https://www.acwing.com/problem/content/3590/【題目描述】 給定一個無向圖和其中的所有邊&#xff0c;判斷這個圖是否所有頂點都是連通的。【輸入格式】 輸入包含若干組數據。 每組數據第一行包含兩個整數 n 和 m&#xff0c;表示無向圖的點和邊數。 接下來 m 行…

Java面試題系列 - 第5天

題目&#xff1a;Java Lambda表達式與Stream API的深度應用 背景說明&#xff1a;Java 8引入了Lambda表達式和Stream API&#xff0c;極大地提升了Java函數式編程的能力&#xff0c;使代碼更簡潔、更易讀。掌握Lambda表達式和Stream API的使用&#xff0c;對于優化數據處理流程…

Qt/C++項目積累: 2.主機監控器 - 2.2 歷史功能實現

修訂歷史&#xff1a; 20240711&#xff1a;初始表設計&#xff0c;采用sqlite 正文&#xff1a; 關于歷史數據存儲&#xff0c;考慮的是用數據庫來完成&#xff0c;目前考慮使用Sqlite和mysql&#xff0c;先用sqlite來實現&#xff0c;設計表過程如下&#xff1a; 機器總覽…

白騎士的C++教學進階篇 2.1 指針與引用

系列目錄 上一篇&#xff1a;白騎士的C教學基礎篇 1.5 數據結構 指針和引用是C中非常重要的概念&#xff0c;它們提供了強大的功能&#xff0c;使程序員能夠直接操作內存&#xff0c;提高程序的效率和靈活性。在本篇博客中&#xff0c;我們將深入探討指針與引用的基礎知識&…

從零開始學習嵌入式----Makefile工具

一、Makefile 簡明指南 你是否曾經面對過一堆源代碼文件&#xff0c;卻不知道如何將它們編譯成可執行文件&#xff1f;或者你是否厭倦了每次修改代碼后都要手動輸入冗長的編譯命令&#xff1f; 如果是的話&#xff0c;那么 Makefile 就是你的救星&#xff01; 二、Makefile 是什…

全網最適合入門的面向對象編程教程:14 類和對象的 Python 實現-類的靜態方法和類方法,你分得清嗎?

全網最適合入門的面向對象編程教程&#xff1a;14 類和對象的 Python 實現-類的靜態方法和類方法&#xff0c;你分得清嗎&#xff1f; 摘要&#xff1a; 本文主要介紹了Python中類和對象中的類方法和靜態方法&#xff0c;以及類方法和靜態方法的定義、特點、應用場景和使用方…

網安防御保護-小實驗

1、DMZ區內的服務器&#xff0c;辦公區僅能在辦公時間內(9:00-18:00)可以訪問&#xff0c;生產區的設備全天可以訪問 2、生產區不允許訪問互聯網&#xff0c;辦公區和游客區允許訪問互聯網 3、辦公區設備10.0.2.10不允許訪問DMZ區的FTP服務器和HTTP服務器&#xff0c;僅能ping通…

vue 環境變量那些事

常見的項目環境變量的使用 總則&#xff1a;使用 .env.環境名字文件去定義&#xff0c;運行命令的時候指定環境 比如&#xff1a;.env 代表所有環境變量使用的一些變量 .env.development 代表的開發環境變量 .env.production 代表的生產環境變量也就是上線以后使用的 vitevu…

自主研發接口測試框架

測試任務&#xff1a;將以前完成的所有的腳本統一改寫為unitest框架方式 1、需求原型 1.1 框架目錄結構 V1.0&#xff1a;一般的設計思路分為配置層、腳本層、數據層、結果層&#xff0c;如下圖所示 V 2.0&#xff1a;加入驅動層testdriver 1.2 框架各層需要完成的工作 1、配…

Fast DDS library windows 下源碼編譯(cmake)

目錄 編譯環境&#xff1a; 編譯需要的源碼文件&#xff1a; Fast DDS編譯&#xff1a; 注意事項&#xff1a; 參考文檔&#xff1a; 基于Fast DDS 的源碼來編譯相關的庫&#xff0c;然后可以通過python 來調用庫文件實現dds 數據通信&#xff0c;本文就詳細的介紹編譯過程…

機器學習筑基篇,容器調用顯卡計算資源,Ubuntu 24.04 快速安裝 NVIDIA Container Toolkit!...

[ 知識是人生的燈塔,只有不斷學習,才能照亮前行的道路 ] Ubuntu 24.04 安裝 NVIDIA Container Toolkit 什么是 NVIDIA Container Toolkit? 描述:NVIDIA Container Toolkit(容器工具包)使用戶能夠構建和運行 GPU 加速的容器,該工具包括一個容器運行時庫和實用程序,用于自動…

石油巨頭受沖擊!埃克森美孚、BP接連發出盈利預警

KlipC報道&#xff1a;近日&#xff0c;BP&#xff08;英國石油&#xff09;預計其第二季度將面臨10億至20億美元的減值費用&#xff0c;并發出警告稱其煉油利潤率“大幅下降”&#xff0c;石油交易收益預計出現疲軟。消息公布后&#xff0c;其股價下跌超4%。 由于中間餾分油利…

JavaScript(8)——函數

函數 function,是被設計執行特定任務的代碼塊。 函數可以把具有相同或相似邏輯的代碼包裹起來&#xff0c;通過函數調用執行這些代碼&#xff0c;這么做的優勢有利于精簡代碼方便復用。類似于alert(),prompt()和console.log()&#xff0c;這些都是js函數&#xff0c;不過已經…

STL(一)

書寫形式&#xff1a;string (const string& str, size_t pos, size_t len npos); 舉例&#xff1a; int main(){ string url("https://mp.csdn.net/mp_blog/creation/editor?spm1000.2115.3001.4503") string sub1(url,0,5);//從下標為0開始向后5個字符&…

如何在 Python 中創建一個類似于 MS 計算器的 GUI 計算器

問題背景 假設我們需要創建一個類似于微軟計算器的 GUI 計算器。這個計算器應該具有以下功能&#xff1a; 能夠顯示第一個輸入的數字。當按下運算符時&#xff0c;輸入框仍顯示第一個數字。當按下第二個數字時&#xff0c;第一個數字被替換。 解決方案 為了解決這個問題&am…

華為OD機考題(HJ108 求最小公倍數)

前言 經過前期的數據結構和算法學習&#xff0c;開始以OD機考題作為練習題&#xff0c;繼續加強下熟練程度。 描述 正整數A和正整數B 的最小公倍數是指 能被A和B整除的最小的正整數值&#xff0c;設計一個算法&#xff0c;求輸入A和B的最小公倍數。 數據范圍&#xff1a;1≤…

Spring中的適配器模式和策略模式

1. 適配器模式的應用 1.1適配器模式&#xff08;Adapter Pattern&#xff09;的原始定義是&#xff1a;將一個類的接口轉換為客戶期望的另一個接口&#xff0c;適配器可以讓不兼容的兩個類一起協同工作。 1.2 AOP中的適配器模式 在Spring的AOP中&#xff0c;使用Advice&#…