STM32实现电子琴:蜂鸣器原理与代码详解

许久没有摸32了,今天是培训的第一天,做个电子琴练练手。

编程难度很小,无非就是gpio控制引脚高低电平转换,比较值得注意的主要是一些乐理上的知识。

我们能听到的1 2 3 4 5 6 7的音符,实际上是一个个固定的频率,这个具体算我也不懂,问巴赫去吧

总而言之,通过百度,我找到了对照图

 那怎么转换这个频率捏,首先来看一下频率单位——赫兹(hz)的定义:

赫兹是国际单位制中频率的单位,它是每秒钟的周期性变动重复次数的计量。
赫兹简称赫。每秒钟振动(或振荡、波动)一次为1赫兹,或可写成次/秒,周/秒。

(摘自百度百科)

这么理解,1赫兹就是一秒震动一次,而图中的高音1就是一秒震动880次。

在单片机里,想让蜂鸣器发出高音1就是一秒高低电平转换880次。

每次震动可以这么写:

GPIO_SetBits(GPIOF,GPIO_Pin_8);
delay_us(5);
GPIO_ResetBits(GPIOF,GPIO_Pin_8);
delay_us(5);

这里就是一个50%的pwm波,记住这是一次频率转换,(博主一开始就把pwm波和频率的概念搞混了)而占空比的变化,反应的是声音的强度,占空比越大,蜂鸣器发出的声音越响。

那880hz举例子,如果我们要让蜂鸣器响高音1一秒钟,那就意味着要转换电平880次,而且,每次转换要均匀分布在1秒内,所以我们要在一秒内分割出880个时间周期,即1s/880=1136us(取整)

而这包含前面的10us,所以一次时间周期应该是这样的:

GPIO_SetBits(GPIOF,GPIO_Pin_8);
delay_us(5);
GPIO_ResetBits(GPIOF,GPIO_Pin_8);
delay_us(5);
delay_us(1136);

事实上,无论是多少秒,只要在这个时间周期内执行这段指令,蜂鸣器都会发出高音1的音调。

以下是函数代码

double connect[3][7]={{880,987.76,1108.73,1174.66,1318.52,1479.98,1661.22},{440,493.88,554.37,587.33,659.33,739.99,830.61},{220,246.94,277.19,293.67,329.63,370,415.31}};
//创建二位数组存放频率数据
void yinjie(int mst, int f,int h)//第一个参数为响的时间(ms),第二个参数确定音阶
{
	int t=(int)1000000.0/connect[h-1][f-1]-10;//计算时间间隔
	int n=mst*1000;//转微秒
	while(n>0)//响的时间每次循环减去时间间隔,小于0时跳出
	{
		GPIO_SetBits(GPIOF,GPIO_Pin_8);
				delay_us(5);
		GPIO_ResetBits(GPIOF,GPIO_Pin_8);
				delay_us(5);
		delay_us(t);
		n-=t+10;
		
	}
	GPIO_ResetBits(GPIOF,GPIO_Pin_8);
			delay_ms(100);
		
		
}

gpio初始化

void Init(){
	//gpio初始化
	GPIO_InitTypeDef  GPIO_InitStructure;

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);//使能GPIOF时钟
  
  //初始化蜂鸣器对应引脚GPIOF8
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;//BEEP对应引脚
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;//下拉
  GPIO_Init(GPIOF, &GPIO_InitStructure);//初始化GPIO
	
  GPIO_ResetBits(GPIOF,GPIO_Pin_8);  //蜂鸣器对应引脚GPIOF8拉低

main(生日快乐歌)

int main(void)
{
	u32 t=0;
	int i;
	Init();
	delay_init(84);

	
  while(1){
		yinjie(400,5,3);
		yinjie(400,5,3);
		yinjie(800,6,3);
		yinjie(800,5,3);
		yinjie(800,1,2);
		yinjie(800,7,3);
		
		yinjie(400,5,3);
		yinjie(400,5,3);
		yinjie(800,6,3);
		yinjie(800,5,3);
		yinjie(800,2,2);
		yinjie(800,1,2);
		
		yinjie(400,5,3);
		yinjie(400,5,3);
		yinjie(400,5,2);
		yinjie(400,3,2);
		yinjie(800,1,2);
		yinjie(800,7,3);
		yinjie(800,6,3);
		
		yinjie(400,4,2);
		yinjie(400,4,2);
		yinjie(400,3,2);
		yinjie(800,1,2);
		yinjie(800,2,2);
		yinjie(800,1,2);
	}

物联沃分享整理
物联沃-IOTWORD物联网 » STM32实现电子琴:蜂鸣器原理与代码详解

发表评论