日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

【直达本质】超快 STM32 系统入门指南

發布時間:2024/1/1 windows 80 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【直达本质】超快 STM32 系统入门指南 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?計算機類的教程多,框架和 API 用法講的全面,成系統的教程很多,CSDN上、知乎上很多個人學習記錄和全面的成書的教程,而且生動形象有甚至有動畫講解,回過頭來看嵌入式的教程,又臭又長。本文 Github 地址。

兩種學習模式,一種是從底層開始看大厚書學習,但這只適合那些理解能力和前后關聯能力強甚至有天賦的人來看,說白了不是設計給新人看的,而是給熟練的人當字典來看的,現在學校的課本一上來直接懟抽象的概念和公式,可能導致的在網上寫教程的也有這毛病,不人性化。另一種學習是面向應用來學,就是下面要說的,是 “真-面向應用”,對于超快 STM32 入門來說就是:聽正常人能理解的句子來了解外設概念和意義,然后直接從 API 入手。

這篇文章需要有 基本數模電和單片機的概念、C 語言基礎和良好英文(或翻譯)。


目錄

第一個外設

進入主題

資源站

總結


第一個外設

這時候可以備好 STM32 編程手冊《STM32F10xxx參考手冊》。

GPIO(General-purpose input/output)為通用目的輸入輸出口,所謂通用即不只可以用軟件控制高低電平的變化,還有輸入、開漏等功能,根據不同應用場景配置成不同功能。以下是該外設的內部數字電路的電路框圖。

該圖就是 STM32 芯片 里面 GPIO 外設部分的真實存在的電路的框圖。

下面兩個 P-MOS 和 N-MOS 就是控制輸出 I/O 口的高低電平,如果 P-MOS 導通,則輸出高電平,這稱為 “推挽輸出” 模式,輸出有一定的驅動能力,輸出高電平為 芯片供電電壓,即 3.3V,低電平為接地,即 0V,可以先這么理解。

如果 下面兩個 P-MOS 和 N-MOS 均不導通,那就是 “浮空輸入” 模式,外接的高低電平可以讀入,外部接上按鍵,就可以用按鍵控制東西。

如果 輸出的時候是 P-MOS 一直處于關閉狀態,而只有 N-MOS 打開或關閉,那就是 “開漏輸出” 模式,在該口上拉一個電阻到 Vref 電壓,那么輸出高電平就是 Vref 電壓,這么做可以改變輸出高電平的電壓,可以任定,而不是上面 “推挽輸出” 時候固定的 3.3V。

圖中還有還有上、下拉電阻,還有復用功能,就是配置別的外設比如 SPI、PWM 等的輸出要從此 I/O 輸出,這些功能組合可以得到這些模式:輸入浮空、輸入上拉、輸入下拉、模擬輸入、開漏輸出、推挽式輸出、推挽式復用功能、開漏復用功能。

進入主題

下載、安裝和會用 STM32CubeMX 軟件。

STM32CubeMX 新建一個工程,選擇 STM32F103C8T6,將 PA8 設為 推挽輸出模式,如下圖。

導出工程。路徑不要有中文和空格,IDE 選擇 MDK(即 Keil 5),右上角生成。

打開 MDK 工程。

打開 main.c 即看到寫用戶程序的地方,我們在 STM32CubeMX 軟件里面圖形化的配置了一個推挽輸出模式的 PA8 引腳,所以現在工程中有了一個 MX_GPIO_Init() 函數,里面就是通過 HAL 庫配置該 I/O 的程序。下面添加上注釋來說明。

/* 聲明一個 GPIO_InitTypeDef 類型的結構體 名叫 GPIO_InitStruct,該結構體打包了配置 I/O 的所有參數,填這個結構體即可 */GPIO_InitTypeDef GPIO_InitStruct = {0};/* 使能 GPIO 的時鐘,STM32 中,每個外設都要有時鐘信號做驅動,數字電路尤其是時序、同步邏輯電路,當然都需要時鐘 *//* GPIO Ports Clock Enable */__HAL_RCC_GPIOA_CLK_ENABLE();/* 預先設置該 I/O 的輸出電壓。在初始化之前,I/O 是浮空的,當初始化完畢之后 I/O 立馬變為設置的高或低電平 *//*Configure GPIO pin Output Level */HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);/* 配置 I/O,結構體 GPIO_InitStruct 共有 Pin、Mode、Pull 和 Speed 這幾個參數,分別填為 I/O口 8、推挽輸出、沒有上下拉電阻、翻轉速度為低然后調用 HAL_GPIO_Init() 函數,填入 結構體 GPIO_InitStruct 的指針,該函數會根據結構體 GPIO_InitStruct 里面的參數配置 I/O 的寄存器 *//*Configure GPIO pin : PA8 */GPIO_InitStruct.Pin = GPIO_PIN_8;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

那么問題就來了,結構體 GPIO_InitStruct 共有 Pin、Mode、Pull 和 Speed 這幾個參數,除此之外,庫里面外設那么多,每個外設都有好幾個結構體和那么多 API,我怎么知道怎么用?

先進行全編譯,如下圖。不全編譯不能做下一步的 “跳轉”。

在 GPIO_InitTypeDef 上面右擊,選擇 Go To Definition Of 'GPIO_InitTypeDef',即可跳轉到 stm32f1xx_hal_gpio.h 文件里面 該結構體類型定義的地方。

在這里面,一目了然,該結構體都有哪些參數,每一個參數都是做什么的,如下圖。

那么每一個參數可以填寫的值,HAL 庫也有定義,每一項后面都有注釋,比如上圖的 Mode 參數,注釋說 可填入的值 參考 GPIO_mode_define這里,那么就 按快捷鍵 ctrl+f 調出搜索框,填入GPIO_mode_define搜索,如下圖,找到這些宏定義。其中GPIO_MODE_INPUT就是浮空輸入模式,GPIO_MODE_OUTPUT_OD就是開漏輸出模式,GPIO_MODE_ANALOG就是模擬輸入模式(用于 ADC 模數轉換外設引腳),帶有 AF 字樣的就是復用功能,帶有 IT 字樣的就是中斷功能。

HAL 庫好就好在,每個外設的配置流程和結構體、宏定義的命名非常規范,命名有意義而且有規律。結構體知道怎么填寫了,那么想知道一個外設有哪些 API,就在每一個外設的 .h 文件里面。還在stm32f1xx_hal_gpio.h里面,如下圖所示,就是 GPIO 外設所有的可供用戶調用的函數,即Exported functions部分。其中HAL_GPIO_Init()為初始化函數,HAL_GPIO_ReadPin()為讀 I/O 電平函數,HAL_GPIO_WritePin()為寫 I/O 電平函數,等等。

還有最后一件事,這些 API 在哪里使用,比如初始化時候先用什么后用什么,這些也在源碼注釋里有詳細的介紹,請打開stm32f1xx_hal_gpio.c文件,拉到最上面,如下圖。兩大塊,第一個GPIO Peripheral features就是介紹該外設的特性,即能做什么,另一個How to use this driver就是細致介紹如何使用這些 API,即怎么做,需要會英文或者用翻譯哈。這里介紹的是 GPIO 外設,HAL 庫具有一貫性,對于每一個外設的源文件和組織形式都是這樣的哈,比較人性化。

我跟你講,大多數第一個寫教程的,基本都是看源碼、看源碼注釋和看官方手冊,再加上不斷測試、驗證想法而得到足夠多經驗的時候才學會的,所以我這里把這個從源頭獲取技能的流程介紹一遍,是更有用的。

該工程還包括的函數SystemClock_Config()用于 STM32 時鐘(RCC)初始化,其它還包括 STM32 的眾多外設,在此不多做介紹,漁已經演示了。還有一些底層概念需要了解,接著往下看。

看看 MDK 界面中左邊的各種源文件:

  • main.c:就是用戶寫主程序的地方。

  • startup_stm32f103xb.s:該文件是官方用匯編寫成的啟動文件,MCU 是微處理器,處理器就是一個復雜的數字電路,該電路的核心有很多寄存器(處理器寄存器)需要初始化,啟動文件就是把這些初始化程序固定下來,用戶不用管也不用改動,主要內容有初始化中斷向量表、定義堆棧空間、準備 C 語言環境和跳轉到 main() 函數等等。

    ARM Cortex-M 系列處理器在函數跳轉的時候有硬件自動的使用棧來保存現場和恢復現場:

    ARM 系列系列詳細看這篇文章【主線劇情 番外01】ARM & SOC 系列快速鳥瞰 - 知乎 (zhihu.com),

    棧和跳轉等可以看 【主線劇情01】ARM & i.MX6ULL 基礎學習記錄 - 知乎 (zhihu.com) 這篇文章最后的 “ARM異常處理 & 啟動文件的示例” 章節,雖然這些知識點對于新人有點超前了。

  • stm32f1xx_hal_gpio.h 和 stm32f1xx_hal_gpio.c :這類文件就是 HAL 庫的源文件,操作外設就調用這些文件里面的 API 即可,所有 API 和詳細使用方法 在 .h 和 .c 文件的注釋里均有詳細說明。

  • stm32f103xb.h:該文件定義 stm32f103xb 系列 MCU 的所有 外設的寄存器,給各個外設的寄存器地址上面加個結構體,以便訪問和修改,下文會幫助理解這段話。

MCU 的外設的寄存器都被映射到內存的各個地址上(物理連接),在 C 語言中讀/寫該寄存器,就是讀該外設的狀態和控制外設行為,外設本質都是數字電路,外設只會根據寄存器內 0 / 1 二進制值去做對應的行為。

以下例子,比如要對內存中 0x20E0084 位置開始的四個字節進行復位(寫 0)和置位(寫 1)的操作,C 語言寫法如下(程序引自 Staok/coding-style-and-more):

static volatile unsigned int *reg_temp = (volatile unsigned int *)(0x20E0084);/* 置位的標準寫法 */ /* 下句表示把 內存中 0x20E0084 位置的 第1、2、5、14位進行置1,其他位不變 */ *reg_temp |= ( (1 << 14) | (1 << 5) | (1 << 2) | (1 << 1) );/* 清位的標準寫法 */ /* 下句表示把 內存中 0x20E0084 位置的 第0、3位進行清0,其他位不變 */ *reg_temp &= ( ~( (1 << 3) | (1 << 0) ) );/* 讀寄存器 */ volatile unsigned int val = *reg_temp;

進一步,MCU 有上千個寄存器,這么一個一個定義肯定不行,下面就是 HAL 庫里面的方法,將結構體的地址賦值為相應寄存器的地址,即創建內存地址上連續區域的結構體,該方法常用于嵌入式開發。如下例子(程序引自 Staok/coding-style-and-more):

typedef struct {volatile unsigned int URXD; /**< UART Receiver Register, offset: 0x00 */volatile unsigned char RESERVED_0[60];volatile unsigned int UTXD; /**< UART Transmitter Register, offset: 0x40 */volatile unsigned int UCR1; /**< UART Transmitter Register, offset: 0x44 */ } Periph_x_Type;/* Periph_x 這個外設的寄存器的基地址為 0x2020000 */ #define Periph_x_BASE (0x2020000u)/* 設置結構體 Periph_x 的地址為 Periph_x_BASE */ #define Periph_x ((Periph_x_Type *)Periph_x_BASE)/* 讀取和設置寄存器(這里以置位舉例) */ Periph_x->UCR1 |= (1 << 2);

接著打開stm32f103xb.h文件,看看是不是所有外設的寄存器都被打包成了結構體,然后把結構體的地址賦值為對應寄存器的地址。

比如 TIM2(定時器 2) 外設的寄存器地址定義如下,外設基地址 + 外設偏移地址。

然后定義將所有 TIM 外設有關的寄存器打包的結構體,如下圖所示。

然后將 TIM2 的地址(TIM2_BASE)強轉為TIM_TypeDef指針類型,然后將這個整體重命名為 TIM2,如下圖。

到此,該外設寄存器地址與該結構體綁定完成,以后訪問結構體 TIM2 下面的參數,都是直接訪問對應的實體寄存器。

STM32 HAL 庫將這些對寄存器的操作封裝成了函數,調用函數即可操控外設。

STM32 的庫函數有兩個,標準庫 和 HAL 庫,前者早在 2011 年停止更新維護, HAL 庫是現行主流的,STM32CubeMX 軟件生成的工程就是使用 HAL 庫的,不過我不太信任用該軟件生成的工程,而且該軟件產生的工程所用的 HAL 庫與單獨下載 HAL 庫在 API 上竟有出入,所以一般我習慣拿它來產生驅動配置程序,然后手動移植到自己的工程,這樣心里有底。

以上描述的過程是自己探索與發現的形式,就像探索世界,但可能也會遇到很多新東西和困難,有參考總歸比沒有強,推薦可以同時參考一個手冊來學,比如正點原子的 STM32 的 HAL 庫的手冊,開源的可以免費下載,下面就是各大廠的資料網址匯總。

資源站

各大廠家對 STM32 出了特別特別特別豐富的教程和例程,如果比較熟悉外設,直接看他們的例程源碼即可,快速掌握各種技巧。各大家的官網和資料下載地址如下:

正點原子:

  • OpenEdv-開源電子網-正點原子論壇 有問題可以在這里找,也可以平時沒事逛一逛;

  • 正點原子官方的個人空間_ 嗶哩嗶哩 _bilibili 所有教學視頻;

  • 原子哥教學平臺,專注電子技術教學 (yuanzige.com);

  • 正點原子資料下載中心 — 正點原子資料下載中心 1.0.0 文檔 (openedv.com) 各種開發板的電路原理圖、例程和教程 統統薅走!

野火:

  • 野火電子論壇 - (firebbs.cn) 論壇;

  • 野火_ firege的個人空間 _ 嗶哩嗶哩 _bilibili 所有教學視頻;

  • 野火產品資料下載中心 — 野火產品資料下載中心 文檔 (embedfire.com) 薅羊毛。

安富萊:

  • 硬漢嵌入式論壇 - Powered by Discuz! (armbbs.cn) 論壇;

  • 武漢安富萊電子有限公司官方網站。STM32開發板,無線IO模塊,H7-TOOL工具,嵌入式系統 (armfly.com) 官網;

  • 【安富萊】各種開發板和模塊的資料下載匯總貼(2021-08-30) - 安富萊電子 - 博客園 (cnblogs.com) 資料下載站。

硬石:

  • 硬石電子 - 社區 (ing10bbs.com) 論壇;

  • 硬石科技的個人空間_ 嗶哩嗶哩 _bilibili 教學視頻;

  • 硬石開源資料下載鏈接(該帖總是最新資料) - 硬石資料更新 - 硬石社區社區 (ing10bbs.com) 資料下載站。

原子、野火、安富萊和硬石各有側重,可以廣泛借鑒:野火、正點原子 非常全面;安富萊偏 M4F 的 DSP 使用;硬石偏電機控制,有步進電機、有、無刷電機。

STM32 官網資料下載站,是源頭,可以找到任何官方的東西,包括選型手冊,好好把握:

  • 中文站:STM32 | 產品 | STM32/STM8 | MCU單片機 | 意法半導體STM | 意法半導體STM | STM32/STM8微控制器 | MCU單片機 (stmcu.com.cn);

  • ST 官方:微控制器與微處理器 - STMicroelectronics。

總結

上述方法一句話總結。外設的概念,比如 FSMC、DMA 等,可以先上網查,知道它是做什么的(比如 UART 外設是串口來收發數據,I2C、SPI,重點看明白時序圖,FSMC 是 SRAM 接口外設,DMA 是數據在內存間通過硬件傳輸的途徑且不占用處理器資源,等等),然后用 STM32CubeMX 生成例程,看外設如何初始化(看例程學習是最快的),然后看源碼注釋了解 API 詳細使用(當成字典隨用隨查),就用起來一個外設了,然后按此法循環每一個外設,外設都依照此方法一個一個擊破,精神集中的話沒幾天就掌握不少外設的使用了。

這里有一個 STM32 程序模板 Staok/stm32_framework (github.com),其幾乎寫好了大部分外設的驅動,大塊復制的時候要注意其開源協議。這里有一個 C 語言的編寫規范 Staok/coding-style-and-more (github.com),其幾乎 “無所不包”。

要知道適合大多數人的上道的學習,是先會用(會快速獲得成就感,如同游戲般及時獲得反饋),然后再去了解架構和細節方面的東西(有興趣、有信心了之后才會面對這些而不犯怵),當用的比較熟了之后,有了一些自己的感悟和理解,然后去 干 大部頭的教程,比如幾十個小時的視頻或者上千頁的 PDF(推薦只看 PDF 文字教程而不去看視頻教程)。

—— 我一直覺得,應該減少人們走彎路,這也是 “二項玻”定則 中 “簡化之能夠簡化” 的一個重要延申理念。peace。


首發? 知乎?Github 地址?于 2021.9

總結

以上是生活随笔為你收集整理的【直达本质】超快 STM32 系统入门指南的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。