上一章,我們介紹了 STM32F1 的 IO 口作為輸出的使用,這一章,我們將通過另外一個例
子講述 STM32F1 的 IO 口作為輸出的使用。在本章中,我們將利用一個 IO 口來控制板載的有
源蜂鳴器,實現蜂鳴器控制。通過本章的學習,你將進一步了解 STM32F1 的 IO 口作為輸出口
使用的方法。本章分為如下幾個小節:
7.1 蜂鳴器簡介
7.2 硬體設計
7.3 軟體設計
7.4 下載驗證
7.1 蜂鳴器簡介
蜂鳴器是一種一體化結構的電子訊響器,採用直流電壓供電,廣泛應用於計算機、印表機、
複印機、報警器、電子玩具、汽車電子設備、電話機、定時器等電子產品中作發聲器件。蜂鳴
器主要分為壓電式蜂鳴器和電磁式蜂鳴器兩種類型。
戰艦 STM32F103 板載的蜂鳴器是電磁式的有源蜂鳴器,如圖 7.1.1 所示:
這裡的有源不是指電源的「源」,而是指有沒有自帶震蕩電路,有源蜂鳴器自帶了震蕩電路,
一通電就會發聲;無源蜂鳴器則沒有自帶震蕩電路,必須外部提供 2~5Khz 左右的方波驅動,
才能發聲。
前面我們已經對 STM32F1 的 IO 做了簡單介紹,上一章,我們就是利用 STM32 的 IO 口直
接驅動 LED 的,本章的蜂鳴器,我們能否直接用 STM32 的 IO 口驅動呢?讓我們來分析下:
STM32F1 的單個 IO 最大可以提供 25mA 電流(來自數據手冊),而蜂鳴器的驅動電流是 30mA
左右,兩者十分相近,但是全盤考慮,STM32F1 整個晶片的電流,最大也就 150mA,如果用
IO 口直接驅動蜂鳴器,其他地方用電就得省著點了…所以,我們不用 STM32F1 的 IO 直接驅動
蜂鳴器,而是通過三極體擴流後再驅動蜂鳴器,這樣 STM32F1 的 IO 只需要提供不到 1mA 的
電流就足夠了。
IO 口使用雖然簡單,但是和外部電路的匹配設計,還是要十分講究的,考慮越多,設計就
越可靠,可能出現的問題也就越少。
本章將要實現的是控制 ALIENTEK 戰艦 STM32F103 上的蜂鳴器發出:「嘀」…「 嘀」…
的間隔聲,進一步熟悉 STM32F1 IO 口的使用。
7.2 硬體設計
本章需要用到的硬體有:
1)指示燈 DS0
2)蜂鳴器
DS0 在上一章已有介紹,而蜂鳴器在硬體上也是直接連接好了的,不需要經過任何設置,
直接編寫代碼就可以了。蜂鳴器的驅動信號連接在 STM32F1 的 PB8 上。如圖 7.2.1 所示:
圖中我們用到一個 NPN 三極體(S8050)來驅動蜂鳴器,R38 主要用於防止蜂鳴器的誤發
聲。當 PB.8 輸出高電平的時候,蜂鳴器將發聲,當 PB.8 輸出低電平的時候,蜂鳴器停止發聲。
7.3 軟體設計
這裡的代碼設計,我們還是在之前的基礎上繼續編寫,打開上一章的 TEST 工程,然後在
HARDWARE 文件夾下新建一個 BEEP 文件夾,用來存放與蜂鳴器相關的代碼。如圖 7.3.1 所示:
然後我們打開 USER 文件夾下的 test.uvprojx 工程,按 按鈕新建一個文件,然後保存在
HARDWARE→BEEP 文件夾下面,保存為 beep.c。在該文件中輸入如下代碼:
#include "beep.h"
//初始化 PB8 為輸出.並使能時鐘
//LED IO 初始化
void BEEP_Init(void)
{
GPIO_InitTypeDef GPIO_Initure;
__HAL_RCC_GPIOB_CLK_ENABLE(); //開啟 GPIOB 時鐘
GPIO_Initure.Pin=GPIO_PIN_8; //PB8
GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP; //推輓輸出
GPIO_Initure.Pull=GPIO_PULLUP; //上拉
GPIO_Initure.Speed=GPIO_SPEED_FREQ_HIGH; //高速
HAL_GPIO_Init(GPIOB,&GPIO_Initure);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_RESET);
//蜂鳴器對應引腳 GPIOB8 拉低,
}
這段代碼 僅包含 1 個函數:void BEEP_Init(void),該函數的作用就是使能 PORTB 的時鐘,
然後調用 GPIO_Init 函數,配置 PB8 為推輓輸出。IO 口的初始化跟上一講跑馬燈實驗非常類似,
這裡我們就不做過多講解。
保存 beep.c 代碼,然後我們按同樣的方法,新建一個 beep.h 文件,也保存在 BEEP 文件夾
下面。在 beep.h 中輸入如下代碼:
#ifndef __BEEP_H
#define __BEEP_H
#include "sys.h"
//LED 埠定義
#define BEEP PBout(8) // 蜂鳴器控制 IO
void BEEP_Init(void); //初始化
#endif
和上一章一樣,我們這裡還是通過位帶操作來實現某個 IO 口的輸出控制,BEEP 就直接代
表了 PB8 的輸出狀態。我們只需要令 BEEP=1,就可以讓蜂鳴器發聲。
將 beep.h 也保存。接著,我們把 beep.c 加入到 HARDWARE 這個組裡面,這一次我們通過
雙擊的方式來增加新的.c 文件,雙擊 HARDWARE,找到 beep.c,加入到 HARDWARE 裡面,
如圖 7.3.2 所示:
可以看到 HARDWARE 文件夾裡面多了一個 beep.c 的文件,然後還是用老辦法(頭文件包
含路徑,見 3.3.2 節或者上一講的圖 6.3.11)把 beep.h 頭文件所在的路徑加入到工程裡面。回到
主界面,在 main.c 裡面編寫如下代碼:
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "beep.h"
int main(void)
{
HAL_Init(); //初始化 HAL 庫
Stm32_Clock_Init(RCC_PLL_MUL9); //設置時鐘,72M
delay_init(72); //初始化延時函數
LED_Init(); //初始化 LED
BEEP_Init(); //初始化蜂鳴器
while(1)
{
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET);
//DS0 拉低,亮 等同 LED0=0;
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_SET);
//BEEP 引腳拉低, 等同 BEEP=0;
delay_ms(300); //延時 300ms
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_SET);
//DS0 拉高,滅 等同 LED0=1;
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_RESET);
//BEEP 引腳拉高, 等同 BEEP=1;
delay_ms(300); //延時 300ms
}
}
注意要將 BEEP 文件夾加入頭文件包含路徑,不能少,否則編譯的時候會報錯。這段代碼
就是通過庫函數 HAL_GPIO_WritePin 實現前面 7.1 節所闡述的功能,同時加入了 DS0(LED0)
的閃爍來提示程序運行(後面的代碼,我們基本都會加入這個),整個代碼比較簡單。 對於這
兩個函數的使用,在我們第六章跑馬燈實驗,我們已經做了非常詳細的講解,大家可以翻過去
仔細學習。
然後按 ,編譯工程,得到結果如圖 7.3.3 所示:
可以看到沒有錯誤,也沒有警告。接下來,大家就可以下載驗證了。如果有 STLINK,則
可以用 STLINK 進行在線調試(需要先下載代碼),單步查看代碼的運行,STM32F1 的在線調
試方法介紹,參見:3.4.2 節。
7.4 下載驗證
同樣,我們通過 flymcu 下載代碼,下載完代碼,可以看到 DS0 亮的時候蜂鳴器不
叫,而DS0 滅的時候,蜂鳴器叫(因為他們的有效信號相反)。間隔為 0.3 秒左右,
符合預期設計。
至此,我們的本章的學習就結束了。本章,作為 STM32F1 的入門第二個例子,進一
步介紹了 STM32F1 的 IO 作為輸出口的使用方法,同時鞏固了前面知識的學習。希
望大家在開發板上實際驗證一下,從而加深印象。