请举一个简单的例子来说明如何制作不同音调的音乐。

用蜂鸣器做音乐很奇怪。众所周知,单片机上的蜂鸣器只有在加上高低电平后才会发出声音。从理论上讲,声音没有频率、音色等。对于单片机来说,可以通过一个IO口的高低电平变化来驱动蜂鸣器发出各种不同平率的声音。

这主要是通过使用timer 1CTC模式,启动iv_TIMER1_COMPA中断,然后得到某首歌曲的平率参数来实现的。我找到了一个程序,如下;

/****************************************

*利用M16单片机的I/O口产生模拟音乐*

*功能:使用I/O端口生成模拟音乐*

*时钟频率:外部7.3728M *

*设计:同和*

*修订日期:2007年4月,13 *

*编译环境:ICC-AVR6.31 *

*实验环境:Afa的M16学习板*

*声音:无源蜂鸣器连接到PD5 *

*结果:测试通过*

****************************************/

# include & ltIOM 16v . h & gt;

# include & ltmacros.h & gt

#include "wo_ni.h" //包含音乐文件。

#include "delay.h" //延迟文件

#定义uchar无符号字符

#定义uint无符号整数

/************************************

*端口初始化功能*

************************************/

void port_init(void)

{

PORTD = 0x20//蜂鸣器接口初始化为高。

DDRD = 0x 20;//蜂鸣器接口输出。

}

/**********************************

*定时器1中断进入功能:产生方波声音*

**********************************/

#pragma中断处理程序定时器1:iv _定时器1_COMPA

void timer 1(void)//timer 1中断入口。

{

portd^=(1<;& lt5);//产生方波,声音。

}

/***********************************

*音乐制作功能*

*功能:输出频率为x,延时为y毫秒的方波*

*范围:x:100-20000赫兹,0:无声音*

* y:0-65536毫秒*

***********************************/

无效声音(uint i)

{

uint x;

x = I;//获取音乐的频率数据

如果(x!=0)

{

x = 3686400/x;//数据计算

ocr 1A = x;//比较值赋值

tccr 1B = 0x 09;//允许反相输出的比较

}

其他

{

tccr 1B = 0x 00;//频率为0,静止,无声音。

}

}

/******************************

*主要功能*

******************************/

无效总管(无效)

{

uchar I = 0;

port _ init();

tccr 1A = 0x 40;//配置T/C1为CTC模式,OC1A反相生成音乐。

TIMSK | =(1 & lt;& ltocie 1A);//打开比较匹配中断

SEI();//打开主机中断

while(1)

{

tccr 1B = 0x 09;//打开比较匹配

while(music_data[i][1]!=0) //等待最后一个音符。

{

sound(music _ data[I][0]);//输出注释

delay _ ms(music _ data[I][1]);//节拍延迟

tccr 1B = 0x 00;//播放一个音符后停止

PORTD | =(1 & lt;& lt5);//关闭蜂鸣器保护喇叭。

i++;//准备一张纸条。

delay _ ms(5);//播放

}

tccr 1B = 0x 00;

PORTD | =(1 & lt;& lt5);//关闭蜂鸣器保护喇叭。

delay _ ms(4000);

I = 0;

}

}

/////头文件2

flash unsigned int music _ data[][2]=

{

{587,800},{698,800},{466,1600},{523,800},{587,800},{349,1600},

{466,800},{523,800},{587,800},{698,800},{523,3200},{587,800},

{698,800},{466,1600},{523,800},{587,800},{392,1600},{523,800},

{349,800},{523,800},{587,800},{466,1600},{784,1600},{698,1600},

{784,1600},{466,1600},{587,800},{392,800},{587,1200},{698,400},

{523,3200},{587,800},{698,800},{466,1600},{523,800},{587,800},

{392,1600},{523,800},{349,800},{523,800},{587,800},{466,3200},

{ 0, 0}

};

#pragma数据:数据

//头文件3

/****************************************

*函数名:void delay_us(uchar i) *

*功能:延迟功能*

*晶体频率:7.3728兆赫*

****************************************/

void delay_us(无符号整数I)

{

当(我-)

{

NOP();

NOP();

}

}

/****************************************

*函数名:void delay_ms(uint i) *

*功能:延迟功能*

*晶体频率:7.3728兆赫*

*入口参数:1毫秒*

****************************************/

void delay_ms(无符号整数I)

{

无符号int a;

for(;我;我-)

{

for(a = 1052;a;答-)

{;}

}

}

你自己把这些程序组合起来,把PD5接到蜂鸣器接口上。会很精彩的。

带着疑问联系