ATmega16控制蜂鸣器播放音乐

/*****************************************************
编译环境:ICC-AVR
芯片型号:ATmega16
时钟频率:12.000MHz
程序功能:PA0口接蜂鸣器,通过单片机驱动蜂鸣器播放音乐
******************************************************/

#include
#include

//计时值=65536-系统时钟/分频系数/音调频率/2
// 音符 计时值 频率Hz
#define LL6 38263 //220
#define LL7 41245 //247
#define L1 42635 //262
#define L2 45128 //294
#define L3 47354 //330
#define L4 48344 //349
#define L5 50230 //392
#define L6 51900 //440
#define L7 53390 //494
#define N1 54064 //523
#define N2 55315 //587
#define N3 56431 //659
#define N4 56940 //698
#define N5 57883 //784
#define N6 58718 //880
#define N7 59463 //988
#define H1 59805 //1047
#define H2 60430 //1175
#define H3 60987 //1319
#define H4 61241 //1397
#define H5 61709 //1568
#define H6 62127 //1760
#define H7 62500 //1976
#define HH1 62669 //2093
#define O 0 //休止符

/************************************
音乐数据
这段是《孤星独吟》,自己对着简谱翻的
*************************************/
unsigned int song[]=
{
N6,12,N7,4,H1,8,H2,4,H3,4,/**/H2,32,/**/N7,12,N6,4,N5,8,N3,4,N5,4,/**/
N6,32,/**/H1,12,N6,4,N6,8,H3,8,/**/H2,32,/**/N5,12,N6,4,N7,8,H1,4,N7,4,/**/
N6,32,/**/H3,24,N6,8,/**/H2,24,H3,4,H2,4,/**/H1,16,H1,4,N6,4,H1,4,H2,4,/**/
N7,24,H1,4,H2,4,/**/H3,24,H2,4,H1,4,/**/H2,32,/**/
N5,4,N6,4,N7,16,N7,4,N5,4,/**/N6,32,/**/
N6,12,N7,4,H1,8,H2,4,H3,4,/**/H2,32,/**/N7,12,N6,4,N5,8,N3,4,N5,4,/**/
N6,32,/**/H1,12,N6,4,N6,8,H3,8,/**/H2,32,/**/N5,12,N6,4,N7,8,H1,4,N7,4,/**/
N6,32,/**/H3,24,N6,8,/**/H2,24,H3,4,H2,4,/**/H1,16,H1,4,N6,4,H1,4,H2,4,/**/
N7,24,H1,4,H2,4,/**/H3,24,H2,4,H1,4,/**/H2,32,/**/
N5,4,N6,4,N7,16,N6,4,N5,4,/**/N6,32,/**/H3,24,H2,4,H1,4,/**/H2,32,/**/
H1,24,N7,4,N6,4,/**/N7,24,H1,4,H2,4,/**/H3,24,H3,4,N6,4,/**/H2,24,H3,4,H2,4, /**/
H1,16,H1,4,N6,4,H1,4,H2,4,/**/N7,32,/**/H3,24,N6,8,/**/H2,24,H3,4,H2,4,/**/
H1,16,H1,4,N6,4,H1,4,H2,4,/**/N7,24,H1,4,H2,4,/**/H3,24,H2,4,H1,4,/**/
H2,24,H3,4,H2,4,/**/H1,24,N6,8,/**/N7,24,H1,8,/**/N6,32,/**/N6,32,/**/
0xFF //音乐结尾符
};

unsigned int beat; //beat用以存储音符对应的计数值


/****************************
函数功能:控制整首乐曲的演奏
*****************************/
void Music(unsigned int *pMusic)
{
while(*pMusic!=0xFF) //0xFF为音乐结尾符
{
TIMSK=0x04; //Timer1溢出中断使能
beat=*pMusic; //取出音符
TCNT1H=beat/256;
TCNT1L=beat%256; //将音符对应的计数值写入计时器,开始发声

pMusic++; //乐谱音符指针+1 ,取拍数
delay_ms((*pMusic)*52); //节拍延时,可以通过这里调整音乐播放速度


TIMSK=0x00; //当前音符结束,屏蔽Timer1溢出中断

pMusic++; //乐谱音符指针+1,指向下一音符
}
delay_ms(1000); //曲谱结束,等待
}

/************************************
函数功能:完成单个音符的播放
*************************************/
#pragma interrupt_handler timer1_ovf_isr:iv_TIM1_OVF
void timer1_ovf_isr(void)
{
if(beat)
{
PORTA ^= BIT(0); //蜂鸣器接入口电平翻转
TCNT1H=beat/256;
TCNT1L=beat%256; //将音符对应的计数值写入计时器
}
}

void main(void)
{
DDRA = 0xff; //设置PORTA为输出
PORTA = 0x00;

TCCR1B = 0x01; //Timer1开始工作,不分频,分频系数为1
SEI(); //打开全局中断

while(1)
{
Music(song);
}
}

void delay_1ms(void)
{
unsigned i;
for(i=1;i<1714;i++);
}

void delay_ms(unsigned int n)
{
unsigned int i;
for(i=0;i{
delay_1ms();
}
}

相关文档
最新文档