個人學習筆記:蜂鳴器實驗
技術標籤:stm32
個人學習筆記:蜂鳴器實驗
蜂鳴器實現原理和led點亮大同小異,所以就不重新編寫了。
一.所使用的函式
1.時鐘使能函式
RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState)
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); //使能GPIOB的時鐘
2.引腳初始化函式
GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
GPIO_Init (GPIOB,&GPIO_InitStructure);
3.對IO口置1
GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
GPIO_SetBits(GPIOB,GPIO_Pin_8);
4.對IO口置0
GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
GPIO_ResetBits(GPIOB,GPIO_Pin_8);
二.硬體部分
蜂鳴器有兩種有源蜂鳴器和無源蜂鳴器。有源和無源這裡的“源”不是指電源,而是指震盪源。也就是說,有源蜂鳴器內部帶震盪源,所以只要一通電就會叫。而無源內部不帶震盪源,所以如果用直流訊號無法令其鳴叫。必須用2K~5K的方波去驅動它。
三.程式碼編寫過程整理
1.編寫beep.h標頭檔案
#ifndef __BEEP_H
#define __BEEP_H
void beep_Iint(void); //函式宣告,在.c的檔案中定義
#endif //避免標頭檔案內容被重複定義
2.編寫beep.c檔案
在該檔案中引用了beep.h的標頭檔案,先聲明瞭 void beep_Iint(void) 這個函式,然後對該函式進行定義
#include "beep.h"
#include "stm32f10x.h"
void beep_Iint(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); //使能GPIOB的時鐘
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; //設定推輓輸出
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8; //蜂鳴器對應的引腳為PB8
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //輸出速度為50MHz
GPIO_Init(GPIOB,&GPIO_InitStructure); //GPIOB初始化
GPIO_SetBits(GPIOB,GPIO_Pin_8); //對IO口置1
}
在這部分編寫程式碼的時候,首先運用到的是rcc標頭檔案中的使能時鐘的函式,基本上所有的程式在開始都需要使能時鐘,然後就是對時鐘進行初始化,在go to definition之後,我們發現它的入口第二個條件是一個結構體,我們就定義了一個指標GPIO_InitStructure指向GPIO_InitTypeDef ,GPIO_InitTypeDef是一個結構體變數,該變數在Stm32f10x_gpio.h標頭檔案中被定義,原型如下:
typedef struct
{
uint16_t GPIO_Pin; //GPIO_pins_define
GPIOSpeed_TypeDef GPIO_Speed; //GPIOSpeed_TypeDef
GPIOMode_TypeDef GPIO_Mode; //GPIOMode_TypeDef
}GPIO_InitTypeDef;
所以我們分別要對這三個結構體成員進行賦值:
首先,第一個變數為GPIO_Pin是一個16為的無符號數(uint),該數只有16位,每一位代表一個引腳,如果想要要配置某一個埠的某一個引腳只需要把相應的位置1就可以了。在STM32的韌體庫中有如下引腳號定義:
#define GPIO_Pin_0 ((uint16_t)0x0001) /*!< Pin 0 selected */
#define GPIO_Pin_1 ((uint16_t)0x0002) /*!< Pin 1 selected */
#define GPIO_Pin_2 ((uint16_t)0x0004) /*!< Pin 2 selected */
#define GPIO_Pin_3 ((uint16_t)0x0008) /*!< Pin 3 selected */
#define GPIO_Pin_4 ((uint16_t)0x0010) /*!< Pin 4 selected */
#define GPIO_Pin_5 ((uint16_t)0x0020) /*!< Pin 5 selected */
#define GPIO_Pin_6 ((uint16_t)0x0040) /*!< Pin 6 selected */
#define GPIO_Pin_7 ((uint16_t)0x0080) /*!< Pin 7 selected */
#define GPIO_Pin_8 ((uint16_t)0x0100) /*!< Pin 8 selected */
#define GPIO_Pin_9 ((uint16_t)0x0200) /*!< Pin 9 selected */
#define GPIO_Pin_10 ((uint16_t)0x0400) /*!< Pin 10 selected */
#define GPIO_Pin_11 ((uint16_t)0x0800) /*!< Pin 11 selected */
#define GPIO_Pin_12 ((uint16_t)0x1000) /*!< Pin 12 selected */
#define GPIO_Pin_13 ((uint16_t)0x2000) /*!< Pin 13 selected */
#define GPIO_Pin_14 ((uint16_t)0x4000) /*!< Pin 14 selected */
#define GPIO_Pin_15 ((uint16_t)0x8000) /*!< Pin 15 selected */
#define GPIO_Pin_All ((uint16_t)0xFFFF) /*!< All pins selected */
其次, GPIOSpeed_TypeDef是一個列舉變數,用來儲存GPIO的速度,其定義如下:
typedef enum
{
GPIO_Speed_10MHz = 1,
GPIO_Speed_2MHz,
GPIO_Speed_50MHz
}GPIOSpeed_TypeDef;
它有三種取值,也就是說GPIO的速度有三種取值,列舉變數為1時GPIO的速度對應10MHz,列舉變數為2時GPIO的速度對應2MHz,列舉變數為3時GPIO的速度對應50MHz,總結如下圖:
GPIO的速度 | 列舉變數的取值 |
---|---|
10MHz | 1 |
2MHz | 2 |
50MHz | 3 |
最後, GPIOMode_TypeDef也是一個列舉變數,用來儲存GPIO的工作模式,其定義如下:
typedef enum
{ GPIO_Mode_AIN = 0x0, //模擬輸入
GPIO_Mode_IN_FLOATING = 0x04, //浮空輸入
GPIO_Mode_IPD = 0x28, //帶下拉輸入
GPIO_Mode_IPU = 0x48, //帶上拉輸入
GPIO_Mode_Out_OD = 0x14, //開漏輸出
GPIO_Mode_Out_PP = 0x10, //推輓輸出(我們所選用的模式)
GPIO_Mode_AF_OD = 0x1C, //複用功能的開漏輸出
GPIO_Mode_AF_PP = 0x18 //複用功能的推輓輸出
}GPIOMode_TypeDef;
在對結構體賦值完之後,我們對led的IO口進行置1,主要是為了讓led保持熄滅的狀態,在這裡我們用到了GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)這個函式:
GPIO_SetBits(GPIOB,GPIO_Pin_8); //對IO口置1
3.編寫main.c檔案
#include "stm32f10x.h"
#include "beep.h"
#include "delay.h" //這裡的delay的標頭檔案是自己寫的一個延遲函式的標頭檔案,自己在主函式中編寫也是可以的
int main (void)
{
beep_Iint(); //我們之前編寫的LED初始化函式,對IO口進行配置並且進行初始化
delay_init(); //自己編寫的延遲函式的初始化
while(1)
{
GPIO_SetBits(GPIOB,GPIO_Pin_5); //IO口置0
delay_ms(300);
GPIO_ResetBits(GPIOB,GPIO_Pin_5); //IO口置1
delay_ms(300);
}
}