你懂精通ARM的含金量嗎?你懂精通STM32的含金量嗎?不管懂不懂都要懂,趕緊學。
這是它的電源系統,下面會說這些引腳的作用
在STM32單片機中,每個寄存器都有一個獨特的地址,這些地址是在芯片的數據手冊中定義的。地址偏移是指每個寄存器的地址相對于其所在寄存器組的基地址的偏移量。
在這里,每一個寄存器都有便宜的地址
例如,在STM32F407VG芯片中,GPIOB寄存器組的基地址為0x40020400。在這個寄存器組中,每個GPIOB端口的控制寄存器的地址偏移量是0x00、0x04、0x08、0x0C等。這意味著,如果您想訪問GPIOB的第一個端口(PB0),則可以通過將地址偏移量0x00添加到GPIOB基地址(0x40020400)來訪問它,即0x40020400 + 0x00 = 0x40020400。
在STM32中,使用寄存器地址偏移來訪問和控制特定寄存器,這可以通過指針操作和位域操作等方式來實現。需要注意的是,對于不同的芯片型號和不同的寄存器組,其基地址和偏移量可能會有所不同。
在STM32單片機中,每個寄存器都有一個復位值(也稱為默認值或初始值),這是當單片機復位時寄存器將被初始化為的值。復位值是在芯片的數據手冊中定義的。
大多數寄存器的復位值都是0或某些特定的值,例如控制寄存器的復位值通常是0x0000或0x0001。
在單片機初始化過程中,為了確保寄存器處于正確的狀態,需要將所有寄存器設置為其復位值。這可以通過在啟動代碼中執行清零操作或者使用STM32提供的庫函數來實現。
一字節是計算機存儲中的基本單位之一,通常包含8個比特(bit),每個比特只能表示0或1兩種狀態。在計算機中,一字節通常用于存儲一個字符或者一個整數等數據。
在二進制表示中,一字節的取值范圍是0~255(即00000000~11111111),因為它可以用8個比特組合出256種不同的狀態,其中一個狀態用于表示0。
一字節的大小在不同的計算機架構中可能會有所不同,但是在大多數計算機中,一字節都被定義為8個比特。此外,一些特殊的系統中,字節大小可能是其他值,如10比特或12比特。
一比特(bit)是計算機存儲和通信中最小的數據單位,它只能表示0或1兩種狀態。比特通常用于表示二進制數據,在計算機中被廣泛應用于數字電路和通信領域。
在二進制表示中,一個比特的取值范圍是0或1,其中0表示低電平(或者“假”),1表示高電平(或者“真”)。比特的狀態可以表示一位二進制數中的一位,因此8個比特組合起來可以表示一個字節,即一個8位的二進制數。
比特在計算機中有著廣泛的應用,例如存儲器單元中的存儲單元就是由比特組成的,CPU中的寄存器也是由多個比特組合而成的。在通信領域,比特是衡量數據傳輸速率的單位,例如“1Mbps”表示每秒傳輸100萬個比特。
這里寫的就是上面的電源引腳,為什么在認知中簡單的+,-兩個而已,現在出來這么多腳?
Vdd和Vss是電子元器件中常用的術語,它們分別代表電路的正電源和負電源。
Vdd是指電路中的正電源,通常表示為Vcc,它為電路提供正電壓,使電路中的器件工作。在數字電路中,Vdd通常為邏輯1的電壓值,而在模擬電路中,Vdd通常為固定的直流電壓源。
Vss是指電路中的負電源,也稱為地線或接地線,通常表示為GND。Vss提供電路中的器件所需的負電壓,以確保電路正常工作。在數字電路中,Vss通常為邏輯0的電壓值,而在模擬電路中,Vss通常為固定的零電位或接地。
Vdd和Vss是電子電路中最基本的兩個電源,電路中的其他信號、電壓和電流都是基于這兩個電源的。
Vdda是指模擬電路中的電源,通常用于提供模擬信號的參考電壓。Vdda通常表示為VddA,與數字電路中的Vdd不同,Vdda通常為模擬電路所需的電壓值,通常比數字電路中的Vdd更為精確和穩定。
Vdda通常用于ADC(模數轉換器)和DAC(數模轉換器)等模擬電路中。在ADC中,Vdda是參考電壓,用于將模擬信號轉換為數字信號。在DAC中,Vdda是數字信號轉換為模擬信號時使用的參考電壓。
與數字電路中的Vdd相比,Vdda的電壓值通常要求更為精確和穩定,以確保模擬電路中的信號質量。
Vdd是指數字電路中的正電源,通常表示為Vcc,它為電路提供正電壓,使電路中的器件工作。在數字電路中,Vdd通常為邏輯1的電壓值。
Vdd電源通常用于數字邏輯電路中,例如微處理器、存儲器、計數器等。Vdd的電壓值取決于具體的器件要求和應用場景,通常在2V到5V之間,也有些器件需要更高的電壓值。
在數字電路中,Vdd電源的穩定性和可靠性非常重要,如果Vdd電壓不穩定或存在波動,可能會導致電路運行不穩定或出現錯誤。因此,在數字電路設計中,通常需要使用穩壓電路或者其他電源管理技術來確保Vdd電壓的穩定性和可靠性,以保證電路的正常工作。
Vssa是指模擬電路中的負電源,通常表示為VssA,它為模擬電路中的器件提供負電壓,以確保模擬電路的正常工作。Vssa通常用于模擬信號的處理和放大等模擬電路中。
與數字電路中的Vss不同,Vssa通常需要比Vss更為精確和穩定,以確保模擬電路中的信號質量。在實際應用中,通常需要使用高精度的電源管理電路或其他電源穩定技術來確保Vssa的穩定性和可靠性,以確保模擬電路的正常工作。
需要注意的是,Vssa和VddA通常是相對于某個參考電位(通常是地線)而言的,它們之間的電壓差通常稱為模擬電源電壓。
這個簡單,就是CubuMX的
在 STM32 數據手冊中,寄存器的訪問選項通常包括以下內容:
讀/寫權限:指示寄存器是否可讀、可寫或既可讀又可寫。
寄存器地址:指示寄存器在芯片內存映射中的地址。
寄存器位域:對于一些特殊的寄存器,可能會將其分為幾個位域來表示不同的控制或狀態信息。
復位值:指示寄存器在復位時的初始值。
等待周期:指示在對該寄存器進行讀/寫操作時需要等待多長時間才能獲得結果。在一些情況下,需要等待芯片內部的一些操作完成后才能獲得正確的結果,因此需要等待周期。
等待周期是指訪問某些寄存器需要等待芯片內部操作完成的時間,通常稱為訪問延遲。在進行某些特殊操作時,需要等待周期才能確保數據的正確性。在進行讀取操作時,等待周期可能包括寄存器響應時間、總線傳輸時間等等,具體時間可能會因為系統的配置和芯片的類型而有所不同。
在微控制器中,有時需要對存儲器進行不同粒度的讀寫操作,字節(Byte)、半字(Half Word)和字(Word)是三種常見的數據粒度,它們分別表示存儲器中的不同位數。具體含義如下:
字節(Byte):是存儲器中的最小單元,通常表示為8位二進制數。字節可存儲0-255的無符號整數,或者-128到127的有符號整數。字節訪問意味著每次訪問一個字節。
半字(Half Word):是由兩個連續的字節組成,通常表示為16位二進制數。半字可存儲0-65535的無符號整數,或者-32768到32767的有符號整數。半字訪問意味著每次訪問兩個字節。
字(Word):是由四個連續的字節組成,通常表示為32位二進制數。字可存儲0-4294967295的無符號整數,或者-2147483648到2147483647的有符號整數。字訪問意味著每次訪問四個字節。
在STM32微控制器中,為了支持不同粒度的讀寫操作,一些寄存器和存儲器區域提供了不同的訪問選項,例如:
8位字節訪問(BYTE):每次訪問8位(1個字節)的數據。
16位半字訪問(HALFWORD):每次訪問16位(2個字節)的數據。
32位字訪問(WORD):每次訪問32位(4個字節)的數據。
在 STM32 微控制器中,系統時鐘和外設時鐘都是由一個基礎時鐘源衍生出來的,對于 STM32 系列微控制器而言,通常都是使用內部的 RC 振蕩器或者外部的晶體振蕩器作為基礎時鐘源。
時鐘中斷寄存器是一類特殊的寄存器,用于配置 STM32 微控制器中的時鐘中斷。時鐘中斷是指在系統時鐘或者外設時鐘到達某個特定時間或者計數值時產生的一種中斷信號,用于觸發某些特定的操作或者執行周期性的任務。
STM32 微控制器中的時鐘中斷寄存器通常包括以下內容:
時鐘控制寄存器:用于配置時鐘的各種參數,例如時鐘源選擇、時鐘分頻系數、時鐘計數器等等。
中斷控制寄存器:用于配置時鐘中斷的觸發條件和中斷優先級等參數。
中斷狀態寄存器:用于記錄當前是否有時鐘中斷發生,并且可以清除中斷標志位。
在 STM32 微控制器中,不同的系列和型號會有不同的時鐘中斷寄存器,具體的使用方法和配置參數需要根據具體的型號和應用場景進行選擇和調整。
復位電路
時鐘樹在面試的時候也會問,這個其實就是多看看就好了
在HSE時鐘上面的晶振如何接
在MX上面生成調試的時候,需要選擇這個
會有默認的引腳來啟用
可以選擇一個IIC的
下面是具體的一些功能,可以去設置,在代碼中有體現
IIC默認開啟的是這兩個引腳
有時候引腳之間是互相沖突的
可以試試UART
硬件外設就直接打開
這些是串口的常見設置
你可以點右邊來設置精確的功能
在這里被設置
當然DMA如果要開啟的時候也是可以的
時鐘
這是一些設置
為每個外設生成H,C
也可以選取LL低級性能庫
第一次找到這個功能,好像是打開回調
代碼在之間
這個就是生成的函數
里面的中斷函數
IO腳的設置自己看嘛
4部分
01控制
速度控制,說了100遍
也可以選擇JTAG
默認復位的功能
一次用4個線,不配了
引腳的配置
自己看
輸入模式
在 STM32 微控制器中,APB2(Advanced Peripheral Bus 2)是一個高速外設總線,它連接了一些重要的外設模塊,例如定時器、串行通信接口、通用串行總線控制器等等。APB2 的時鐘頻率可以通過時鐘樹的分頻器進行配置,因此可以實現不同外設模塊之間的時序控制和數據交換。
STM32 APB2 外設包括但不限于以下幾個:
定時器:STM32 微控制器中有多種不同類型的定時器,包括基本定時器、通用定時器、高級定時器等等,這些定時器可以用于產生各種精度和周期的定時器中斷,同時還支持 PWM 信號輸出、脈沖計數等功能。
串行通信接口:STM32微控制器中支持多種不同的串行通信協議,包括 UART、SPI、I2C等等,這些外設模塊可以實現與其他設備的數據通信和控制。
通用串行總線控制器:STM32 微控制器中的通用串行總線控制器(USB OTG FS)是一種高速的通用串行總線接口,可以實現與 USB 設備的通信和數據傳輸。
ADC:STM32 微控制器中的 ADC(模數轉換器)可以用于采集模擬信號并將其轉換為數字信號,提供多種不同的采樣率和分辨率選擇。
DMA:STM32 微控制器中的 DMA(直接存儲器訪問)模塊可以實現高效的數據傳輸和數據存儲,同時也可以降低 CPU 的負載,提高系統性能。
在STM32中,APB2是高速外設總線,例如SPI、I2S、USART、ADC等,其時鐘頻率通常比APB1和AHB總線更高。在每個APB2時鐘上采樣指的是在APB2時鐘周期內對某個外設進行多次采樣以提高采樣精度和減小采樣誤差的技術。
例如,在使用STM32的ADC(模數轉換器)時,可以選擇在每個APB2時鐘上采樣來提高轉換精度。這樣做的好處是可以將ADC的采樣周期與APB2總線的時鐘同步,提高ADC采樣率,減小噪聲和抖動對采樣的影響,從而提高系統的性能和穩定性。
在STM32中,IRQ是指中斷請求(Interrupt Request)。它是一種特殊的處理器信號,用于通知CPU有重要的事件需要立即處理。當一個中斷事件被觸發時,它會向處理器發出IRQ信號,將處理器從正常的程序執行中打斷,轉而執行預定義的中斷服務程序(ISR)來處理中斷事件。
STM32芯片具有許多外設(例如定時器、串口、ADC等),這些外設可以通過配置相應的中斷請求(IRQ)來實現異步事件的處理。當外設產生了預定義的事件(例如定時器計數器溢出、串口接收數據等)時,它會自動向中斷控制器發出IRQ信號,觸發中斷請求,并使得CPU暫時停止執行正在運行的程序,轉而執行相應的中斷服務程序來處理該事件。
在STM32中,IRQ信號由中斷控制器(NVIC,Nested Vector Interrupt Controller)進行管理和分配,它可以對外設產生的不同類型的中斷請求進行優先級排序和處理。
異步編程是一種編程模型,它不依賴于線程的同步和阻塞等機制,而是通過回調函數、事件驅動等方式來實現代碼的非阻塞執行,從而提高系統的并發性能和響應速度。
異步編程通常涉及到異步操作和異步實踐兩個概念。
異步操作指的是一種不會阻塞當前線程的操作,例如IO操作、網絡請求等。異步操作一般是通過異步函數或異步API來實現的,它們通常會在后臺啟動一個或多個線程或進程來處理請求,從而避免當前線程被阻塞。異步操作通常會在完成后觸發一個事件或回調函數,通知應用程序異步操作已經完成,并將操作結果傳遞給應用程序。
異步實踐指的是使用異步編程模型來優化系統性能和響應速度的一系列技術和方法。異步實踐的核心思想是將那些可能導致阻塞的操作(例如IO操作、數據庫訪問等)轉換為異步操作,以保證系統的高并發性能和響應速度。異步實踐還包括一些常見的技術和方法,例如使用事件驅動、異步回調、異步消息隊列等,來實現代碼的異步執行和解耦合。
在嵌入式開發中,異步實踐也非常重要。例如,使用STM32等微控制器進行嵌入式開發時,可以使用異步編程模型和異步實踐技術來實現對外設的異步控制和數據采集等功能,從而提高系統的性能和可靠性。
1.使用異步函數或異步API:嵌入式系統中的許多操作都是耗時的,例如IO操作、網絡通信等,如果使用同步方式進行處理,會導致當前線程被阻塞,影響系統的響應速度。因此,在嵌入式系統中,通常使用異步函數或異步API來實現這些操作。異步函數或API會在后臺啟動一個或多個線程或任務來處理請求,從而避免當前線程被阻塞,同時也可以提高系統的并發性能和響應速度。
2.使用中斷機制:嵌入式系統中,許多操作都是通過中斷機制來實現的,例如定時器中斷、外部中斷等。使用中斷機制可以使得系統不必等待某些操作的完成,而是在該操作完成時自動觸發中斷處理程序,從而實現異步處理。
3.使用事件驅動模型:事件驅動模型是一種基于事件和回調函數的編程模型,它通過監聽特定的事件來觸發對應的回調函數。在嵌入式系統中,事件驅動模型可以用來實現異步操作的回調函數。例如,在處理串口通信時,可以使用事件驅動模型監聽串口接收數據的事件,并在數據到達時觸發對應的回調函數進行數據處理。
4.使用消息隊列:消息隊列是一種將消息異步傳遞給消費者的機制。在嵌入式系統中,可以使用消息隊列來實現異步任務的處理。例如,在處理圖像識別時,可以使用消息隊列來異步處理圖像數據,從而避免阻塞當前任務的執行。
引腳的開漏模式是指在輸出電平時,將該引腳連接的晶體管的源極或發射極與地相連,使得該引腳的輸出電平只能為低電平(0V)或高阻態(電阻很大,相當于沒有連接)。開漏模式的引腳通常被稱為開漏輸出引腳。
在開漏模式下,輸出引腳不會直接提供高電平的輸出,而是通過連接一個上拉電阻或使用內部上拉電阻來實現。上拉電阻的值通常很大,因此在輸出高電平時,輸出電平可能不穩定,容易受到外部干擾的影響。
開漏模式的引腳通常用于控制外部電路中的開關元件(例如晶體管、繼電器等),以及驅動I2C總線等外部設備。在這些場景中,開漏模式的引腳可以通過控制開關元件的導通和斷開來實現對外部設備的控制,同時也可以避免由于外部設備的反向電流等問題對系統的損害。
需要注意的是,開漏模式的引腳在輸出高電平時不能直接驅動負載,需要通過使用外部上拉電阻或使用內部上拉電阻來實現,同時在設計電路時需要考慮到該引腳的輸出電流和負載電流的匹配,以避免對系統的損害。
引腳的推挽模式是指在輸出電平時,將該引腳連接的晶體管的源極或發射極與電源相連,使得該引腳的輸出電平可以為高電平(電源電壓)或低電平(0V)。推挽模式的引腳通常被稱為推挽輸出引腳。
在推挽模式下,輸出引腳可以直接提供高電平和低電平的輸出,并且輸出電流通常比較大,可以直接驅動一定的負載電流。
推挽模式的引腳通常用于控制外部電路中的驅動元件(例如LED、直流電機等),以及驅動SPI總線等外部設備。在這些場景中,推挽模式的引腳可以通過控制驅動元件的導通和斷開來實現對外部設備的控制,同時也可以提供較大的輸出電流以驅動負載電流。
需要注意的是,在推挽模式下,引腳的輸出電平不能為高阻態,需要確保連接的晶體管在輸出低電平時處于關閉狀態,否則可能導致電路不穩定或電路損壞。
相同點:
都可以作為引腳的輸出模式,輸出高電平和低電平的電壓信號;
都可以用來控制外部電路中的驅動元件,例如LED、直流電機等。
不同點:
開漏模式的引腳輸出電平只能為低電平或高阻態,需要通過上拉電阻來實現高電平的輸出;推挽模式的引腳輸出電平可以為低電平或高電平;
推挽模式的引腳具有較大的輸出電流能力,可以直接驅動負載電流,而開漏模式的引腳需要通過上拉電阻來驅動負載電流;
開漏模式的引腳通常用于控制外部電路中的開關元件(例如晶體管、繼電器等),以及驅動I2C總線等外部設備;而推挽模式的引腳通常用于控制外部電路中的驅動元件(例如LED、直流電機等),以及驅動SPI總線等外部設備。
推挽模式的引腳適合需要較大輸出電流的場景,例如驅動LED、直流電機等負載,同時也適合驅動SPI總線等外部設備;
開漏模式的引腳適合需要通過控制開關元件的導通和斷開來實現控制的場景,例如驅動I2C總線等外部設備。
當外設模塊需要從CPU讀取數據時,它需要按照APB2總線時鐘的節奏來發送讀取請求,并在每個APB2時鐘周期中傳輸一個數據位,直到所有數據都被讀取完畢為止。
施密特觸發輸入是一種常見的數字電路輸入技術,也被稱為施密特觸發器輸入或雙穩態輸入。施密特觸發輸入通過特殊的電路設計,能夠使輸入信號的干擾和抖動不會輕易導致輸出信號的誤判或不穩定。
施密特觸發輸入的基本原理是在輸入信號的電壓上下閾值范圍內,輸出信號維持穩定的高或低電平;而當輸入信號超過一定的閾值范圍時,輸出信號則發生明顯的翻轉,并維持到輸入信號回到另一個閾值范圍時才再次翻轉。這種特性可以有效地防止輸入信號的干擾和抖動導致輸出信號的誤判或不穩定。
施密特觸發輸入常見的應用場景包括數字信號的輸入、信號的去抖動處理、信號的濾波處理等。在數字電路的設計和實現中,施密特觸發輸入可以提高電路的抗干擾能力和穩定性,從而提高數字系統的性能和可靠性。
P-MOS
P-MOS是一種由p型半導體材料制成的MOSFET晶體管,其控制方式是通過在柵極和源極之間施加負電壓來控制晶體管的導通狀態。當柵極電壓低于源極電壓時,P-MOS導通;當柵極電壓高于源極電壓時,P-MOS截止。P-MOS的導通電阻相對較大,通常用于高電平驅動電路中。
N-MOS
N-MOS是一種由n型半導體材料制成的MOSFET晶體管,其控制方式是通過在柵極和源極之間施加正電壓來控制晶體管的導通狀態。當柵極電壓高于源極電壓時,N-MOS導通;當柵極電壓低于源極電壓時,N-MOS截止。N-MOS的導通電阻相對較小,通常用于低電平驅動電路中。
弱上拉是指在輸入端口(比如微控制器的GPIO口)上通過加入一個大約為10kΩ的電阻,從而使該輸入端口與VCC(正電源)之間形成一個電阻分壓網絡,從而使輸入端口的電壓在沒有外部信號的情況下趨向于高電平,即被上拉到VCC電平。
弱上拉的作用在于,當沒有外部信號輸入時,輸入端口會被保持在一個已知的狀態,從而有效地避免了輸入端口因為外部信號干擾而導致的錯誤輸入。同時,在需要對輸入端口進行讀取的時候,由于弱上拉電阻的存在,輸入端口的狀態可以更容易地被檢測到。
我們其實就是操作IO的輸出和輸入,各種功能到底怎么樣的配置?
這么多的定時器,讓我來給大家寫一寫
STM32定時器的輸入捕獲功能可以用來測量外部信號的時間間隔、頻率和脈寬等信息,常用于測量脈沖信號、編碼器信號、PWM信號等。
具體實現步驟如下:
配置定時器為輸入捕獲模式。
配置定時器的輸入捕獲通道,選擇輸入捕獲邊沿(上升沿或下降沿)觸發測量。
在輸入捕獲中斷服務函數中讀取捕獲寄存器的值,計算出測量值。
根據需要,可以通過中斷或DMA方式進行多次測量,并對測量結果進行平均值計算等處理。
下面是一個基于STM32 HAL庫的輸入捕獲示例代碼,以測量外部脈沖信號的周期和脈寬為例:
#include "stm32f4xx_hal.h" TIM_HandleTypeDef htim2; uint32_t pulse_width = 0; uint32_t period = 0; void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) { if (htim->Instance == TIM2) { static uint32_t last_capture = 0; uint32_t capture = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1); uint32_t diff = capture - last_capture; last_capture = capture; if (diff > 0) { period = diff; } else { pulse_width = -diff; } } } int main(void) { HAL_Init(); __HAL_RCC_TIM2_CLK_ENABLE(); htim2.Instance = TIM2; htim2.Init.Prescaler = 83; // 84MHz / 84 = 1MHz htim2.Init.CounterMode = TIM_COUNTERMODE_UP; htim2.Init.Period = 0xFFFF; htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; HAL_TIM_IC_Init(&htim2); TIM_IC_InitTypeDef sConfigIC; sConfigIC.ICPolarity = TIM_ICPOLARITY_BOTHEDGE; sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI; sConfigIC.ICPrescaler = TIM_ICPSC_DIV1; sConfigIC.ICFilter = 0; HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_1); HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1); while (1) { // do something } }
在上述代碼中,使用了TIM2定時器的通道1進行輸入捕獲,并開啟了中斷模式(HAL_TIM_IC_Start_IT函數)。在輸入捕獲中斷服務函數中,計算出上一次和本次捕獲的時間差,根據時間差的正負值來區分計算周期還是脈寬,最終得到測量結果。
STM32定時器的輸出比較功能可以用來生成PWM波形、產生觸發信號、實現周期性的定時器中斷等。其實現步驟如下:
配置定時器為輸出比較模式,并選擇輸出比較通道。
配置定時器的時基參數,包括計數器的時鐘頻率、計數器的計數范圍等。
配置輸出比較模式下的通道參數,包括輸出模式(比較輸出或PWM輸出)、比較值等。
啟動定時器,使其開始計數并產生輸出信號。
下面是一個基于STM32 HAL庫的輸出比較示例代碼,以生成50%占空比、1kHz的PWM信號為例:
#include "stm32f4xx_hal.h" TIM_HandleTypeDef htim2; void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if (htim->Instance == TIM2) { __HAL_RCC_TIM2_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_5; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.Alternate = GPIO_AF1_TIM2; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); } } void MX_TIM2_Init(void) { TIM_ClockConfigTypeDef sClockSourceConfig = {0}; TIM_MasterConfigTypeDef sMasterConfig = {0}; TIM_OC_InitTypeDef sConfigOC = {0}; htim2.Instance = TIM2; htim2.Init.Prescaler = 83; // 84MHz / 84 = 1MHz htim2.Init.CounterMode = TIM_COUNTERMODE_UP; htim2.Init.Period = 999; // 1kHz PWM htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; HAL_TIM_PWM_Init(&htim2); sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig); sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig); sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.Pulse = 499; // 50% duty cycle sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1); } int main(void) { HAL_Init(); MX_TIM2_Init(); HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1); while (1) { // do something } }
STM32定時器的互補輸出功能可以用來實現半橋或全橋逆變器、電機驅動器等應用。它通過在同一個定時器中同時配置兩個輸出比較通道,一個通道輸出高電平,另一個通道輸出低電平,以實現互補輸出的功能。
下面是一個基于STM32HAL庫的互補輸出示例代碼,以實現半橋逆變器為例:
#include "stm32f4xx_hal.h" TIM_HandleTypeDef htim1; void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if (htim->Instance == TIM1) { __HAL_RCC_TIM1_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOE_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_8; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.Alternate = GPIO_AF1_TIM1; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_13; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.Alternate = GPIO_AF1_TIM1; HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); } } void MX_TIM1_Init(void) { TIM_ClockConfigTypeDef sClockSourceConfig = {0}; TIM_MasterConfigTypeDef sMasterConfig = {0}; TIM_OC_InitTypeDef sConfigOC = {0}; htim1.Instance = TIM1; htim1.Init.Prescaler = 839; // 84MHz / 840 = 100kHz htim1.Init.CounterMode = TIM_COUNTERMODE_UP; htim1.Init.Period = 9999; // 10Hz PWM htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim1.Init.RepetitionCounter = 1; // 2 channels, repetition count = 1 HAL_TIM_PWM_Init(&htim1); sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig); sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE; HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig); sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.Pulse = 4999; // 50% duty cycle sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1); HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_2); HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2); HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_1); HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_2); } int main(void) { HAL_Init(); MX_TIM1_Init(); while (1) { } }
STM32定時器的剎車輸入是用于實現電機或馬達控制器的緊急停止或剎車功能。當剎車輸入信號被觸發時,定時器立即停止計數,并且輸出保持在一個預定義的狀態(例如輸出低電平或高電平)。在應用中,剎車輸入通常是由硬件電路(如電機控制器)提供的。
STM32定時器的剎車輸入通常與定時器的輸入捕獲或輸出比較功能結合使用。例如,在一個三相電機驅動器中,定時器的輸入捕獲功能用于捕獲電機轉速,輸出比較功能用于產生PWM波形驅動電機,而剎車輸入則用于實現急停功能。
下面是一個基于STM32 HAL庫的剎車輸入示例代碼:
#include "stm32f4xx_hal.h" TIM_HandleTypeDef htim1; void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if (htim->Instance == TIM1) { __HAL_RCC_TIM1_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_8; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.Alternate = GPIO_AF1_TIM1; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); } } void MX_TIM1_Init(void) { TIM_ClockConfigTypeDef sClockSourceConfig = {0}; TIM_MasterConfigTypeDef sMasterConfig = {0}; TIM_OC_InitTypeDef sConfigOC = {0}; htim1.Instance = TIM1; htim1.Init.Prescaler = 839; // 84MHz / 840 = 100kHz htim1.Init.CounterMode = TIM_COUNTERMODE_UP; htim1.Init.Period = 999; // 1kHz PWM htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; HAL_TIM_PWM_Init(&htim1); sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig); sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE; HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig); sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.Pulse = 499; // 50% duty cycle sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1); HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); } int main(void) { HAL_Init(); MX_TIM1_Init(); while (1) { // Main loop } } void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim) { if (htim->Instance == TIM1 && htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1) { // Handle PWM pulse finished event } }
STM32定時器的外部觸發時鐘輸入是一種使定時器以外部信號作為計數時鐘的功能。它允許定時器在外部觸發信號到來時開始計數,并且不依賴于內部時鐘。這種功能常用于需要精確時間測量或同步的應用,如數據采集、PWM控制和通信接口等。
STM32定時器的外部觸發時鐘輸入可通過使用TIMx_ETR (外部觸發器)引腳來實現。在應用中,可以選擇使用外部觸發器引腳(例如TIM1_ETR),然后使用寄存器配置定時器的觸發模式和觸發源。
下面是一個基于STM32 HAL庫的外部觸發時鐘輸入示例代碼:
#include "stm32f4xx_hal.h" TIM_HandleTypeDef htim1; void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim) { if (htim->Instance == TIM1) { __HAL_RCC_TIM1_CLK_ENABLE(); } } void MX_TIM1_Init(void) { TIM_ClockConfigTypeDef sClockSourceConfig = {0}; TIM_MasterConfigTypeDef sMasterConfig = {0}; htim1.Instance = TIM1; htim1.Init.Prescaler = 8399; // 84MHz / 8400 = 10kHz htim1.Init.CounterMode = TIM_COUNTERMODE_UP; htim1.Init.Period = 999; // 10Hz timer htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; HAL_TIM_Base_Init(&htim1); sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_ETRMODE2; sClockSourceConfig.ClockPolarity = TIM_CLOCKPOLARITY_NONINVERTED; sClockSourceConfig.ClockPrescaler = TIM_CLOCKPRESCALER_DIV1; sClockSourceConfig.ClockFilter = 0; HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig); sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE; HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig); HAL_TIM_Base_Start(&htim1); } int main(void) { HAL_Init(); MX_TIM1_Init(); while (1) { // Main loop } }
TM32定時器是一種用于計時和控制輸出信號的硬件模塊,它具有多種功能和操作模式。STM32定時器的原理是利用一個計數器(Counter)來計數,當計數器的值達到某個閾值時,就會產生一個中斷或觸發一個事件。其中,計數器的計數基準由定時器時鐘源(Timer Clock Source)提供,可以是內部時鐘(例如APB1時鐘)或外部時鐘(例如外部晶振)。
STM32定時器的計數器可以通過多種方式進行控制和配置,其中包括:
接著看看串口的功能
分頻器(Prescaler):通過分頻器可以將定時器時鐘源的頻率降低,從而改變計數器的計數速度。分頻器的分頻值由預分頻器寄存器(PSC)設置,它是一個16位寄存器。
自動重載寄存器(Auto-reload Register):自動重載寄存器(ARR)存儲定時器計數器的最大值。當計數器的計數值達到自動重載寄存器的值時,計數器會重新從零開始計數。這種方式通常用于周期性產生中斷或控制PWM波形的占空比。
捕獲寄存器(Capture Register):捕獲寄存器(CCR)用于存儲定時器計數器的當前值。當捕獲到一個特定事件時,捕獲寄存器會自動被更新。這種方式通常用于測量外部事件的持續時間或頻率,例如測量脈沖寬度或計算輸入信號的頻率。
比較寄存器(Compare Register):比較寄存器(CCR)用于存儲與計數器進行比較的值。當計數器的值達到比較寄存器的值時,會觸發中斷或控制輸出信號的狀態。這種方式通常用于產生精確的定時事件或控制PWM波形的頻率和占空比。
TM32的UART模塊支持全雙工模式,其中數據可以在同一個UART通道上同時發送和接收。
要使用STM32的UART模塊進行全雙工通信,您需要進行以下設置:
配置UART模塊的時鐘和波特率,使其能夠與外部設備通信。
配置UART模塊的發送和接收引腳,以便將數據發送到外部設備并從外部設備接收數據。
配置UART模塊的工作模式為全雙工模式,這可以通過將UART模塊的USART_InitTypeDef結構體中的Mode字段設置為USART_MODE_TX_RX來實現。
在程序中編寫發送和接收函數,以便發送和接收數據。
以下是一個使用STM32的UART模塊進行全雙工通信的示例代碼:
#include "stm32f10x.h" #includeUSART_InitTypeDef USART_InitStructure; void USART1_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); USART_InitStructure.USART_BaudRate = 115200; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART1, &USART_InitStructure); USART_Cmd(USART1, ENABLE); } void USART1_SendChar(char ch) { while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); USART_SendData(USART1, ch); } char USART1_ReceiveChar(void) { while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET); return USART_ReceiveData(USART1); } int main(void) { char received_char; USART1_Init(); while(1) { //發送數據 USART1_SendChar('H'); USART1_SendChar('e'); USART1_SendChar('l'); USART1_SendChar('l'); USART1_SendChar('o'); USART1_SendChar(' '); //接收數據 received_char = USART1_ReceiveChar(); printf("Received: %c ", received_char); }
單工模式(Simplex Mode):在單工模式下,串口只能在一個方向上傳輸數據,即數據只能單向發送或接收。在單工模式下,無法同時發送和接收數據。這種模式的應用場景較為有限,通常只用于簡單的數據采集或監測任務。
半雙工模式(Half Duplex Mode):在半雙工模式下,串口可以在兩個方向上傳輸數據,但不能同時進行。也就是說,數據可以在發送和接收之間切換,但不能同時進行。這種模式廣泛應用于需要雙向通信的應用場景,例如工業自動化和機器人控制。
全雙工模式(Full Duplex Mode):在全雙工模式下,串口可以在兩個方向同時傳輸數據,也就是說,可以同時發送和接收數據。這種模式的應用場景最為廣泛,通常用于數據通信、網絡通信等領域。
不同串口模式的異同在于其能否同時進行數據的發送和接收。單工模式只能單向傳輸數據,半雙工模式可以雙向傳輸數據但不能同時進行,全雙工模式可以同時進行數據的雙向傳輸。因此,在實際應用中,需要根據具體的場景和需求選擇適合的串口模式。
SPI全雙工模式:在SPI全雙工模式下,數據可以同時在主機和從機之間傳輸。主機通過發送時鐘信號來控制數據傳輸,每次傳輸一個字節或者一個字(16位)。SPI全雙工模式是最常用的SPI模式,應用于數據傳輸速度要求較高、需要雙向數據傳輸的場景。
SPI半雙工模式:在SPI半雙工模式下,數據只能在主機和從機之間單向傳輸。主機先發送數據,然后從機接收數據,或者從機先發送數據,然后主機接收數據。SPI半雙工模式應用于一些只需要單向數據傳輸的場景,例如LED顯示、IO擴展等。
SPI主機模式:在SPI主機模式下,主機控制SPI通信的時序和數據傳輸,從機被動接受并響應主機的控制。SPI主機模式常用于控制多個SPI從機的場景。
SPI從機模式:在SPI從機模式下,從機被動接受來自主機的控制和數據傳輸。SPI從機模式應用于一些只需要單個從機的場景。
不同SPI模式的異同在于其能否同時進行雙向數據傳輸,以及數據傳輸時的時序和控制方式。
SPI全雙工模式和半雙工模式的主要區別在于雙向傳輸的能力,而SPI主機模式和從機模式的主要區別在于SPI通信的控制者是主機還是從機。
SPI(Serial Peripheral Interface,串行外圍設備接口)是一種簡單的、高速的串行通信協議,用于在微控制器和外部設備之間傳輸數據。SPI協議是一種同步協議,數據在時鐘信號的控制下進行傳輸。
SPI協議的基本通信原理是:
在SPI通信中,需要至少兩個設備,一個作為主設備,另一個或多個作為從設備。主設備負責控制SPI通信的時序和數據傳輸,從設備被動接受并響應主設備的控制。
SPI通信中有四條信號線:SCK、MOSI、MISO和SS。SCK是時鐘信號線,由主設備產生;MOSI是主設備發送數據到從設備的信號線;MISO是從設備發送數據到主設備的信號線;SS是片選信號線,用于選擇從設備。在多個從設備的情況下,每個從設備都需要有一個獨立的片選信號線。
在SPI通信中,主設備產生時鐘信號,每個時鐘周期傳輸一個比特位,總線的數據傳輸是由主設備控制的。主設備先選擇一個從設備,即在對應的片選信號線拉低,然后向從設備發送數據。從設備在接收到數據后,根據協議進行響應,并將響應數據發送給主設備。主設備接收完從設備的響應數據后,選擇下一個從設備或結束通信。
SPI協議的優點是傳輸速度快、控制簡單、通信穩定可靠。SPI通信速度可以達到幾十MHz,具有很高的實時性和實時控制性能。
三瓜倆棗的價格還給個USB
USB OTG(On-The-Go)控制器:USB OTG控制器可以支持主機和設備兩種USB模式,因此可以在連接不同USB設備時自動識別主機和設備角色,并切換到相應的模式。USB OTG控制器支持USB 2.0標準,能夠實現高速(480 Mbps)、全速(12 Mbps)和低速(1.5 Mbps)的數據傳輸。此外,USB OTG控制器還支持Suspend和Resume模式,可以使設備在空閑狀態下降低功耗。
USB設備接口:STM32F103系列微控制器還內置了USB設備接口,可以直接連接到PC或其他USB主機設備。在這種模式下,微控制器可以作為USB設備與主機進行通信,如傳輸數據、控制外圍設備等。USB設備接口支持USB 2.0標準,能夠實現高速、全速和低速的數據傳輸。
USB引導加載器:STM32F103系列微控制器還支持通過USB引導加載器(USB bootloader)對程序進行燒錄,這種方式不需要額外的燒錄器件,只需通過USB接口即可進行程序下載。這種方式便于生產線上的批量燒錄和固件更新。
USB DMA(Direct Memory Access)控制器:STM32F103系列微控制器還支持USB DMA控制器,可以實現高效的USB數據傳輸。DMA控制器能夠直接將USB數據傳輸到內存中,從而減少CPU的負擔,提高數據傳輸效率。
完事了家人們
SDIO是一種標準的接口協議,它可以用于SD卡,MMC(MultiMediaCard)卡等存儲卡的數據交換。STM32F103的SDIO接口支持SD卡的SD1.0、SD1.1、SD2.0和SD3.0標準,最高傳輸速度可達到48Mbps。
SDIO接口的主要功能包括:
初始化:配置SDIO時鐘、總線寬度、傳輸模式、數據超時等參數。
SD卡識別:通過發送CMD0命令使SD卡進入Idle狀態,并發送CMD8命令獲取SD卡的電壓范圍和支持的接口版本。
卡信息讀取:通過發送CMD9命令讀取SD卡的CSD(Card Specific Data)寄存器和CID(Card Identification)寄存器,獲取SD卡的制造商信息、容量、傳輸速率等信息。
數據讀寫:通過發送CMD17和CMD18命令讀取SD卡的數據塊,通過發送CMD24和CMD25命令寫入數據塊。
卡狀態監測:通過發送CMD13命令查詢SD卡的狀態,包括卡是否準備好、當前傳輸狀態、錯誤狀態等。
DMA傳輸:STM32F103的SDIO接口支持DMA傳輸,可以減少CPU的負擔,提高數據傳輸效率。
最后兩個,打完收工:
誰懂啊,家人們
輸入和輸出
定時器這塊沒有完全吃透,準備先寫51或者是MSP430的時鐘系統。
這個就是定時器的數據手冊,不知道為什么倒著寫
①CK_PSC是定時器時鐘TIMxCLK,經APB1預分頻器后分頻提供。
②定時器時鐘經過PSC 預分頻器之后,即CK_CNT,用來驅動計數器計數。
③計數器CNT 是一個16 位的計數器,向上,向下,向上/下計數模式,最大計數值為65535。當計數達到自動重裝載寄存器的時候產生更新事件,并清零從頭開始計數。
④自動重裝載寄存器ARR 是一個16位的寄存器,這里面裝著計數器能計數的最大數值。當計數到這個值的時候,如果使能了中斷的話,定時器就產生溢出中斷。
計數器信號
其中CK_CNT時鐘就類似心跳,CNT計數器就類似心跳次數。要實現60秒定時,CK_CNT是1s,我們設置CNT計數器向上計數開啟中斷,因為只有溢出時,也就是計數到65535時才會有中斷,那么我們設置CNT計數器為65535-60=65475,開始計時,那么60秒后就會產生中斷。
設置自動重裝載寄存器ARR也為65475,當CNT計數器溢出時,自動重裝載寄存器ARR就會自動裝載到CNT計數器中,就能實現自動循環定時60秒。經過上面分析,精確定時的關鍵在于CK_CNT的頻率,而CK_CNT是由定時器時鐘分頻而來的。
注:為什么需要中間對齊模式:
在永磁同步電機的控制中,需要對電機的三相定子施加一定的電壓,才能控制電機轉動。現在用的較多的是SVPWM(SVPWM的具體原理會在后面另寫一篇博客說明),要想產生SVPWM波形,需要控制的三相電壓呈如下形式,即A、B、C三相的電壓是中間對齊的,這就需要用到stm32定時器的中間對齊模式了。
審核編輯:劉清
-
單片機
+關注
關注
6039文章
44575瀏覽量
636384 -
ARM
+關注
關注
134文章
9107瀏覽量
367970 -
寄存器
+關注
關注
31文章
5357瀏覽量
120632 -
STM32
+關注
關注
2270文章
10906瀏覽量
356560 -
電源系統
+關注
關注
3文章
621瀏覽量
37809
原文標題:萬字長文解讀STM32-1
文章出處:【微信號:TT1827652464,微信公眾號:云深之無跡】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論