對于微控制器,LED 閃爍程序相當于“hello world”程序。在我們之前的教程中,我們學習了如何開始使用 STM8S103F3 開發(fā)板以及如何設置 IDE 和編譯器來對我們的 STM8S 控制器進行編程。我們還學習了如何使用標準外設庫,以及如何編譯代碼并將其上傳到我們的微控制器中。涵蓋了所有基礎知識,讓我們真正開始編寫代碼。在本教程中,我們將學習如何在 STM8S 控制器上執(zhí)行通用 GPIO 功能。該板已經(jīng)有一個連接到端口 B 的引腳 5 的板載 LED,我們將學習如何使該 LED 閃爍,并添加一個外部 LED 并使用按鈕對其進行控制。
準備好硬件
在我們深入研究程序之前,讓硬件連接準備好。如前所述,我們將在這里使用兩個 LED,一個是板載 LED,它會持續(xù)閃爍,另一個是外部 LED,可以通過按鈕進行切換。這個想法是在一個簡單的設置中學習所有的 GPIO 功能。板載 LED 已經(jīng)連接到 PB5(PORTB 的引腳 5),所以我剛剛將 LED 連接到 PA3,將按鈕連接到 PA2,如下圖所示。
但是,在我們控制的所有可用輸出引腳中,為什么我選擇 PA3 作為輸出,PA2 作為輸入?這些問題是有效的,我將在本文后面解釋。我為本教程的硬件設置如下所示。如您所見,我還將我的 ST-link 編程器連接到編程引腳,這不僅可以對我們的電路板進行編程,還可以用作電源。
了解 STM8S103F 上的 GPIO 引腳排列
現(xiàn)在回到問題,為什么 PA2 用于輸入,為什么 PA3 用于輸出?為了理解這一點,讓我們仔細看看微控制器的引腳排列,如下所示。
根據(jù)引腳圖,我們的微控制器上有四個端口,即端口 A、B、C 和 D,分別用 PA、PB、PC 和 PD 表示。每個 GPIO 引腳還具有一些其他特殊功能。例如,PB5(PORT B 的引腳 5)不僅可以用作 GPIO 引腳,還可以用作 I2C 通信的 SDA 引腳和定時器 1 的輸出引腳。因此,如果我們將此引腳用于連接 LED 等簡單的 GPIO 用途,那么我們將無法同時使用 I2C 和 LED。遺憾的是,板載 LED 連接到此引腳,所以我們在這里沒有太多選擇,而且在這個程序中,我們不會使用 I2C,所以問題不大。
STM8S103F GPIO 選擇的引腳說明和提示
說真的,使用 PA1 作為輸入引腳并沒有什么壞處,它只是工作引腳。但我特意提出這一點,是為了讓我有機會向您展示一些在新微控制器上選擇 GPIO 引腳時可能會陷入的常見陷阱。避免陷阱的最佳方法是閱讀STM8S103F3P6 數(shù)據(jù)表中提供的引腳詳細信息和引腳說明。數(shù)據(jù)表中提到的 STM8S103F3P6 微控制器引腳描述詳細信息如下圖所示。
我們微控制器上的輸入引腳可以是浮動或弱上拉,輸出引腳可以是開漏或推挽。已經(jīng)討論了開漏和推挽輸出引腳之間的區(qū)別,因此我們不會詳細介紹。簡單來說,開漏輸出引腳可以使輸出只有低不高,而推挽輸出引腳可以使輸出既高又高。
除了上表之外,您還可以注意到輸出引腳可以是快速輸出 (10 Mhz) 或慢速輸出 (2 MHz)。這決定了 GPIO 的速度,如果你想非常快速地在高低之間切換你的 GPIO 引腳,那么我們可以選擇快速輸出。
如上圖所示,我們控制器上的一些 GPIO 引腳支持真正的漏極開路 (T)和高灌電流 (HS) 。Open Drain 和 True Open Drain 之間的一個相當大的區(qū)別是連接到開漏的輸出不能被拉高超過微控制器的工作電壓 (Vdd),而真正的開漏輸出引腳可以被拉高到高于 Vdd。具有高吸收能力的引腳意味著它可以吸收更多電流。任何 GPIO HS 引腳的源電流和灌電流均為 20mA,而電源線可消耗高達 100mA。
仔細查看上圖,您會注意到幾乎所有 GPIO 引腳都是高灌電流 (HS) 類型,但 PB4 和 PB5 是真正的開漏型 (T)。這意味著這些引腳不能被拉高,即使引腳被拉高,它們也無法提供 3.3V。這就是為什么板載 LED 連接到 3.3V 并通過 PB5 接地,而不是直接從 GPIO 引腳為其供電。
有關詳細的引腳說明,請參閱數(shù)據(jù)表的第 28 頁。如上圖所示,PA1 自動配置為弱上拉,不推薦用作輸出引腳。無論如何,它可以與按鈕一起用作輸入引腳,但我決定使用 PA2 只是為了嘗試從程序中啟用上拉。這些只是一些基本的東西,當我們編寫更復雜的程序時它們會很有用?,F(xiàn)在,如果很多事情都從你的腦海中浮現(xiàn)出來也沒關系,我們將在其他教程中深入探討。
使用 SPL 對 STM8S 進行 GPIO 輸入和輸出編程
正如我們在第一個教程中討論的那樣,創(chuàng)建一個工作區(qū)和新項目。您可以添加所有頭文件和源文件,也可以僅添加 gpio、config 和 stm8s 文件。打開main.c文件并開始編寫程序。
確保您已包含如上圖所示的頭文件。打開main.c文件并啟動代碼。完整的 main.c 代碼可以在此頁面底部找到,您還可以從那里下載項目文件。代碼解釋如下,如果您對編碼部分感到困惑,也可以參考SPL 用戶手冊或本頁底部鏈接的視頻。
取消初始化所需端口
我們通過取消初始化所需端口來開始我們的程序。正如我們之前所討論的,每個 GPIO 引腳除了像普通的輸入和輸出一樣工作外,還有許多其他功能與其相關聯(lián)。如果這些引腳先前已用于其他應用程序,那么在我們使用它們之前應該將其取消初始化。這不是強制性的,但是,這是一個很好的做法。下面兩行代碼用于De-Initialize Port A和Port B。使用語法GPIO_DeInit (GPIOx)即可;并提及端口名稱代替 x。
GPIO_DeInit(GPIOA); //準備端口A工作
GPIO_DeInit(GPIOB); // 準備端口 B 工作
輸入輸出GPIO聲明
接下來,我們必須聲明哪些引腳將用作輸入,哪些引腳將用作輸出。在我們的例子中,引腳 PA2 將用作輸入,我們還將將該引腳聲明為內(nèi)部上拉,這樣我們就不必在外部使用一個。語法為GPIO_Init (GPIOx, GPIO_PIN_y, GPIO_PIN_MODE_z);。 其中 x 是端口名稱,y 是引腳編號,z 是 GPIO 引腳模式。
//聲明PA2為輸入上拉引腳
GPIO_Init (GPIOA, GPIO_PIN_2, GPIO_MODE_IN_PU_IT);
接下來,我們必須將引腳 PA3 和 PB5 聲明為輸出。同樣可以使用多種類型的輸出聲明,但我們將使用“GPIO_MODE_OUT_PP_LOW_SLOW”,這意味著我們將其聲明為低速推挽式輸出引腳。默認情況下,該值會很低。語法將是相同的。
GPIO_Init(GPIOA,GPIO_PIN_3,GPIO_MODE_OUT_PP_LOW_SLOW);
//聲明PB5為推挽輸出引腳
GPIO_Init(GPIOB、GPIO_PIN_5、GPIO_MODE_OUT_PP_LOW_SLOW);
SPL 用戶手冊中的以下快照提到了所有可能的 GPIO 模式 (z)。
無限while循環(huán)
在引腳聲明之后,我們需要創(chuàng)建一個無限循環(huán),在其中我們將永遠閃爍 LED 并監(jiān)控按鈕的狀態(tài)以切換 LED。無限循環(huán)可以使用while(1)或 for (;;)創(chuàng)建。這里我使用了while (1)。
而 (1)
{
}
檢查輸入引腳的狀態(tài)
我們必須檢查輸入引腳的狀態(tài),這樣做的語法是GPIO_ReadInputPin(GPIOx, GPIO_PIN_y); 其中 x 是端口名稱,y 是引腳號。如果引腳為高電平,我們將得到“1”,如果引腳為低電平,我們將得到“0”。我們已經(jīng)習慣在 if 循環(huán)中檢查引腳是高電平還是低電平。
if (GPIO_ReadInputPin(GPIOA, GPIO_PIN_2)) //如果按鈕被按下
使 GPIO 引腳為高電平或低電平
要使 GPIO 引腳高或低,我們可以使用GPIO_WriteHigh(GPIOx,GPIO_PIN_y); 和GPIO_WriteLow(GPIOx,GPIO_PIN_y); 分別。在這里,我們使 LED 在按鈕被按下時打開,如果按鈕未被按下則關閉。
if (GPIO_ReadInputPin(GPIOA, GPIO_PIN_2)) //如果按鈕被按下
GPIO_WriteLow(GPIOA,GPIO_PIN_3); //帶領
別的
GPIO_WriteHigh(GPIOA,GPIO_PIN_3); //LED關閉
切換 GPIO 引腳
要切換 GPIO 引腳,我們有GPIO_WriteReverse(GPIOx,GPIO_PIN_y); 調(diào)用此函數(shù)將改變輸出引腳的狀態(tài)。該引腳為高電平時,變?yōu)榈碗娖?,為低電平時,變?yōu)楦唠娖健N覀冋谑褂么斯δ軄黹W爍 PB5 上的板載 LED。
GPIO_WriteReverse(GPIOB,GPIO_PIN_5);
延遲功能
與 Arduino 不同的是,cosmic 編譯器沒有預定義的延遲函數(shù)。所以我們必須自己創(chuàng)造一個。我的延遲函數(shù)如下所示。延遲的值將在變量 ms 中接收,我們將使用兩個 for 循環(huán)來保持或程序執(zhí)行。就像_asm(“nop”) 是一個匯編指令,它代表無操作。這意味著控制器將在不執(zhí)行任何操作的情況下循環(huán)進入 for 循環(huán),從而產(chǎn)生延遲。
void delay (int ms) //函數(shù)定義
{
整數(shù) i =0 ;
詮釋 j = 0;
對于 (i=0; i《=ms; i++)
{
for (j=0; j《120; j++) // Nop = Dark/4
_asm(“nop”); //執(zhí)行無操作 //匯編代碼
}
}
上傳和測試程序
現(xiàn)在我們的程序已經(jīng)準備好了,我們可以上傳它并測試它。上傳后,我的硬件按預期工作。板載紅色 LED 每 500 毫秒閃爍一次,每次按下開關時外部綠色 LED 都會亮起。
/* MAIN.C 文件
*
* 版權所有 (c) 2002-2005 STMicroelectronics
*/
#define Green_LED GPIOA,GPIO_PIN_3
#包括“STM8S.h”
void delay (int ms) //函數(shù)定義
{
整數(shù) i =0 ;
詮釋 j = 0;
對于 (i=0; i<=ms; i++)
{
for (j=0; j<120; j++) // Nop = Dark/4
_asm("nop"); //執(zhí)行無操作 //匯編代碼
}
}
主要的()
{
GPIO_DeInit(GPIOA); //準備端口A工作
GPIO_DeInit(GPIOB); // 準備端口 B 工作
//聲明PA2為輸入上拉引腳
GPIO_Init (GPIOA, GPIO_PIN_2, GPIO_MODE_IN_PU_IT);
//聲明PA3為推挽輸出引腳
GPIO_Init (Green_LED, GPIO_MODE_OUT_PP_LOW_SLOW);
//聲明PB5為推挽輸出引腳
GPIO_Init(GPIOB、GPIO_PIN_5、GPIO_MODE_OUT_PP_LOW_SLOW);
而 (1)
{
if (GPIO_ReadInputPin(GPIOA, GPIO_PIN_2)) //如果按鈕被按下
GPIO_WriteLow(Green_LED);//帶領
別的
GPIO_WriteHigh(綠色_LED);//LED關閉
GPIO_WriteReverse(GPIOB,GPIO_PIN_5);
延遲(100);
}
}
-
控制器
+關注
關注
112文章
16111瀏覽量
177083 -
GPIO
+關注
關注
16文章
1189瀏覽量
51839 -
STM8S
+關注
關注
16文章
149瀏覽量
31336 -
LED閃爍
+關注
關注
0文章
29瀏覽量
9799
發(fā)布評論請先 登錄
相關推薦
評論