第二十一课 51音乐之一 音阶测试
程序讲解
1、蜂鸣器头文件 MIDI_1.H (无源蜂鸣器)
/*--------------------------------------------------------------*/
/*File: MIDI_1.H */
/*Date: 08-11-2 */
/*Time: 16:58 */
/*Source: Web */
/*Info: 中断发声程序 */
#ifndef __MIDI_1_H__
#define __MIDI_1_H__
/*--------------------------------------------------------------*/
//接口定义
sbit bp = P3^6; //开发板蜂鸣器对应蜂鸣器管脚
/*--------------------------------------------------------------*/
//数据定义
unsigned char STH0;
unsigned char STL0;
unsigned int code tab_fre[] = //音符与计数值对应表
{
64021, 64103, 64260, 64400, //用来给定时器赋初值,以用来发出不同的音调
64524, 64580, 64684, 64777, //每次定时器满,都会溢出中断一次,此时蜂鸣器
64820, 64898, 64968, 65030, //高低电平翻转一次,发出声音(注意为无源的)
65058, 65110, 65157, 65178
};
/*--------------------------------------------------------------*/
//按键消抖延时程序
void delay5ms(void)
{
unsigned char i,j;
for(i = 185; i > 0; i--)
for(j = 12; j > 0; j--);
}
/*--------------------------------------------------------------*/
//定时器中断服务程序
void timer0_ISR(void) interrupt 1 using 0
{
TH0 = STH0; //给高位赋初值
TL0 = STL0; //给低位赋初值
bp = ~bp; //输出高低电平,让蜂鸣器发出声音
}
/*--------------------------------------------------------------*/
void timer0_INT(void)
{
TMOD = 0x01; // 定时器0工作在方式1(16位)
IE = 0x82; //EA = 1; ET0 = 1;
}
#endif
2、主程序
#include<AT89X52.H>
#include"MIDI_1.H" //蜂鸣器头文件
sbit INC_K = P3^4; //升调 调节按键
sbit DEC_K = P3^5; //降调 调节按键
void main(void)
{
unsigned char k;
timer0_INT(); //定时器初始化
while(1)
{
if((INC_K == 0) || (DEC_K == 0)) //判断有无按键按下
{
delay5ms(); //延时消斗
if(INC_K == 0) k++; //升调
if(DEC_K == 0) k--; //降调
while((INC_K == 0) || (DEC_K == 0)) //按键处理
{
TR0 = 1; //允许定时器0工作 音乐响起
STH0 = (unsigned char)(tab_fre[k & 0x0f] >> 8); //取出k对应的音符码,并将音符码高8位送到定时器高8位的缓冲区 STH0
STL0 = (unsigned char)(tab_fre[k & 0x0f] & 0xff); //取出k对应的音符码,并将音符码低8位送到定时器低8位的缓冲区 STL0
}
}
TR0 = 0; //按键没按下则关闭音乐
bp = 1; //关闭蜂鸣器(由PNP三极管驱动,B极为高电平,故处于截止状态)
}
}
本节重点
1、蜂鸣器发声
蜂鸣器分为有源(高电平就发声)和无源(高低电平交替才会发声)两种,我们的开发板选用的是无源的,它发出的声音效果比有源好。我们利用定时器0计数产生溢出中断时将蜂鸣器高低电平翻转一次,即实现了发声。通过按键改变定时器的初值使产生溢出中断的时间不同,于是得到了不同频率的方波(高低电平)于是蜂鸣器就发出了不同的音阶!
2、STH0 = (unsigned char)(tab_fre[k & 0x0f] >> 8);
k & 0x0f 表示取k的低四位防止溢出数组tab_fre[](tab_fre[]里面只有16个数),tab_fre[k & 0x0f] >> 8 表示将数据tab_fre[k & 0x0f] 右移8位,tab_fre[]里面的是16位二进制数,这就是取tab_fre[k & 0x0f] 高8位的意思!(unsigned char)表示将tab_fre[k & 0x0f] >> 8 变成 unsigned char型数据(8位)。tab_fre[k & 0x0f] & 0xff 就是取tab_fre[k & 0x0f]低八位的意思!
相关程序:https://static.assets-stash.eet-china.com/album/old-resources/2009/6/2/5734de86-a5ba-4749-bd64-ac77dfa7d888.rar
文章评论(0条评论)
登录后参与讨论