本文首發於個人博客huanghaozi.cn,原連接git
最近在研究STM32,看了一段洋桃電子的教學視頻感受還不錯,就買了開發板回來折騰。可是在看視頻剛剛看到代碼的時候我就產生了大量的疑惑,由於視頻裏並無一開始就上來寫代碼,而是對已經寫好的代碼進行講解。github
他們寫好的代碼裏已經作了不少封裝抽象,好比sys.h,led.h都不是官方固件庫裏有的,其中有大量的宏定義,我認爲這增長了學習的難度,由於宏是你本身定義的,方便本身用的,給別人用還須要必定的學習記憶,對本質代碼的理解很不直觀。編程
所以我又看了其餘廠商如正點原子、野火的一些視頻,基本都是一個樣。還在網上閱讀了各類使用寄存器操做的所謂「最簡」代碼。最後我閱讀了《STM32固件庫用戶手冊》,本身實現了點LED燈的最簡代碼。ide
對於工程的構建你們基本上都是同樣的,固件庫壓縮包裏的Library(庫)文件夾纔是本體。下面列出它的文件目錄樹:函數
├─CMSIS
│ ├─CM3
│ │ ├─//CoreSupport -- CMSIS
│ │ └─DeviceSupport
│ │ └─ST
│ │ └─//STM32F10x -- CMSIS
│ │ └─startup
│ │ ├─//arm -- STARTUP
│ │ ├─gcc_ride7
│ │ ├─iar
│ │ └─TrueSTUDIO
│ └─Documentation
└─//STM32F10x_StdPeriph_Driver -- LIB
├─inc
└─src
複製代碼
其中標註//的目錄下含有**.h、.c、.s後綴的C/彙編源碼文件,通常須要將其單獨複製出來**,創建一個工程模板方便使用。工具
單獨複製出來有三個文件夾:CMSIS、LIB、STARTUP,實際上還需創建一個放咱們本身代碼的文件夾——User,ST公司對此提供了一個工程模板,並不在Library中,而是在固件庫壓縮包的Project-->STM32F10x_StdPeriph_Template文件夾中。咱們僅需複製其中的main.c、stm32f10x_it.c、stm32f10x_it.h、stm32f10x_conf.h便可。學習
以後咱們在keil5裏新建工程,導入這幾個文件夾便可,以下圖所示: spa
導入文件後須要作一些編譯設置,點擊工具欄上的魔術棒按鈕,以下圖設置: 3d
Define編輯框內設置:STM32F10X_MD,USE_STDPERIPH_DRIVER
Include Paths編輯框內設置:.\CMSIS;.\LIB\inc;.\USER
code
輸出設置,以下圖:
首先須要清空main.c,加入以下最簡的代碼,編譯構建一遍看是否出錯,若出錯需檢查上一步驟:
#include "stm32f10x.h"
int main() {
while(1)
{
}
}
複製代碼
若無錯誤就能夠開始對照**《STM32固件庫用戶手冊》**進行編程啦。
個人開發板上的LED燈電路比較簡單,以下圖所示:
LED1接在PB0上,LED2接在PB1上,PB其實是GPIO口(標準IO口)。
在固件庫的用戶手冊中提到,操做引腳必須先對其進行初始化,在手冊中第2.3節提到了具體的代碼編寫方法:
我總結了一下以上內容大概是:假設外設接口叫PPP,首先要聲明一個PPP_InitTypeDef類型的名爲PPP_InitStructure結構體,而後對結構體的參數進行設置(不一樣外設接口參數不同),最後使用PPP_Init函數初始化外設。此外,須要記住的是,在初始化外設以前還須要初始化時鐘,可以使用RCC_AHBPeriphClockCmd、RCC_APB2PeriphClockCmd、RCC_APB1PeriphClockCmd函數操做。
而個人LED燈接在GPIO口上,天然須要查閱初始化GPIO的一些函數。翻一翻用戶手冊的目錄,我直接找到了目錄中的GPIO_Init函數,其中對其參數介紹很是詳細,讀者可自行查閱。
由此即可以寫出初始化的代碼了:
void LED_Init() {
//把GPIOB的時鐘初始化了
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
//設定好GPIO初始化的參數
GPIO_InitTypeDef LED_InitStructure;
LED_InitStructure.GPIO_Pin = GPIO_Pin_0; //第0腳
LED_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //50MHz最大速度
LED_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推輓輸出模式
//執行初始化
GPIO_Init(GPIOB, &LED_InitStructure); //GPIOB組引腳
}
複製代碼
編寫點亮LED的代碼以前,須要在main函數中執行咱們上面寫好的初始化代碼。
//在while死循環前加入
LED_Init();
複製代碼
下一步即是點亮LED了,由個人電路可知,要給引腳輸出高電平才能點亮LED。再次查閱手冊,發現GPIO_SetBits函數能夠很好地實現這個功能。
因而在main函數中加入以下代碼:
//在while循環中加入
GPIO_SetBits(GPIOB, GPIO_Pin_0);
複製代碼
構建,燒錄運行,是否是看到效果啦?!整體代碼以下,是否是很簡單:
#include "stm32f10x.h"
void LED_Init() {
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitTypeDef LED_InitStructure;
LED_InitStructure.GPIO_Pin = GPIO_Pin_0;
LED_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
LED_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOB, &LED_InitStructure);
}
int main() {
LED_Init();
while(1)
{
GPIO_SetBits(GPIOB, GPIO_Pin_0);
}
}
複製代碼
本篇文章由一文多發平臺ArtiPub自動發佈