STM32 学习12 蜂鸣器实验
Posted 编程圈子
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32 学习12 蜂鸣器实验相关的知识,希望对你有一定的参考价值。
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 学习12 蜂鸣器实验的主要内容,如果未能解决你的问题,请参考以下文章
STM32F103五分钟入门系列蜂鸣器实验(库函数+寄存器)
stm32入门第二天环境搭建RCC时钟GPIO闪烁实验与有源蜂鸣器实验
stm32入门第二天环境搭建RCC时钟GPIO闪烁实验与有源蜂鸣器实验