這次是針對NUCLEO_L552ZE_Q開發板的第三次評測貼,上次的帖子介紹了如何在Windows平臺上搭建開發環境,既然環境已經準備好了,接下來我們就要開始動手寫程序測試了(寫程序是不會寫的,這輩子都不會寫程序的,因為有STM32CubeMX),是的,STM32CubeMX把基本的程序框架都寫好了,對于基本的測試,只需敲幾行字母就行了,真是懶人的必備,哈哈哈。
廢話不多說,相信許多玩過單片機的朋友都知道,拿到一款單片機,寫程序的第一步無非就是GPIO口的輸出輸入功能,輸出功能就是點亮一盞LED,輸入功能就是按鍵掃描,那接下來我們就遵守這一不成文的規定,先從GPIO口的輸出輸入功能入手。
評測內容
1、新建MDK-ARM工程,使用STM32CubeMX新建一個工程;
2、GPIO口電平輸出功能,控制NUCLEO_L552ZE_Q開發板上的紅色LED燈閃爍;
3、GPIO口電平輸入功能,使用NUCLEO_L552ZE_Q開發板上的USER BUTTON按鍵控制紅色LED燈閃爍的頻率大小。
新建MDK-ARM工程
在開始之前,我們還需要了解一些如何使用STM32CubeMX新建一個工程的知識。
01 新建目錄
在電腦的磁盤上新建一個文件夾,這個文件夾并不是工程目錄,至于工程目錄是哪個,稍后會說。注意,文件件的名稱,上級名稱,上上級名稱等,就是整個路徑,一定不能含有中文!半個中文都不能有!不信你可以試試。為了演示,我就隨便建個名為“Demo”的文件夾,如下圖。
02 新建STM32CubeMX工程
1、打開STM32CubeMX,鼠標左鍵單擊“New Project”中的“ACCESS TO MCU SELECTOR”,
2、在彈出的“New Project from a MCU/MPU”窗口中的左側的搜索框中輸入你需要的單片機型號,我這里輸入“STM32L552ZE”,
3、然后在左下角的“MCUs/MPUs List”中選擇所需要的單片機型號,我這里選擇STM32L552ZET6Q,雙擊單片機型號,
4、彈出窗口問你是否使用TrustZone,我選擇No,然后就創建了一個STM32CubeMX工程。
03 配置STM32CubeMX工程
1、設置工程屬性,點擊STM32CubeMX工程窗口上方的“Project Manager”選項,在最左邊選項切換到“Project”,
2、在“Project Location”中選擇在第一步的時候創建的文件夾,
3、在“Project Name”中填入工程名(不能是中文),填入的工程名就是這個工程的根目錄,路徑如藍色框所示,
4、在“Toolchain / IDE”中選擇“MDK-ARM”,其他保持默認即可,具體如下圖所示,
5、最左邊選項切換到“Code Generator”,在右邊的“STM32Cube MCU packages an embedded software packs”中有三個選項,意思分別為拷貝全部的庫文件到工程目錄中、僅拷貝需要的庫文件到工程目錄中、僅在工程文件中引用需要的庫文件(庫文件放在STM32CubeMX的安裝目錄中),我選擇第二項,
6、設置時鐘屬性,點擊STM32CubeMX工程窗口上方的“Project Manager”選項,在“HCLK(MHz)”中輸入需要的時鐘頻率,按回車鍵,在彈出的提示中選擇Ok便可,我輸入STM32L552ZET6Q的最大時鐘頻率:110MHz,其他的保持默認:內部高速時鐘16MHz和內部低速時鐘32KHz,
7、配置點亮LED燈的GPIO,NUCLEO_L552ZE_Q開發板上共有三盞LED燈,分別為紅綠藍三色,根據原理圖提供的信息,紅綠藍三盞等分別接在了單片機的PA9、PC7和PB7引腳,我選擇了最經典的紅色LED,在“Pinout & Configuration”中使用鼠標左鍵點擊單片機模型上的PA9引腳(右側從上往下數第8個引腳),在小窗口中選擇“GPIO_Output”,至此,STM32CubeMX工程就配置好了。
04 保存STM32CubeMX工程
點擊上方菜單中的“File”,選擇“Save Project”即可。
05 生成MDK-ARM工程
鼠標左鍵單擊右上方的“GENERATE CODE”,軟件便可根據之前的配置自動生成一個代碼工程,如果在第一步中創建的目錄中有中文,在這一部生成代碼工程的時候就會出現錯誤提示,導致工程創建失敗,因此需要特別注意。
GPIO口電平輸出功能:點亮一盞LED燈 01 了解一下工程的目錄結構
irvers:存放STM32的固件庫以及ARM公司提供的CMSIS庫,通常情況下不需要修改里面的文件內容;
inc:存放用戶編寫的.h文件,文件內容可修改;
MDK-ARM:存放MDK的工程文件,以及STM32的啟動文件,文件內容通常情況下不需要修改;
src:存放用戶編寫的.c文件,文件內容可修改。
02
D在MDK-ARM文件夾內,雙擊打開.uvprojx后綴的工程文件,不需要改動,直接鏈接一遍,看是否有問題,結果0錯誤、0警告。
03
打開main.c文件,找到主函數main(),在主函數的while循環內添加如下代碼,意思為每隔500ms對PA9引腳進行電平取反操作,讓紅色LED燈閃爍。
04 配置目標屬性
1、電機窗口上方的魔術棒,彈出配置窗口;
2、切換到“Debug”選項;
3、選擇調試器,我使用ST-Link Debugger;
4、電機左側的“Settings”
5、在彈出的窗口中切換到“Flash Download”選項,勾選“Reset and Run”,使得將程序燒錄到單片機后就會自動復位并運行程序。
6、點擊“確定”、“OK”確認修改后,再次編譯鏈接工程,0錯誤0警告。
05 燒錄程序
1、使用一根Micro USB數據線鏈接電腦與開發板上的ST-Link USB-A口,如果還沒安裝驅動,可查看我上一期的帖子,末尾有附件,如果開發板上的LD4亮紅色,LD6亮綠色,說明連接正常。
2、電機MDK軟件左上角的下載按鈕,開始將程序下載到單片機上運行。
3、觀察運行情況,紅色LED燈開始閃爍,說明GPIO口能夠正常輸出高低電平。
GPIO口電平輸入功能:按鍵掃描 01 重新生成MDK-ARM工程
將MDK-ARM工程關閉,根據原理圖知道開發板上的USER按鍵連接在單片機的PC13引腳,回到STM32CubeMX工程,在“Pinout & Configuration”中使用鼠標左鍵點擊單片機模型上的PC13引腳(芯片模型的左側從上往下數第7個引腳),在小窗口中選擇“GPIO_Input”,保存STM32CubeMX工程并且點擊“GENERATE CODE”重新生成代碼。
02 實現按鍵掃描代碼
1、打開MDK-ARM工程,在main.c源文件的主函數實現代碼的開頭添加如下代碼,聲明兩個局部變量。
2、在主函數的while循環內添加如下代碼,實現按鍵掃描和LED閃爍功能。
3、修改完之后,編譯鏈接一遍代碼,將代碼燒錄到開發板上,用手按開發板左下方的USER按鍵,觀察紅色LED的閃爍頻率變化情況,實際情況如下:
仿位帶操作:實現與51單片機一樣的IO口操作方法
使用過正點原子Cortex_M3或者Cortex_M4系列單片機開發板的朋友都應該接觸過位帶操作功能,在Cortex_M3權威指南(中文)中的第5.5節有如下介紹
在CM3中,有兩個區中實現了位帶。其中一個是SRAM區的最低1MB范圍,第二個則是片內外設區的最低1MB范圍。這兩個位帶中的地址除了可以像普通的RAM一樣使用外,它們還都有自己的“位帶別名區”,位帶別名區把每個比特膨脹成一個32位的字。當你通過位帶別名區訪問這些字時,就可以達到訪問原始比特的目的。
文中所述的位帶區與位帶別名區有如下對應關系
STM32單片機的GPIO口地址就在片內外設區的最低1MB范圍內,意思就是能夠通過位帶別名區中的每一個地址,操作到對應的片內外設區的外設寄存器中的一個bit,往位帶別名區中的地址寫1,則對應的片內外設區的外設寄存器中的相應位就會置1,讀取位帶別名區中的地址的值,就會返回對應的片內外設區的外設寄存器中的相應位的值,GPIO口的每一個Pin的電平就是由ODR寄存器中的每一個位來控制,以及通過IDR寄存器中的一個位來獲取一個Pin的電平。但是,我查找過Cortex_M33的手冊,并沒有發現這個位帶別名區,也就是Cortex_M33沒有位帶操作功能,但我可以通過自定義一個位域結構體來實現類似的操作,實現代碼如下:
typedef struct
{
uint16_t OD0 : 1;
uint16_t OD1 : 1;
uint16_t OD2 : 1;
uint16_t OD3 : 1;
uint16_t OD4 : 1;
uint16_t OD5 : 1;
uint16_t OD6 : 1;
uint16_t OD7 : 1;
uint16_t OD8 : 1;
uint16_t OD9 : 1;
uint16_t OD10 : 1;
uint16_t OD11 : 1;
uint16_t OD12 : 1;
uint16_t OD13 : 1;
uint16_t OD14 : 1;
uint16_t OD15 : 1;
} ODR_TypeDef;
#define PAin(n) ( ( GPIOA->IDR&(1 << (n)) )>>n )
#define PBin(n) ( ( GPIOB->IDR&(1 << (n)) )>>n )
#define PCin(n) ( ( GPIOC->IDR&(1 << (n)) )>>n )
#define PDin(n) ( ( GPIOD->IDR&(1 << (n)) )>>n )
#define PEin(n) ( ( GPIOE->IDR&(1 << (n)) )>>n )
#define PFin(n) ( ( GPIOF->IDR&(1 << (n)) )>>n )
#define PGin(n) ( ( GPIOG->IDR&(1 << (n)) )>>n )
#define PAout(n) ( ((ODR_TypeDef *)(&(GPIOA->ODR)))->OD##n )
#define PBout(n) ( ((ODR_TypeDef *)(&(GPIOB->ODR)))->OD##n )
#define PCout(n) ( ((ODR_TypeDef *)(&(GPIOC->ODR)))->OD##n )
#define PDout(n) ( ((ODR_TypeDef *)(&(GPIOD->ODR)))->OD##n )
#define PEout(n) ( ((ODR_TypeDef *)(&(GPIOE->ODR)))->OD##n )
#define PFout(n) ( ((ODR_TypeDef *)(&(GPIOF->ODR)))->OD##n )
#define PGout(n) ( ((ODR_TypeDef *)(&(GPIOG->ODR)))->OD##n )
可將此代碼封裝到一個頭文件內供調用,使用方法同正點原子的源碼一樣。
總結
可見,在STM32CubeMX的幫助下,實現一些基礎的功能代碼還是比較方便的,加之有HAL固件庫的支持,無論單片機的底層寄存器如何變化,HAL固件庫都已經統一封裝成一致的函數名,使用起來也非常方便。本次測試的GPIO口操作,主要使用到了兩個函數:HAL_GPIO_TogglePin和HAL_GPIO_ReadPin,兩個函數的實現也比較簡單,都是直接操作寄存器:
本次我們介紹了GPIO口的使用,由于篇幅已經太多了,花了一天時間才寫完,等下次有空再介紹其他一些基本的功能。
-
led
+關注
關注
242文章
23765瀏覽量
671722 -
STM32
+關注
關注
2290文章
11018瀏覽量
362939
原文標題:分享 | 人生中的首塊STM32L552開發板——GPIO
文章出處:【微信號:STM32_STM8_MCU,微信公眾號:STM32單片機】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
基于小凌派RK2206開發板:OpenHarmony如何使用IoT接口控制GPIO中斷

基于小凌派RK2206開發板:OpenHarmony如何使用IoT接口控制GPIO外設

免費丨米爾 STM32MP257開發板有獎試用

評論