原创 第二十一课 51音乐之一 音阶测试

2009-6-2 21:00 4619 7 7 分类: MCU/ 嵌入式

第二十一课  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


 

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
我要评论
0
7
关闭 站长推荐上一条 /3 下一条