本文练习硬件使用STM32F103C8芯片开发板,软件使用Keil5-5.23版本安装对应Keil4兼容包,使用Keil4标准库函数开发,练习目的为掌握STM32单片机操作方法,最终独立完成相关项目,为巩固学习并分享学习经验现分享如下:
蜂鸣器相关操作
1.1 相关函数定义
- delay.h
#ifndef __DELAY_H #define __DELAY_H #include "sys.h" void delay_s(u16 s); void delay_ms(u16 ms); void delay_us(u32 us); #endif
- delay.c
#include "delay.h" #define AHB_INPUT 72 //请按RCC中设置的AHB时钟频率填写到这里(单位MHz) void delay_us(u32 uS){ //uS微秒级延时程序(参考值即是延时数,72MHz时最大值233015) SysTick->LOAD=AHB_INPUT*uS; //重装计数初值(当主频是72MHz,72次为1微秒) SysTick->VAL=0x00; //清空定时器的计数器 SysTick->CTRL=0x00000005;//时钟源HCLK,打开定时器 while(!(SysTick->CTRL&0x00010000)); //等待计数到0 SysTick->CTRL=0x00000004;//关闭定时器 } void delay_ms(u16 ms){ //mS毫秒级延时程序(参考值即是延时数,最大值65535) while( ms-- != 0){ delay_us(1000); //调用1000微秒的延时 } } void delay_s(u16 s){ //S秒级延时程序(参考值即是延时数,最大值65535) while( s-- != 0){ delay_ms(1000); //调用1000毫秒的延时 } }
- buzzer.h
#ifndef __BUZZER_H #define __BUZZER_H #include "sys.h" #define BUZZERPORT GPIOB //定义IO接口 #define BUZZER GPIO_Pin_5 //定义IO接口 void BUZZER_Init(void);//初始化 void BUZZER_BEEP1(void);//响一声 void MIDI_PLAY(void); #endif
- buzzer.c
#include "buzzer.h" #include "delay.h" void BUZZER_Init(void){ //蜂鸣器的接口初始化 GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = BUZZER; //选择端口号 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //选择IO接口工作方式 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置IO接口速度(2/10/50MHz) GPIO_Init(BUZZERPORT, &GPIO_InitStructure); GPIO_WriteBit(BUZZERPORT,BUZZER,(BitAction)(1)); //蜂鸣器接口输出高电平1 } void BUZZER_BEEP1(void){ //蜂鸣器响一声 u16 i; for(i=0;i<200;i++){ GPIO_WriteBit(BUZZERPORT,BUZZER,(BitAction)(0)); //蜂鸣器接口输出0 delay_us(500); //延时 GPIO_WriteBit(BUZZERPORT,BUZZER,(BitAction)(1)); //蜂鸣器接口输出高电平1 delay_us(500); //延时 } } uc16 music1[78]={ //音乐1的数据表(奇数是音调,偶数是长度) 330,750, 440,375, 494,375, 523,750, 587,375, 659,375, 587,750, 494,375, 392,375, 440,1500, 330,750, 440,375, 494,375, 523,750, 587,375, 659,375, 587,750, 494,375, 392,375, 784,1500, 659,750, 698,375, 784,375, 880,750, 784,375, 698,375, 659,750, 587,750, 659,750, 523,375, 494,375, 440,750, 440,375, 494,375, 523,750, 523,750, 494,750, 392,750, 440,3000 }; void MIDI_PLAY(void){ //MIDI音乐 u16 i,e; for(i=0;i<39;i++){ for(e=0;e<music1[i*2]*music1[i*2+1]/1000;e++){ GPIO_WriteBit(BUZZERPORT,BUZZER,(BitAction)(0)); //蜂鸣器接口输出0 delay_us(500000/music1[i*2]); //延时 GPIO_WriteBit(BUZZERPORT,BUZZER,(BitAction)(1)); //蜂鸣器接口输出高电平1 delay_us(500000/music1[i*2]); //延时 } } }
1.2 蜂鸣器驱动
- 初始化,按键蜂鸣音
- 初始化时钟,LED,按键
- 初始化蜂鸣器
BUZZER_Init
void BUZZER_Init(void)
功能: 蜂鸣器接口初始化 参数: 无 返回值: 无void BUZZER_Init(void){ //蜂鸣器的接口初始化 GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = BUZZER; //选择端口号 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //选择IO接口工作方式 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置IO接口速度(2/10/50MHz) GPIO_Init(BUZZERPORT, &GPIO_InitStructure); GPIO_WriteBit(BUZZERPORT,BUZZER,(BitAction)(1)); //蜂鸣器接口输出高电平1 }
- 蜂鸣器以1KHz鸣响一声
BUZZER_BEEP1
void BUZZER_BEEP1(void)
功能: 蜂鸣器响一声 参数: 无 返回值: 无void BUZZER_BEEP1(void){ //蜂鸣器响一声 u16 i; for(i=0;i<200;i++){//可以调整鸣响时长 GPIO_WriteBit(BUZZERPORT,BUZZER,(BitAction)(0)); //蜂鸣器接口输出0 delay_us(500); //可以调整频率 GPIO_WriteBit(BUZZERPORT,BUZZER,(BitAction)(1)); //蜂鸣器接口输出高电平1 delay_us(500); //可以调整频率 } }
- FLASH写入LED端口状态时注意转换,确保LED以外端口状态不变
GPIO_ReadOutputDataGPIO_Write(LEDPORT,a|0xfffc&GPIO_ReadOutputData(LEDPORT));
u16 GPIO_ReadOutputData(GPIO_TypeDef* GPIOx)
功能: 读取指定的 GPIO 端口输出 参数: GPIOx:x 可以是 A,B,C,D 或者 E,来选择 GPIO 外设 返回值: GPIO 输出数据端口值 - 相关概念
- 蜂鸣器种类
- 有源蜂鸣器:
- 内置频率发生电路
- 通电就能发声
- 声音频率固定
- 成本较高
- 无源蜂鸣器:
- 无内置频率发生电路
- 需要外部给与频率发声
- 声音频率可调
- 成本低
- 有源蜂鸣器:
- 频率周期
一个低电平与一个高电平组成一个频率周期,发出1KHz声音,每秒1000个周期,每个周期1000us
- 无源蜂鸣器工作原理
低电平下PNP三极管导通,给出频率后蜂鸣器工作,单纯低电平导通并不会使蜂鸣器发声而长时间导通会使其内部线圈发热损坏,所以蜂鸣器要以高电平结束,高电平下三极管C端E端断开,蜂鸣器断电
- 蜂鸣器种类
1.3 MIDI音乐播放程序
- MIDI音乐播放程序
- 初始化时钟,LED,按键,蜂鸣器
- 创建数组保存音符的频率(奇数位)与长度(偶数位)
uc16 music1[78]={ //音乐1的数据表(偶数位是频率,奇数位是长度) 330,750, 440,375, 494,375, 523,750, 587,375, 659,375, 587,750, 494,375, 392,375, 440,1500, 330,750, 440,375, 494,375, 523,750, 587,375, 659,375, 587,750, 494,375, 392,375, 784,1500, 659,750, 698,375, 784,375, 880,750, 784,375, 698,375, 659,750, 587,750, 659,750, 523,375, 494,375, 440,750, 440,375, 494,375, 523,750, 523,750, 494,750, 392,750, 440,3000 };
- MIDI_PLAY
void MIDI_PLAY(void)
功能: 播放指定数量的音调与节拍 参数: 无 返回值: 无
void MIDI_PLAY(void){ u16 i,e; for(i=0;i<39;i++){//播放全部音符 for(e=0;e<music1[i*2]*music1[i*2+1]/1000;e++){//求节拍,长度*频率(s)/1000=播放时间(ms) GPIO_WriteBit(BUZZERPORT,BUZZER,(BitAction)(0)); //蜂鸣器接口输出0 delay_us(500000/music1[i*2]); //0.5S内振动相应次数的延时长度,音调 GPIO_WriteBit(BUZZERPORT,BUZZER,(BitAction)(1)); //蜂鸣器接口输出高电平1 delay_us(500000/music1[i*2]); //0.5S内振动相应次数的延时长度,音调 } } }
- 相关概念
- 频率f 频率是单位时间内完成周期性变化的次数,是描述周期运动频繁程度的量
- 周期T 周期,物体作往复运动或物理量作周而复始的变化时,重复一次所经历的时间
- f=1/T
- C调音符频率对照表