STM32蜂鸣器实验(位操作)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32蜂鸣器实验(位操作)相关的知识,希望对你有一定的参考价值。

参考技术A 1.beep.h文件中写入

//蜂鸣器端口定义

void BEEP_Init(void); //初始化

2.beep.c文件中写入

//初始化 PB8 为输出口.并使能这个口的时钟
//LED IO 初始化
void BEEP_Init(void)

GPIO_InitTypeDef GPIO_InitStructure; //结构体指针
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
//使能 GPIOB 端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //BEEP-->GPIOB.8 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度为 50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure); //根据参数初始化 GPIOB.8
GPIO_ResetBits(GPIOB,GPIO_Pin_8); //输出 0,关闭蜂鸣器输出


main主函数里面写入

//ALIENTEK 精英 STM32 开发板实验 2
//蜂鸣器实验
int main(void)

delay_init(); //延时函数初始化
LED_Init(); //初始化与 LED 连接的硬件接口ALIENTEK 精英 STM32F103 V1 开发板教程

BEEP_Init(); //初始化蜂鸣器端口
while(1)

LED0=0; //位操作,LED0为低电平
BEEP=0; //位操作,BEEP为低电平
delay_ms(300); //延时300毫秒
LED0=1;
BEEP=1;
delay_ms(300);

STM32 学习12 蜂鸣器实验

一、蜂鸣器简介

蜂鸣器主要有: 压电式蜂鸣器和电磁式蜂鸣器。

  • 压电式蜂鸣器,由多谐振荡器、压电蜂鸣片、阻抗匹配器及共鸣箱、外壳等组成,一般是无源是蜂鸣器。
  • 电磁式蜂鸣器:由振荡器、电磁线圈、此贴、震动膜片及外壳等组成,一般要接电源。

通过改变单片机引脚输出波形的频率,就可以控制蜂鸣器发出声音的银色、音调,脉冲一般1.5-5KHz。
改变输出电平的高低电平占空比,可一控制蜂鸣器声音大小。

本文使用普中开发板,其中:

  • P26806L使用的是无源蜂鸣器。
  • P2806D 使用的是有源蜂鸣器。

本文使用6806L,无源蜂鸣器,电路如下:

如果使用PZ6806D,则使用有源蜂鸣器,电路如下:

有源蜂鸣器需要使用PNP 三极管对stm32引脚信号进行放大。

二、程序开发

1. 位操作定义

system.h 里定义

#ifndef _system_H
#define _system_H


#include "stm32f10x.h"


//位带操作,实现51类似的GPIO控制功能
//具体实现思想,参考<<CM3权威指南>>第五章(87页~92页).
//IO口操作宏定义
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2)) 
#define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr)) 
#define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum)) 
//IO口地址映射
#define GPIOA_ODR_Addr    (GPIOA_BASE+12) //0x4001080C 
#define GPIOB_ODR_Addr    (GPIOB_BASE+12) //0x40010C0C 
#define GPIOC_ODR_Addr    (GPIOC_BASE+12) //0x4001100C 
#define GPIOD_ODR_Addr    (GPIOD_BASE+12) //0x4001140C 
#define GPIOE_ODR_Addr    (GPIOE_BASE+12) //0x4001180C 
#define GPIOF_ODR_Addr    (GPIOF_BASE+12) //0x40011A0C    
#define GPIOG_ODR_Addr    (GPIOG_BASE+12) //0x40011E0C    

#define GPIOA_IDR_Addr    (GPIOA_BASE+8) //0x40010808 
#define GPIOB_IDR_Addr    (GPIOB_BASE+8) //0x40010C08 
#define GPIOC_IDR_Addr    (GPIOC_BASE+8) //0x40011008 
#define GPIOD_IDR_Addr    (GPIOD_BASE+8) //0x40011408 
#define GPIOE_IDR_Addr    (GPIOE_BASE+8) //0x40011808 
#define GPIOF_IDR_Addr    (GPIOF_BASE+8) //0x40011A08 
#define GPIOG_IDR_Addr    (GPIOG_BASE+8) //0x40011E08 
 
//IO口操作,只对单一的IO口!
//确保n的值小于16!
#define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr,n)  //输出 
#define PAin(n)    BIT_ADDR(GPIOA_IDR_Addr,n)  //输入 

#define PBout(n)   BIT_ADDR(GPIOB_ODR_Addr,n)  //输出 
#define PBin(n)    BIT_ADDR(GPIOB_IDR_Addr,n)  //输入 

#define PCout(n)   BIT_ADDR(GPIOC_ODR_Addr,n)  //输出 
#define PCin(n)    BIT_ADDR(GPIOC_IDR_Addr,n)  //输入 

#define PDout(n)   BIT_ADDR(GPIOD_ODR_Addr,n)  //输出 
#define PDin(n)    BIT_ADDR(GPIOD_IDR_Addr,n)  //输入 

#define PEout(n)   BIT_ADDR(GPIOE_ODR_Addr,n)  //输出 
#define PEin(n)    BIT_ADDR(GPIOE_IDR_Addr,n)  //输入

#define PFout(n)   BIT_ADDR(GPIOF_ODR_Addr,n)  //输出 
#define PFin(n)    BIT_ADDR(GPIOF_IDR_Addr,n)  //输入

#define PGout(n)   BIT_ADDR(GPIOG_ODR_Addr,n)  //输出 
#define PGin(n)    BIT_ADDR(GPIOG_IDR_Addr,n)  //输入


#endif

2. 引脚定义

beep.h

#ifndef _beep_H
#define _beep_H

#include "system.h"

/*  蜂鸣器时钟端口、引脚定义 */
#define BEEP_PORT 			GPIOB   
#define BEEP_PIN 			GPIO_Pin_5
#define BEEP_PORT_RCC		RCC_APB2Periph_GPIOB

#define beep PBout(5)

void BEEP_Init(void);

#endif

3. GPIO 初始化

#include "beep.h"

void BEEP_Init()	  //端口初始化
{
	GPIO_InitTypeDef GPIO_InitStructure;	//声明一个结构体变量,用来初始化GPIO

	RCC_APB2PeriphClockCmd(BEEP_PORT_RCC,ENABLE);   /* 开启GPIO时钟 */

	/*  配置GPIO的模式和IO口 */
	GPIO_InitStructure.GPIO_Pin=BEEP_PIN;		//选择你要设置的IO口
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;		  //设置推挽输出模式
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;	  //设置传输速率
	GPIO_Init(BEEP_PORT,&GPIO_InitStructure); 	 /* 初始化GPIO */
}



4. 主函数输出脉冲

main.c



#include "system.h"
#include "SysTick.h"
#include "beep.h"

int main()
{
	u16 i=0;
	SysTick_Init(72);
	BEEP_Init();
	while(1)
	{
		i++;
		if(i%10==0)
		{
			beep=!beep;
		}
		delay_us(10);  
	}
}

可以通过改变延迟来修改音调:

while(1){
	beep=1;
	delay_us(150);
	beep=0;
	delay_us(50);
}

三、音乐盒程序开发

1. 项目架构

2. 主程序入口

main.c

#include "system.h"
#include "SysTick.h"
#include "beep.h"


int main()
{
	SysTick_Init(72);
	BEEP_Init();
	while(1)
  {                
     play_music();        
  }    
}

3. beep.h 头文件

#ifndef _beep_H
#define _beep_H

#include "SysTick.h"
#include "system.h"

/*  蜂鸣器时钟端口、引脚定义 */
#define BEEP_PORT 			GPIOB   
#define BEEP_PIN 			GPIO_Pin_5
#define BEEP_PORT_RCC		RCC_APB2Periph_GPIOB

#define beep PBout(5)

void BEEP_Init(void);
void play_music(void);
#endif

4. beep.c 乐谱文件

#include "beep.h"


/*******************************************************************************
* 函 数 名         : BEEP_Init
* 函数功能		   : 蜂鸣器初始化
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/

void BEEP_Init()	  //端口初始化
{
	GPIO_InitTypeDef GPIO_InitStructure;	//声明一个结构体变量,用来初始化GPIO

	RCC_APB2PeriphClockCmd(BEEP_PORT_RCC,ENABLE);   /* 开启GPIO时钟 */

	/*  配置GPIO的模式和IO口 */
	GPIO_InitStructure.GPIO_Pin=BEEP_PIN;		//选择你要设置的IO口
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;		  //设置推挽输出模式
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;	  //设置传输速率
	GPIO_Init(BEEP_PORT,&GPIO_InitStructure); 	 /* 初始化GPIO */
}

void Sound(u16 frq)
{
    u32 time;
    if(frq != 1000)
    {
        time = 500000/((u32)frq);
        beep = 1;
        delay_us(time);
        beep = 0;
        delay_us(time);
    }else
        delay_us(1000);
}

void play_music(void)
{    
    // 各音调频率表    
                // 0   1   2   3   4   5   6   7  低1  低2 低3 低4 低5 低6 低7
    uc16 tone[] ={250,262,294,330,350,393,441,495,525,589,661,700,786,882,990}; //音调
	  // 生日快乐乐谱
    u8 music[]={5,5,6,5,8,7,5,5,6,5,9,8,5,5,12,10,8,7,6,11,
                  11,10,8,9,8,5,5,8,5,5,12,10,8,7,6,11,11,10,8,9,8
    };
	  // 节拍时间
    u8 time[] = {1,2,2,2,2,4,1,2,2,2,2,4,1,2,2,2,1,4,
                  4,1,2,2,2,2,4,1,2,4,1,2,2,2,1,4, 4,1,2,2,2,2,4,4
    }; 
              
		// velocity 越大,播放越快
    u32 velocity;
    u16 i,e;
    velocity = 20;
    for(i=0;i<sizeof(music)/sizeof(music[0]);i++){
        for(e=0;e<((u16)time[i]) * tone[music[i]] / velocity;e++){
            Sound((u32)tone[music[i]]);
        }    
    }
}

以上是关于STM32蜂鸣器实验(位操作)的主要内容,如果未能解决你的问题,请参考以下文章

STM32 学习12 蜂鸣器实验

STM32的位操作问题

STM32IO口8位操作移位的方式

STM32F103五分钟入门系列蜂鸣器实验(库函数+寄存器)

STM32中常用的C语言知识点总结!

STM32F103C8T6,没有蜂鸣器我想装上,要怎么操作