1.stm32之LED燈控制

接觸嵌入式半年以來學(xué)習(xí)地非常零碎,沒有一個(gè)系統(tǒng)的知識(shí)體系,因此決定進(jìn)行一個(gè)系統(tǒng)的學(xué)習(xí)并做記錄,如果有錯(cuò)誤希望各位指出,不勝感激。
我使用的單片機(jī)系統(tǒng)的芯片為STM32f103zet6,這是一款144引腳的芯片,集成了STM32系列芯片的較多功能,適合用于學(xué)習(xí)。

嵌入式的知識(shí)結(jié)構(gòu)

1.計(jì)算機(jī)硬件基礎(chǔ)

編程語言
計(jì)算機(jī)組成原理
數(shù)據(jù)庫

2.系統(tǒng)硬件層

數(shù)/模電路
嵌入式平臺(tái):ARM、DSP、FPGA
原理圖及PCB設(shè)計(jì)

3.硬件抽象層

通用設(shè)備接口及協(xié)議:USB、TCP/IP、SPI
設(shè)備相關(guān):信息監(jiān)測、電機(jī)控制

4.系統(tǒng)軟件層

文件系統(tǒng)
GUI
操作系統(tǒng)
應(yīng)用程序

新建工程

1.新建工程文件夾

工程文件下的子文件夾.png

內(nèi)部包含以下子文件夾:
Doc:內(nèi)部包含程序說明文檔 read me
Libraries:內(nèi)部包含 CMSIS、FWLib 兩個(gè)文件夾,內(nèi)部為庫文件,可從其他項(xiàng)目中拷貝。
Listing:建立工程時(shí)不用存放任何文件。
Output:編譯工程時(shí)在這里生成USB燒寫的 .hex 文件。
Project:放置新建工程時(shí)產(chǎn)生的工程文件。
USER:包含 main.c、stm32f10x_conf.h、stm32f10x_it.c、stm32f10x_it.h 四個(gè)文件,可從其他項(xiàng)目中拷貝。

2.在MDK中新建項(xiàng)目

新建項(xiàng)目時(shí)需要選擇芯片,選擇stm32f103ze系列,之后直接建立工程。
之后在Manage Project Items中添加 STARTUP、CMSIS、FWLib 以及 USER 這四個(gè)Group。
STARTUP這個(gè)Group中添加 CMSIS 中 startup 文件中的某一個(gè),這個(gè)是根據(jù)芯片決定的,我在項(xiàng)目中添加的是 startup_stm32f10x_hd.s
CMSIS中添加除了 startup 的5個(gè)文件。
FWLib中添加FWLib文件夾中的src文件夾中的所有內(nèi)容。
USER中添加對(duì)應(yīng)文件夾下的內(nèi)容。

keil內(nèi)工程視圖.png

3.項(xiàng)目配置

打開 options for target...串口

1.Target配置
將xtal(MHz)設(shè)置為8.0


Target配置.png

2.Output配置
在 create hex file 前打鉤。
設(shè)置Output的文件路徑,路徑為工程文件夾下的Output文件夾。


Output配置.png

3.Listing配置
配置文件路徑為Listing文件夾。

4.C/C++配置
添加USE_STDPERIPH_DRIVER, STM32F10X_HD這兩句宏定義。
為 Include Paths 添加路徑,具體如下圖所示。


C/C++配置.png

在STM32F103中:
STM32F10X_LD 對(duì)應(yīng)于 LowDensity ,即小容量的STM32F103芯片。
STM32F10X_MD 對(duì)應(yīng)于 MediumDensity ,即中等容量的STM32F103芯片。
STM32F10X_HD 對(duì)應(yīng)于 HighDensity ,即大容量的STM32F103芯片。
這次我所使用的stm32f103zet6就是大容量芯片。

5.Debug及Utilities配置
因?yàn)槲沂褂玫氖荱SB下載程序,因此選擇ULink調(diào)試。


Debug配置.png

LED燈的控制

1.目的

使單片機(jī)電路板的LED燈形成一個(gè)流水燈。

2.工程配置

為了操作LED燈,我們需要添加自己的庫函數(shù)以便進(jìn)行控制
在項(xiàng)目的user文件夾中,新建一個(gè)LED文件夾和一個(gè)INC文件夾。
LED文件夾中用于存放led.c,INC文件夾存放led.h。
以后每新建一個(gè).c文件都應(yīng)該建立一個(gè)專門的文件夾來存放,而.c文件對(duì)應(yīng)的.h文件則都存放于INC文件夾中以便指定路徑。因此需要在Options for Target...中的C/C++中添加一個(gè)這樣的路徑:..\USER\INC


添加用戶自定義庫文件路徑.png

3.程序代碼

led.h源代碼:
//首先進(jìn)行防衛(wèi)聲明
#ifndef __LED_H
#define __LED_H

#include "stm32f10x.h"

#define ON  0
#define OFF 1

/* 定義帶參宏,使用方法類似C++中的內(nèi)聯(lián)函數(shù) */
/* 本次使用的單片板有三個(gè)LED燈,其中一個(gè)是電源燈。
另外兩個(gè)才是給用戶使用的,因此定義兩個(gè)燈開關(guān)的宏。 */
#define LED2(a) if(a) GPIO_SetBits( GPIOE, GPIO_Pin_5 ); else GPIO_ResetBits( GPIOE, GPIO_Pin_5 )
#define LED3(a) if(a) GPIO_SetBits( GPIOB, GPIO_Pin_5 ); else GPIO_ResetBits( GPIOB, GPIO_Pin_5 )

void LED_Init(void);

#endif

led.c源代碼:
#include "stm32f10x.h"
#include "led.h"

//LED初始化函數(shù)
void LED_Init(void)
{
    
    /* 定義一個(gè)GPIO_InitTypeDef類型的結(jié)構(gòu)體 */
    GPIO_InitTypeDef GPIO_InitStructure;
    
    /* 打開GPIOB和GPIOE的外設(shè)時(shí)鐘 */
    RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE );
    
    /* 選擇要控制的GPIOB引腳;設(shè)置為推挽輸出;最大速率設(shè)置為50MHz;初始化GPIOB */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init( GPIOB, &GPIO_InitStructure );
    
    /* 選擇要控制的GPIOE引腳;設(shè)置為推挽輸出;最大速率設(shè)置為50MHz;初始化GPIOE */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init( GPIOE, &GPIO_InitStructure );
    
    /* 關(guān)閉所有LED燈 */
    GPIO_SetBits( GPIOB, GPIO_Pin_5 );
    GPIO_SetBits( GPIOE, GPIO_Pin_5 );
}
led.c解釋:

GPIO_InitTypeDef結(jié)構(gòu)體在庫函數(shù)里的定義如下。(可以選中它再按F12進(jìn)入庫函數(shù)查看。)

typedef struct
{
  uint16_t GPIO_Pin;             /*!< Specifies the GPIO pins to be configured.
                                      This parameter can be any value of @ref GPIO_pins_define */

  GPIOSpeed_TypeDef GPIO_Speed;  /*!< Specifies the speed for the selected pins.
                                      This parameter can be a value of @ref GPIOSpeed_TypeDef */

  GPIOMode_TypeDef GPIO_Mode;    /*!< Specifies the operating mode for the selected pins.
                                      This parameter can be a value of @ref GPIOMode_TypeDef */
}GPIO_InitTypeDef;

也就是說,要初始化一個(gè)GPIO口,需要指明它的引腳,速率以及輸出方式。

首先打開它的外設(shè)時(shí)鐘,這里涉及到stm32的時(shí)鐘頻率??梢栽趕tm32f103的用戶手冊中查找時(shí)鐘樹,這個(gè)整體比較復(fù)雜,以后再細(xì)談,這里選擇APB2即可。

之后我們再根據(jù)電路原理圖打開LED燈對(duì)應(yīng)的引腳,如圖為我所使用的板子的LED模塊的原理圖。因此打開PB5和PE5引腳。這個(gè)電路很簡單,只要我們對(duì)PB5和PE5進(jìn)行高低電平的控制就能改變LED燈的開關(guān)狀態(tài)。


LED模塊原理圖

最后我們再通過結(jié)構(gòu)體設(shè)置引腳的速率以及輸出方式。

主函數(shù)main.c
#include "stm32f10x.h"
#include "led.h"

//一個(gè)不精確的延時(shí)函數(shù),通過循環(huán)來延時(shí)
void Delay( __IO u32 nCount )
{
    for( ; nCount != 0; nCount-- );
}

//這里實(shí)現(xiàn)了兩個(gè)LED燈的閃爍,如果有四五個(gè)就可以實(shí)現(xiàn)流水燈了
int main(void)
{
    LED_Init();
    
    while(1)
    {
        LED2( ON );
        Delay(0x0FFFFF);
        LED2( OFF );
        
        LED3( ON );
        Delay(0x0FFFFF);
        LED3( OFF );
    }
    
}

關(guān)于LED燈的操作基本就是這樣,很多涉及到GPIO口的程序都是類似的,比如蜂鳴器
和一些傳感器。之后會(huì)介紹蜂鳴器的開關(guān)代碼。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容