在一些带电机的产品上,上电时,可以听到美妙的开机音乐,如DJI的mavic pro[1],很是优雅,让人流连忘返,更有甚者,有下载后作为手机铃声的,有作闹铃的等等用途,对于工程师来说,最最有趣的事情是,拆开外壳后,在电路板上竟然未发现有蜂鸣器,未发现有扬声器(俗称喇叭),按照常规,播放音乐要不是喇叭,要不是蜂鸣器,那声音的来源来至于何处?
物理学知识告诉人们,声音起源于振动,人耳的敏感频率是20Hz-20KHz,并且随着年龄的增长,敏感频率的上下限会向中间收缩,原因可参考链接[2]。蜂鸣器和喇叭的原理即是基于此而来,二者的原理和结构可以参考链接[3][4],这里不再缀述。
对这些有开机音乐并且无蜂鸣器和扬声器的产品来说,发声也是由振动产生,而振动源正是来源于电机。实验表明,电机转动会带动气隙空气振动,进而发出声音,发声的频率等于振动的频率,前提是电机宏观无转动,否则会出现类似破音的感觉。
基于以上原理,可以编写电机的单频点声音,由于无法产生正弦波,可以用方波替代。其中方波的频率等于声音的频率,占空比影响声音(振动)大小,切记,不可让电机转动。这里有两种方法可以做:
① 延时,获得大致的时间,这样得到的频率不够准确,调试复杂,移植麻烦
② 定时器,可以精确得到频率,调试简单,移植方便
因此,这里采用定时器的方式来产生。
对于Cortex-M4&M3内核来说,系统自带一个24位的Systick定时器,时钟可以配置成
外部时钟,也可以配置成系统时钟,请参考相应MCU的手册。根据Keil官网可以获悉,与Systick定时器有关的寄存器为以下四个:
而在这里应用到的就只有CSR和RVR,CSR是控制状态寄存器,有效的为四位:
⑴ Countflag是定时器溢出标志,systick定时器采用向下计数的方式,定时器从RVR的值,经过一个时钟减一,减到0时,置位countflag。
⑵ clksource选择定时器的时钟,0选择外部时钟,可查看手册中定义;1选择处理器时钟,即为单片机的主频。
⑶ tickint使能中断与否,1使能中断,下溢出触发中断;0失能中断
⑷ enable使能定时器与否,1使能,定时器载入RVR寄存器的值,开始下计数;0失能,定时器不工作。
以上关于定时器的位定义,可以查阅DUI0553A_cortex_m4_dgug.pdf文件而得。
void sing(void)
{
****//开启电机
SysTick->LOAD =(uint32_t)(170000000*volume/freq);
SysTick->CTRL |= 0x00000001;//enablesystick timer
while(((SysTick->CTRL)&0x00010000)==0);
SysTick->CTRL&= 0xFFFEFFFE;//Disable systick timer and clear countflag
****//关闭电机
SysTick->LOAD=(uint32_t)(170000000*(1.0f-volume)/freq);
SysTick->CTRL|= 0x00000001;//enable systick timer
while(((SysTick->CTRL)&0x00010000)==0);
SysTick->CTRL&= 0xFFFEFFFE;//Disable systick timer and clear countflag
}
上面代码中,volulme是音量,决定声音大小,freq是相应的频点,170000000是所选用的MCU主频170MHz,根据所选用的主频做相应的修改。
下载频率后,可以听到电机发出了单频点的声音,可以在手机上使用Decibel X分析声音频率。
由此可以看出,电机的发声方式与蜂鸣器的原理是一样的,都是可以发出单频点,所以控制上可以相同,多频点,甚至一首简单的单曲,也可以由电机发出,需要说明的是,无刷电机也可以同有刷电机一样发声,其原理在于控制某两相导通关断即可,mavic pro就是依照如此进行控制。