@
文章參考:
【STM32】STM32F4 GPIO八種模式及工作原理詳解
2021北京理工大學機器人隊第四屆薪火培訓 電控部分——單片機與GPIO
【SUES木鳶機甲工作室】RoboMaster電控組基礎培訓——單片機基礎
關於單片機
初識單片機
相信很多同學第一次看到“單片機”這個字眼的時候都不是很清楚其具體含義,上百度一查,看到類似下面的晦澀語句:
單片機也被稱為單片微控器,屬於一種集成式電路芯片。在單片機中主要包含CPU、只讀存儲器ROM和隨機存儲器RAM等,多樣化數據采集與控制系統能夠讓單片機完成各項復雜的運算,無論是對運算符號進行控制,還是對系統下達運算指令都能通過單片機完成。 由此可見,單片機憑借着強大的數據處理技術和計算功能可以在智能電子設備中充分應用。簡單地說,單片機就是一塊芯片,這塊芯片組成了一個系統,通過集成電路技術的應用,將數據運算與處理能力集成到芯片中,實現對數據的高速化處理。
其實,要想快速地理解一個東西最好的方法是看一看這個東西長什么樣子,應用是什么,怎么用它。
至於理解,最好是一邊使用一邊進行。
下面這枚黑色小方塊,就是所謂的單片機,就像前面百科說的那樣,其實就是一塊芯片,芯片周圍有根據芯片型號數量固定的引腳
常用的STM32F103C8T6,有48個引腳
但是這些引腳太細,太脆弱(易折斷),為了便於初學者進行學習,我們一般是使用開發板
單片機上很多外設,建議是用到什么學什么,“在戰爭中學習戰爭”,不過,在踏入外設使用這道門之前還有一個概念需要理解,那就是時鍾
時鍾
時鍾可以簡單理解為像單片機的心臟,每跳動一下,單片機各個電路就同步運行一下。只要單片機接上了電,無論單片機處於什么狀態(跑進while(1),進回調……),時鍾總是以一定的頻率在運行。
時鍾的頻率是通過高低電平來實現的,它決定着單片機運行的快慢,我們總是希望時鍾越快越好。
時鍾的信號源並不是單片機自動配置好的,須知參差多態乃是STM32好用的根源,我們可以根據內部/外部 以及 低速/高速這兩個方面來進行時鍾的選擇。一般情況下,我們會選擇外部高速時鍾,它頻率高,同時也更穩定
至於時鍾選擇如何在軟件中操作,那便是下面的事了,這里暫且不表
GPIO簡介
GPIO的全稱:General Purpose Input/Output
簡單地說,就是控制某個引腳進行輸入的讀取和輸出的高低電平設置嘛
general,就代表着這是一個相當基礎的功能,很多功能其實通過GPIO也是能夠實現的,狂風起於青萍之末,我們從最簡單的開始學起。
GPIO函數
我們使用的Cube能夠幫我們自動生成很多代碼,因此我們就介紹幾個與輸入輸出有關的函數
函數名 | HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) |
---|---|
作用 | 讀取引腳輸入電平高低 |
返回值 | 輸入電平高低情況,GPIO_PIN_SET(高電平,真實值為1),GPIO_PIN_REST(低電平,真實值為0) |
參數 | 引腳基本信息,若選擇引腳為PA14,那么函數可表征為:HAL_GPIO_ReadPin(GPIOA,GPIO_Pin_14); |
函數名 | HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState) |
---|---|
作用 | 設置引腳輸出電平高或低 |
返回值 | 無 |
參數 | 前兩個與Readpin基本相似,最后一個PinState就是選擇要設置的電平高低(就是readpin的返回值) |
函數名 | HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) |
---|---|
作用 | 翻轉某個GPIO引腳的電平狀態。如果為0則變為1;如果為1則變為0 |
返回值 | 無 |
參數 | 引腳基本信息,若選擇引腳為PA14,那么函數可表征為:HAL_GPIO_ReadPin(GPIOA,GPIO_Pin_14); |
八種輸入輸出模式
GPIO的八種模式的實現原理已經有大佬寫得很詳細了
【STM32】STM32F4 GPIO八種模式及工作原理詳解
不過其軟件方面沒必要學習,鏈接里使用的是標准庫,而我們使用的是HAL庫
在這里我就給一個簡單的理解
模式 | 說明 |
---|---|
浮空輸入 | 在無輸入的情況下讀取值不確定 |
上拉輸入 | 無輸入默認高電平 |
下拉輸入 | 無輸入默認低電平 |
模擬輸入 | 讀取值為模擬信號,需要額外開ADC |
開漏輸出 | 輸出的高電平高低取決於IO口外部電平上拉或下拉,低電平仍為低電平 |
推挽輸出 | IO口電平即為輸出的電平 |
復用開漏/推挽輸出 | GPIO啟用其他外設,除了輸出信號的來源改變 其他與開漏/推挽輸出功能相同 |
不過需要說明的是,我們平常使用GPIO,保持默認其實能夠滿足大部分需求
Cube和keil使用簡介
使用cube建立項目
keil使用
貼一個keil快捷鍵的使用那些快捷鍵不香嗎?無能KEIL 其二 快捷鍵
相信很多大一的同學看到keil這么多代碼頭都要暈了
不過不要害怕!我們是站在巨人的肩膀上,cube幫我們生成了很多底層的代碼,我們暫時可以不用去管它
就目前而言,我們只需要在main函數的while(1)中寫我們的內容即可
作業講解與點評
作業的前兩項,其實就是為了讓大家復習一下這節課學習的東西,無所謂多少,無所謂質量,只要做了就行
第三項作業就是比較難的了(相對而言),也是希望大家擁有能夠自學的能力,在聽我們第二節課的時候能夠輕松一點。組長也一再強調希望作業能夠難一點,所以我就直接把我們第二節課的內容搬了一點上來。
講解
ok,那就先來講解一下這份代碼
首先看看我寫在main函數之外的函數duty_output:
void duty_output(float duty){
if(duty<0||duty>1000)return;
for(int i=0;i<1000;i++){
if(i>duty)HAL_GPIO_WritePin(DEMO_GPIO_Port,DEMO_Pin,GPIO_PIN_RESET);
else HAL_GPIO_WritePin(DEMO_GPIO_Port,DEMO_Pin,GPIO_PIN_SET);
}
}
學過了今天的內容之后,相信大家對於這個函數實現的功能應該比較明白了,說白了就是通過GPIO輸出一個pwm波。
我們GPIO只能夠輸出高電平和低電平,即0和1。可是生活中很多東西並不是非黑即白的,它很復雜。單片機也是這樣。我們能輸出0,1,這很好,但是萬一要輸出0.8,0.2這樣的值呢?
為了實現這樣的輸出,pwm波算是一種途徑,具體實現的方法學長有詳細的講解,大概就是某個時間段內的“有效電平”,1s內我有0.8s輸出1,0.2s輸出0,那么這1s內我的有效電平就是0.8。大概可以這么理解。
扯遠了,回到作業內容,理解了duty_output這個函數,那么就只剩下while(1)中的語句了
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_9)==GPIO_PIN_SET&&!input_flag){input_flag=1;HAL_Delay(10);}//Hal_Delay(10)是為了避免按鍵消抖,這里判斷按鍵是否被按下
if(!input_flag) HAL_GPIO_WritePin(DEMO_GPIO_Port,DEMO_Pin,GPIO_PIN_SET);//如果按鍵沒被按下
else{//按鍵被按下
for(int i=0;i<900;i+=10) {duty_output(i);HAL_Delay(2);}
for(int i=900;i>0;i-=10) {duty_output(i);HAL_Delay(2);}}//呼吸燈
}
這邊其實還整了一個花活,就連接一個按鍵到PA5,通過讀取PA輸入電平來判斷按鍵是否被按下,若被按下切換為呼吸燈,如果一直保持不被按下的狀態,則是常亮。其實按鍵來控制還有更高明的方法,更靈活,功能也更加強大,就是第三節課要將到的外部中斷,有興趣的同學可以預習一下。
至於呼吸燈,第二節課應該是講過了,還有比較神奇的按鍵消抖,那就自行百度咯~
作業點評
大概有五分之一的同學能夠正確寫出“呼吸燈”或者“pwm”這樣的字眼,其實寫到這個份上應該算是回答正確,能夠寫出整體邏輯更好。(但是有的同學就寫上三個字“呼吸燈”這讓我有點手足無措,也不知道是不是真的搞懂了)
不過有的同學卻誤入歧途,講解了SystemClock_Config,MX_GPIO_Init這些cube幫我們配置好的函數的作用,我們上課的時候不是說了嘛,這么多的代碼在這個階段我們不用很關注,只需要知道一般在哪里寫就行,譬如你進我的項目先看看while(1),一看duty_output沒有見過,那就右擊選擇go to definition看看這到底是個什么玩意兒,再稍微理解一下就差不多了。
前幾天更新了一下cube,所以版本是最新的,大家估計因為版本低所以打不開,關系也不大,很多東西都在keil里,你不會升級cube,打開keil讀讀代碼也行。但是就有好些個同學就寫“打不開,沒看”,這就讓我們有點哭笑不得了。搞機器人本來就是“敢熱愛,你就來”的科創,這種敷衍潦草的態度我深不以為然。
總結
電控第一講到這里也就結束了
電控的入門比較艱難,可是一旦掌握了基礎,在不斷的實操中便能夠得到精進
日拱一卒無有盡,希望大家能在不斷的嘗試中成就自我!