用单片机验证音调高低与振动频率的关系
2019-10-25吝欢欢任新成王玉清
吝欢欢,任新成,王玉清
延安大学物理与电子信息学院,陕西延安716000
1引言
“音调”是物理8年级上册《声音的特性》一节中的重要概念。我们都知道,声音的高低叫做音调,在日常生活中,我们可以通过听觉的不同感受来辨别音调的高低。但是,由于对发声体的振动频率我们无法直观感知,更难以获得准确的数据。所以,“音调高低与振动频率的关系”就成为本节的教学难点。因此,如何让学生更好地感受音调的高低、明确振动频率的大小,并进一步得到两者的相互关系就成为教学的关键所在[1]。
利用AT89C51单片机的定时器中断功能,通过改变蜂鸣器的发声频率来控制音调高低,模拟简易电子琴的工作过程。能够使学生更加直观地感受物理现象,精确验证音调高低与发声体振动频率的关系,总结物理规律。而且单片机操作系统成本低廉 (一般在二三十元不等),性价比高,为学习和应用提供了便利条件。
2 实验基本原理介绍
2.1 AT89C51单片机简介
AT89C51单片机是美国ATMEL公司生产的低电压、高性能CMOS8位单片机,内含4KB可反复擦写的只读程序存储器(ROM)和128KB随机数据存储器(RAM)。内置通用8位中央处理器(CPU)和Flash存储单元,并且兼容MCS-51指令系统。
图1 AT89C51单片机控制蜂鸣器电路图
2.2 AT89C51单片机控制发声系统
AT89C51单片机控制发声系统[2]如图1所示,它是由单片机、时钟电路、复位电路、按键电路和蜂鸣器电路组成。其中,时钟电路由一个12 MHz的晶振和两个33 pF的电容组成,它们决定了单片机的工作时间精度为1 μs。该系统采用按键手动复位方式,即在单片机运行期间,用手动按键的方式使单片机初始化。系统利用P1口的P1.0-P1.7引脚设置了8个独立按键,当有键按下时,P1口相应的引脚置为低电平,单片机接收脉冲信号。在实验中,我们用其中P1.0-P1.6这7个引脚分别来控制C调中音的7个音调。蜂鸣器电路主要由蜂鸣器、PNP型三极管和一个电阻组成,低电平有效,即当向电路输入高电平(P3.0引脚置1)时,蜂鸣器中无电流通过,电路不发声;当向其输入低电平(P3.0引脚置0)时,蜂鸣器中有电流通过,产生蜂鸣。我们可以通过控制高、低电平的持续时间来形成不同频率的脉冲电压,驱动蜂鸣器发声,从而实现对音调高低的控制。
2.3 音调控制原理
当单片机[3]内部定时器/计数器T0工作在计数器模式1时,寄存器TH0和TL0是以全部16位参与工作,计数长度为216=65 536。我们就可以通过改变计数初值TH0、TL0来产生不同的频率。 例如,C 调中音 1(do)的音频 f=523 Hz,周期s=1912 μs,定时器的定时时间为μs=956 μs,即每经过 956 μs,使输出口改变一次脉冲电压。定时器的计数值=956,则装入T0计数器初值65 536-956=64 580,即启动T0工作后,每计数956次时将产生溢出中断,进入中断服务后将P3.0(RXD)引脚输出电平取反就可得到中音do的音符频率,如图2所示。
图2 音符脉冲波形图
同理,C调中音各音符的频率与计数初值如表1所示。
表1 C调中音各音符的频率与计数初值对照表
3 实验过程
我们使用Keil C51软件的C语言编写程序来实现实验目的。
3.1 准备工作
首先,启动Keil C51软件进入编辑界面,单击“Project”菜单,在弹出的下拉子菜单中选择“New Project”选项建立新工程,选择文件保存路径,输入工程文件名后点击保存,在弹出的对话框中选择相应的单片机型号,即Atmel公司的AT89C51型单片机,点击确定按钮。然后,在编辑界面“File”菜单的下拉子菜单中单击“New”选项新建文件。 再单击“File”菜单下的“Save As”选项保存该文件,在弹出的对话框中“文件名”栏内输入文件名及对应的扩展名,如“test.c”。单击“保存”按钮后回到编辑界面,单击“Target 1”前面的“+”号,在“Source Group 1”上单击右键后再单击“Add Files to Group‘Source Group 1’”。 最后,在弹出的对话框中选中文件test.c,单击 “Add”按钮,如图3所示。
图3 Keil C51编辑界面
3.2 输入程序和编译
在KeilC51的编辑界面输入如下C语言源程序:
#include<reg51.h> //包含51单片机寄存器定义的头文件
sbit key1=P1^0; //将key1位定义为P1.0引脚
sbit key2=P1^1; //将key2位定义为P1.1引脚
sbit key3=P1^2; //将key3位定义为P1.2引脚
sbit key4=P1^3; //将key4位定义为P1.3引脚
sbit key5=P1^4; //将key5位定义为P1.4引脚
sbit key6=P1^5; //将key6位定义为P1.5引脚
sbit key7=P1^6; //将key7位定义为P1.6引脚
sbit sound=P3^0; //将sound位定义为P3.0
unsigned int C; //定义全局变量,储存定时器的定时常数
unsigned long n; //定义无符号数n
//以下是C调中音的音频宏定义
#define do 64580 //将“do”宏定义为中音“1”的初值64580
#define re 64687 //将“re”宏定义为中音“2”的初值64687
#define mi 64780 //将“mi”宏定义为中音“3”的初值64780
#define fa 64822 //将“fa”宏定义为中音“4”的初值64822
#define sol 64900 //将“sol”宏定义为中音“5”的初值64900
#define la 64969 //将“la”宏定义为中音“6”的初值64969
#define si 65031 //将“si”宏定义为中音“7”的初值65031
timer0()interrupt 1 //函数功能:产生中断,改变脉冲电压
{TH0=C/256; //对16位计数器高8位TH0赋值
TL0=C%256; //对16位计数器低8位TL0赋值
sound=~sound;} //取反形成脉冲电压,输出音频
void main(void) //函数功能:主函数
{TMOD=0x01; //使用定时器0的工作模式1
ET0=1; //定时器T0中断允许
EA=1; //开总中断
while(1) //无限循环,按键扫描
{if(key1==0) //检测key1键按下
{for(n=0;n<5000;n++); //延时 5ms,按键消抖,防止误操作
while(!key1) //如果key1键按下,循环指令
{C=do; //将中音do的初值赋给C
TR0=1;}} //开定时器T0
if(key2==0) //检测key2键按下
{for(n=0;n<5000;n++); //延时 5ms,按键消抖,防止误操作
while(!key2) //如果key2键按下,循环指令
{C=re; //将中音re的初值赋给C
TR0=1;}} //开定时器T0
if(key3==0) //检测key3键按下
{for(n=0;n<5000;n++); //延时 5ms,按键消抖,防止误操作
while(!key3) //如果key3键按下,循环指令
{C=mi; //将中音mi的初值赋给C
TR0=1;}} //开定时器T0
if(key4==0) //检测key4键按下
{for(n=0;n<5000;n++); //延时 5ms,按键消抖,防止误操作
while(!key4) //如果key4键按下,循环指令
{C=fa; //将中音fa的初值赋给C
TR0=1;}} //开定时器T0
if(key5==0) //检测key5键按下
{for(n=0;n<5000;n++); //延时 5ms,按键消抖,防止误操作
while(!key5) //如果key5键按下,循环指令
{C=sol; //将中音sol的初值赋给C
TR0=1;}} //开定时器T0
if(key6==0) //检测key6键按下
{for(n=0;n<5000;n++); //延时 5ms,按键消抖,防止误操作
while(!key6) //如果key6键按下,循环指令
{C=la; //将中音la的初值赋给C
TR0=1;}} //开定时器T0
if(key7==0) //检测key7键按下
{for(n=0;n<5000;n++); //延时 5ms,按键消抖,防止误操作
while(!key7) //如果key7键按下,循环指令
{C=si; //将中音si的初值赋给C
TR0=1;}} //开定时器T0
TR0=0; //关定时器
sound=1;}} //关蜂鸣器
程序输入完毕后,单击“Project”菜单下的“Built Target”选项,确认编译无误,如图4所示。
图4 Keil C51程序编译界面
3.3 调试和下载
依次单击 “Debug”菜单下的“Start/Stop Debug Session”和“Go”选项调试运行,然后再依次单击 “Stop Running” 和 “Start/Stop Debug Session”选项停止运行。选择“Project”菜单下的“Options for Target ‘Target 1’”选项 ,在弹出的对话框中将“Target”选项卡的Xtal(MHz)一栏输入 12,选择“Output”选 项 卡中的“Create HEX File”选项,点击确定按钮,使程序编译后产生HEX代码,最后用烧录软件(STC-ISP)将程序下载至AT89C51单片机中即可,如图5所示。
图5 程序下载界面
4 实验小结
利用AT89C51单片机的基本操作功能,可以用实验的方法精确验证音调高低与发声体振动频率的关系,使学生更加清晰、直观地感受物理现象,自主总结物理规律,同时寓教于乐,通过模拟电子琴的工作流程,激发了学生强烈的好奇心和求知欲望,而且了解了有关编程方面的知识和方法,训练了学生的逻辑思维。