一、實驗準備
1.模板demo
原因呢,我在第一講中已經說過,費盡千辛萬苦搭建了一個模板,流過多少淚、費勁多少事,只有親自搭建過的才會體會到(第一講我只是講了組成,后續有機會,我將帶大家親手搭建一個),搭建完成后,備份壓縮(玩過Linux的大概有點感觸,配置了一個新環境,就得做個鏡像,哪天系統崩了,就可以重裝系統,這里也是一樣的)。
2.板級支持包
就是在我的工程文件中,所有以”Bsp_”開頭的文件,位于BSP文件夾下:
BSP文件夾下有兩個文件夾:BINC、BSRC。一個存放h文件,一個存放c文件,是可以放到一個文件中,我只是為分類能夠明顯點。
PS:關于這種分類,我在其他文件夾中也有類似的設計,有興趣可自行查找,另外無論去不去查找,請記住這里的東西,我在本章后面還會用到這里的知識點。
另外介紹一下什么“板級支持包“:
百度到的一段介紹,本來BSP是用來實現對操作系統的支持,比如我們在使用PC時,有顯示器、有鍵盤、有鼠標,PC的操作系統,比如Windows、Linux系統,它們只是用來管理這些資源,向用戶或者應用提供使用接口(如果你《大學計算機基礎》這門課還記得的話)操作系統通過BSP來訪問硬件設備。單片機到現在(起碼到我們正在學習的這個初期階段)還無法移植操作系統。但是我們也需要去使用外設的,如使用usart來跟PC進行通信,我們需要配置usart的工作模式。這里,BSP就涵蓋了一些對硬件外設的操作。
總之,一句話,有了BSP,我們可以隨心所欲的配置單片機上的外設,而不需要去關心如何去配置,當然,如果想研究比如usart的工作原理時,不好意思,讀源碼吧。
另外,補充一點,BSP是我在學習時候編寫的,是基于ST公司的固件庫(位于SYSLIB文件夾中)所做的二次開發。
二、實驗目的
配置gpio工作模式,使其可以讀取一個外部按鍵的狀態
配置gpio工作模式,使其可以控制一個LED燈
三、實驗前理論準備
打開”STM32F4xx中文參考手冊.pdf”文件(我很反感使用中文手冊,雖然我英語也不是很好,我建議可能的話盡量使用英文原版的datasheet,建議,建議),第7章,講的是通用I/O(GPIO)。
和51單片機不同,STM32等一些相對高端的單片機,它的I/O口可以工作在輸入、輸出、復用、模擬,不僅如此,還可以上拉、下拉、浮空,沒完呢,還有推挽模式、開漏模式。
當初我在學習時,那叫一個頭疼,去**的(和諧音),好難。不過仔細想想,這么設計也是必須的,存在即合理,接下來,解釋一下這些東西:
(都是大白話,不要見怪……)
輸入:數字信號流入單片機引腳;
輸出:數字信號從單片機引腳流出;
復用:有些引腳在被設計成特殊功能后,硬件會控制它,不需要用戶在程序中操作;
模擬:模擬信號流入單片機引腳;
上拉:引腳通過一個電阻連接到VDD;
下拉:引腳通過一個電阻連接到GND;
浮空:引腳啥也不接;
推挽模式:可理解為普通;
開漏模式:漏極開路(理解它,需要一點模電知識,場效應管相關知識);
用大白話解釋了一遍,接下來,用幾個硬件電路來從理論方面解釋一下:
下圖是”STM32F4xx中文參考手冊.pdf”文件中的第176頁圖17:
這張圖,完整的展示了GPIO的工作方式,特別說明,這只是一個引腳,在STM32F407VE上,每16個為一組,像這樣的一組,STM32F407VE有好幾組(GPIOA、GPIOB、GPIOC…自己去找找吧,我就不多說了)。
PS:為了能夠看懂這張圖,我們先來解釋一些特殊符號:
TTL施密特觸發器:詳細介紹請百度,我這里只告訴大家,它可以容忍信號的一些小波動(畢竟空間里的信號永遠不會穩定,不服來辯)。
場效應管:詳細介紹也請百度,理解為電子開關,左側的兩根線時控制信號(注意,這里是兩個不同的場效應管!),另外,有小圓圈的表示低電平有效。
二極管保護電路:這個嘛,是為了容忍引腳輸入5V信號的,因為STM32F407VE是3.3V的,沒有這個電路的話,分分鐘鈔票送到馬云爸爸兜里啊。當然,我們本章實驗最高也就接入3.3V,所以,這個電路就沒作用,既然沒作用,也就不用考慮了。
然后,我們就可以分析了:
首先是輸入模式:圖中的紅線就是輸入信號的流動過程,下方的輸出我們就不考慮了。
輸入模式的信后從引腳傳入,進來后,有一個上拉電阻和下拉電阻的選擇,是可以控制的(拉上開啟,接入上拉電阻;拉下開啟接入,下拉電阻;都關閉,浮空;都開啟,你丫是有病吧!),之后,信號可能傳入模擬通道(如果開啟了ADC設備,信號會被送到ADC中),然后就是TTL施密特觸發器,經過TTL施密特觸發器,信號相對穩定,一些小的波動被忽略了;然后,信號可以進入復用功能輸入通道,如果開啟了復用工作模式,相關硬件會來接管這個信號,硬件會自行判斷;最后的最后,進入輸入數據寄存器,到這里,信號就被存儲到單片機里了,用戶就可以訪問這個所謂的輸入數據寄存器來感知傳入的信號是高電平還是低電平了。
PS:到底信號能否進入模擬通道、復用功能輸入通道,是靠一個開關(學名叫寄存器)來控制的,想知道的自己查找嘍。
另外,說一個冷門的知識點,不管模擬通道、復用功能輸入通道是否打開,信號總會進入輸入信號寄存器,也就是說,無論是什么信號(模擬也好、數字也好,還是復不復用都好),用戶總是可以去主動讀取這個輸入信號。(注意,這個以后你一定會用到的,我以我這輩子的桃花做擔保,用不到,我一輩子遇不到她!)
再來是輸出模式:
輸出模式比較麻煩了,不過也不是沒有突破點。
首先,按照我之前說的,不要看二極管保護電路(不知道那個是,倒回去看去!),然后,暫時(注意是暫時!)不看輸入驅動器(再強調一起,暫時不看!)。好了,該說的都說了,來分析吧。
信號是從左到右,從單片機內部到引腳:首先是寫,這個寫需要注意一下,不是直接寫進輸出寄存器,而是通過向置位和復位寄存器(這是兩個寄存器!)寫數據,然后單片機硬件再把置位和復位寄存器里的數據轉移到輸出寄存器中**(PS:置位和復位寄存器的值是為1有效,如果置位寄存器的某一位為1,則這個位對應的引腳最終會輸出高電平,為0無效;如果復位寄存器的某一位為1,則這個位對應的引腳最終會輸出低電平,為0無效。建議大家仔細閱讀這段話。)。**
為什么要這么麻煩?有道理的,往下看:
輸出數據寄存器的數據還會來自片上外設,如USART1,會使用PA9和PA10來傳輸數據。設計成這么復雜,目的只有一個,在當USART1工作時,可以通過關閉從置位和復位寄存器到輸出數據寄存器的通道,來防止用戶對片上外設的輸出操作產生干擾。
隨著信號接著看,輸出數據寄存器的數據到了輸出控制那里,這里是很復雜的一塊電路,不過只要知道這里會完成信號的調理、邏輯轉換即可,還有的就是可以選擇用不用后面的邏輯門(通過這個來選擇工作在開漏模式還是推挽模式)。同時,復用功能的輸出也會對輸出進行控制。輸出控制之后是開關門,通過了邏輯門,信號才會被轉化為真正的信號(因為在此之前,信號可能只是存在于寄存器中的一個表示形式,好比U盤里的數據,雖然這個比喻不太恰當);通過了邏輯門,就到了上拉、下拉電阻接入控制區,在之后,就是輸出引腳了。
特別注意一下,右下角有一個模擬輸出,不要忘了,畢竟還有個東西叫DAC!
PS:輸出模式的工作原理基本說完了,不過我還要補充一點,我再講輸出模式時,說過暫時忽略這個模式下的輸入通道,好了,現在要開始講了:
首先貼幾個截圖,都可以在”STM32F4xx中文參考手冊.pdf”文件的第7章找見:
可以發現,GPIO模式的工作方式無非就是輸入、輸出、模擬、復用模式,除了模擬模式時,其他所有的模式都開啟了施密特觸發器,說明了什么?說明了什么?說明了什么?說明了,這幾種模式下,我們輸出了信號之后,可以回讀信號;也可以輸出信號,然后讀入信號而不需要切換工作模式,只需要讀信號時對輸出做些處理。
同時,可以根據這幾個截圖的信息重新再回顧一下輸入輸出模式的工作原理(有點馬后炮了,早不提醒!實際上,工作原理需要大家下點功夫去學習,3遍、5遍是少不了的)。
二、C語言那些被遺忘的語法
本來不想去說的,不過當下某學校的C語言這么課,講的真是,***(和諧音),實在看不下去了,我就再啰嗦幾句吧,自認為C語言很棒的,自動跳過:
1.結構體
首先結構體的定義:
struct
{
uint8_t param_a;
uint16_t param_b;
} a_struct;
或:
struct newStruct
{
uint8_t param_a;
uint16_t param_b;
};
struct newStruct a_struct;
或:
typedef struct
{
uint8_t param_a;
uint16_t param_b;
} newStruct ;
newStruct a_struct;
PS:順便問一個小問題,變量a_struct所占存儲空間大小是多少?
還有,無比仔細琢磨三種方式的特點;
結構體是可以嵌套的:
比如:
struct tag_1
{
struct tag_1 *ps; //注意,只能是個指針!
uint8_t param_a;
uint16_t param_b;
} ;
但是,這樣就錯誤了:
typedef struct
{
NODE *ps; //錯誤,NODE還沒有被定義!
uint8_t param_a;
uint16_t param_b;
} NODE;
好了,暫時結構體先會這些,我主張的學習的總之就是:缺哪補哪,打哪指哪;
2.位操作
這個是在普通C中常常被忽略的東西,因為在PC端,我們學習C的目的是為了簡化繁瑣的科學計算,所以往往很少去糾結位與位的操作;
首先,回憶一下位操作符:&、|、~、^;(我記得就這4個吧,不好意思,忘了);
然后,出幾個題:
0xFF & 0xFE = ?
0xA0 | 0x0B = ?
0x11 ^ 0x11 = ?
…
PS:琢磨一下我出的三個題的特點,聽我的,馬上就會有用的。
最后,跟賦值運算符結合”=”一下:于是就有了:&=、|=、^=;
3.移位操作
老實說,這個也是位操作的范疇,因為太常用了,我把它揪出來單獨說:
首先,移位操作符有兩個:>>和<<;
然后,還是出幾個題:
a = 0x01;
b = a<<2;
b = ?
a = 0x80;
b = a>>6;
b = ?
…
4.數據的存放
數據在存儲器中是如何存放的?
學過C語言的我們都知道,char、int、float、double,學習了C#之后,還有string等,學習了Python后,還有complex啥的(雖然人家python主打的概念是標簽)等等。
那么,數據到底如何存放?
我想這么來說:首先,計算機能識別的,就是通電和斷電(抽象點,就是0和1),這個概念叫二進制,一個二進制只有兩個值,換句話說,只有兩個狀態,也就只能表示兩個結果,這樣的一個二進制稱之為“1位數據(bit)”,表示的數據種類太少了。將8個二進制位捆綁在一起,這樣就可以表示2^8種結果(不會的,回去復習高中的排列、組合),就可以表示最大數值為255的十進制整數,這樣的8個二進制位稱為“1個字節(Byte)”。想表示的數值再大怎么辦,16個二進制唄,沒錯,不過別叫16個二進制位了,叫兩個字節。再大呢,4個字節(以后會知道,4個字節叫字(Word),所以2個字節也叫半字(Half Word)),顯而易見,8個字節叫雙字(Double Word)。想表示小數怎么辦,最開始是使用定點數,后來就使用浮點數(PS:關于定點數和浮點數,不是我這里的重點,請自行百度)。
所以,數據在存儲器中是按“組”存放的,這個“組”,指的就是字節、半字、字、雙字等。至于什么char、int、float,只是對這個“組”按照不同的需求進行別名:比如,若一個字節內存放的時ASCII碼,那么這塊數據的類型就是char;當然,若使用兩個字節存放一個有符號的整數,那么這塊數據的類型就是int;其他的也類似。所以,要明白,所謂的類型,只是對數據類型的說明和所占空間長度的說明,數據存放的本質,還是以二進制的形式按照不同的空間分塊方式(1個字節、2個字節…)來存放。
PS:似乎我說的比較毀三觀,也有點懵,不過不要緊,多寫寫程序,就會明白:什么char、int,在我STM32的世界里,統統是int8_t、uint8_t、int16_t、uint16_t、int32_t、uint32_t。
然后我在留一個小問題:負數是怎么存放的?
三、開始實驗
1.添加需要的ST固件庫
這個可能我在模板里已經添加了,沒關系,一起來熟悉一下:
要添加的是:stm32f4xx_gpio.c和stm32f4xx_rcc.c,雙擊”SYSLIB”在之前說的SYSLIB文件夾下找到這兩個文件,添加;
其他的嘛,是單片機正常工作所必須的,慢慢就會知道了,這里只有stm32f4xx_gpio.c和stm32f4xx_rcc.c和本次實驗密切相關;
2.添加需要的BSP文件
同樣,雙擊”BSP”在之前說的BSP文件夾下找到這兩個文件,添加;
3.在main.h中注冊
4.設置h文件的包含路徑
然后點擊下圖中紅框中的按鈕:
添加如下內容:
當然了,我已經添加好了,不過大家可以去熟悉一下流程;
5.主函數中書寫測試代碼
程序其實很簡單,使用BSP提供的接口初始化led燈和按鍵(其實就是配置gpio的輸入和輸出方式,詳細配置我們一會挨個看)。
PS:特別說明的是,程序中用到了一個比較經典的案例,就是按鍵消抖,同樣,什么是按鍵消抖,請百度。
四、分析BSP配置代碼,學習GPIO
大家打開”Bsp_led.c”文件,找到第24行,這個就是gpio方式的配置過程:
第40行:
RCC_AHB1PeriphClockCmd((1<<(((u32)GPIOx - AHB1PERIPH_BASE)>>10)), ENABLE);
1
這個是使能時鐘,就是給所使用的GPIO開啟能量,這個是我寫的一個通用方式,其一般形式是:AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);不要糾結,以后我會詳細講解。
第45至50行:
gpio.GPIO_Pin = (1< gpio.GPIO_OType = GPIO_OType_PP; //配置工作模式,推挽輸出 gpio.GPIO_PuPd = GPIO_PuPd_UP; //配置工作模式,上拉模式 gpio.GPIO_Speed = GPIO_Speed_50MHz; //配置翻轉速度,50MHz(即中速) GPIO_Init(GPIOx, &gpio); //將配置真正寫入到寄存器 這個是STM32中的初始化常用方式,我說過,ST的外設太多,導致寄存器很多,一般人根本記不住,所以ST公司就提供了固件庫,用戶通過ST提供的接口函數的參數進行設置,然后調用初始化函數,進行初始化。 至于為什么使用結構體,想想就知道:要配置的內容太多,而且類型又不一樣,有8位數據,有16位數據,所以數組是不能用的,結構體恰恰是最佳選擇。 而且GPIO_Init()這個函數的實質,就是把結構體gpio包含的內容,組合后賦給指定的寄存器: PS:仔細看”Bsp_led.c”文件的第45行,這個移位指令能告訴我當PinNum為2是1<< PinNum是十六進制的多少么?然后使用Go to the Definition操作看一下GPIO_Pin_2是多少? 五、問題思考 1.以同樣的方式看一下BSP_KEY_InitConfig()的配置過程 2.打開”Bsp_led.c”文件,找到第24行 RCC_AHB1PeriphClockCmd((1<<(((u32)GPIOx - AHB1PERIPH_BASE)>>10)), ENABLE); 當GPIOx為GPIOA時,((1<<(((u32)GPIOx - AHB1PERIPH_BASE)>>10))的十六進制結果是多少? 同樣使用Go to the Definition操作看一下RCC_AHB1Periph_GPIOA的十六進制結果是多少?發現了什么?
這個是對GPIO_Init()函數執行Go to the Definition操作(還記得怎么操作么?忘記的話回去看第一講),可以發現,好多”&=”和”|=”,我這里先不介紹怎么用,只是說它們一個叫置位、一個叫復位,相關細節,我會拿出一講詳細介紹。
上一篇:stm32f4的GPIO和位帶區
下一篇:STM32F4xx GPIO函數解釋
推薦閱讀
史海拾趣
在市場拓展方面,奇力公司采取了多元化的銷售策略。除了與大型知名企業合作外,奇力公司還積極開拓國內外市場,參加各類展會和論壇,提升品牌知名度和影響力。同時,奇力公司還注重品牌建設,通過提升產品質量和服務水平,樹立了良好的企業形象。
在穩固了電子元器件和模塊市場地位后,Emmoco開始尋求多元化發展。公司利用自身的技術優勢和市場經驗,逐步拓展產品線,涉足智能家居、物聯網等領域。通過不斷的技術創新和市場拓展,Emmoco成功實現了產品線的多元化,為客戶提供更加全面和多樣化的解決方案。
AC Photonics Inc非常重視人才培養和團隊建設。公司建立了完善的人才培養和激勵機制,吸引了一大批優秀的研發人才和管理人才加入。同時,公司還注重團隊建設,通過定期舉辦團隊活動、開展員工培訓等方式,增強團隊凝聚力和向心力。這些措施為公司的持續創新和發展提供了有力的人才保障。
隨著全球電子市場的不斷擴大,CW Industries也積極拓展其國際業務。公司通過參加各種國際電子展會和交流活動,與全球各地的客戶和合作伙伴建立了廣泛的聯系。這不僅為公司帶來了更多的商機,還使得CW Industries能夠及時了解國際市場的最新動態和技術趨勢。通過這些國際交流活動,CW Industries不斷提升其品牌影響力和市場競爭力。
近年來,芯旺微電子在資本市場也取得了顯著的成果。公司先后完成了多輪融資,吸引了眾多知名投資機構的關注和投資。同時,芯旺微電子也在積極推進上市進程,計劃通過資本市場進一步拓展業務規模和提升品牌影響力。這些戰略布局的實施不僅為芯旺微電子提供了更多的資金支持和發展動力,也為其未來的發展奠定了堅實的基礎。
為了進一步擴大市場份額,ECS公司開始積極拓展全球市場。他們與全球各地的云服務提供商建立了緊密的合作關系,共同為客戶提供更加全面、便捷的服務。同時,ECS公司還積極參加國際云計算展會和論壇,與國際同行交流經驗和技術,不斷提升自身的競爭力。通過這些努力,ECS公司的品牌知名度和市場份額得到了顯著提升。
1. AD轉換器的分類 下面簡要介紹常用的幾種類型的基本原理及特點:積分型、逐次逼近型、并行比較型/串并行型、Σ-Δ調制型、電容陣列逐次比較型及壓頻變換型。 1)積分型(如TLC7135) 積分型AD工作原理是將輸入電壓轉換成時間( ...… 查看全部問答∨ |
|
事無巨細,數碼管閃亮 仍然是深夜,仍然精力充沛,遂來寫寫數碼管的顯示。篇幅也許會很長,各位看客最好端杯茶慢慢消遣。 言歸正傳,我們先看看什么是數碼管(圖片來自網絡): 上圖就是各種長相各種樣子的數碼管了,肯定很眼熟了吧。 簡單講講 ...… 查看全部問答∨ |
|
一個應用程序,當從某個盤符下讀寫數據時, 開始的時候要收到一個消息,結束的時候也要知道一個通知消息, 不知道有哪個高手知道怎么做. 我曾經參考過filemon,但是出現的消息太復雜了.搞不懂.… 查看全部問答∨ |
|
1.STM32F103先上電2406后上電 485通訊正常 2.2406先上電 在STM32F103上電時 會自動給2406發數(貌似是硬件上電就會這樣)然后2406就不能進接受中斷了 不能通訊 3.用串口調試助手給2406 ...… 查看全部問答∨ |
設計資源 培訓 開發板 精華推薦
- 高通攜手中國“汽車朋友圈”亮相2025上海車展: 加速駕駛輔助普惠,推動艙駕創新升級
- 工業市場正在快速回暖,德州儀器如何重塑電力電子市場?
- 特斯拉:美國交付的Model Y/3電池包已實現100%美國生產
- 地平線與博世深化合作,攜手為多家車企提供輔助駕駛產品
- 強化中國市場戰略布局,德州儀器正靈活應對全球關稅挑戰
- Molex莫仕通過本地合作和創新加強支持中國汽車行業
- 貿澤開售Texas Instruments適用于高分辨率AR HUD的 全新DLP4620S-Q1 0.46"汽車數字微鏡器件
- ROHM推出高功率密度的新型SiC模塊,將實現車載充電器小型化!
- 用上車規級UFS 4.0,讓出行變得高效且可靠
- 車載測試技術解析:聚焦高帶寬、多通道同步采集與協議分析