- 阅读权限
- 150
- UID
- 7
- 帖子
- 140
- 精华
- 0
- 注册时间
- 2013-2-26
- 在线时间
- 20 小时
- UID
- 7
- 帖子
- 140
- 精华
- 0
- 注册时间
- 2013-2-26
- 在线时间
- 20 小时
|
/*****************************************
* 用M16单片机I/O口生成模拟音乐 *
* 功 能:用I/O口生成模拟音乐 *
* 时钟频率:内部8M(频率太低音乐不准) *
* 设 计:tonghe *
* 修改日期:2007年04月13日 *
* 参考资料:ICC AVR应用实例 *
* 编译环境:ICC-AVR6.31 *
* 实验环境:M16学习板 *
* 发 声:无源蜂鸣器 *
* 结 果:试验通过 *
*****************************************/
#include <iom16v.h>
#include <macros.h>
#define uchar unsigned char
#define uint unsigned int
/****************************************
* 定义音乐数据二维数组{x,y} *
* x:对应音符音阶(频率),0表示休止符 *
* y:对应音符节拍 *
****************************************/
//以下音乐数据为《卡秋莎》,位于程序区
flash uint music_data[][2]=
{
{440,600},{494,200},{523,600},{440,200},{523,400},{494,200},
{440,200},{494,400},{330,400},{494,600},{523,200},{587,600},
{494,200},{587,400},{523,200},{494,200},{440,800},{659,400},
{880,400},{784,400},{880,200},{784,200},{698,400},{659,200},
{587,200},{659,400},{440,400},{ 0,200},{698,400},{578,200},
{659,600},{523,200},{494,200},{330,200},{523,200},{494,200},
{440,800},{659,400},{880,400},{784,400},{880,200},{784,200},
{698,400},{659,200},{587,200},{659,400},{440,400},{ 0,200},
{698,400},{587,200},{659,600},{523,200},{494,200},{330,200},
{523,200},{494,200},{440,800},{ 0, 0}
};
#pragma data:data //设置回到数据存储器区
uint delay=0;
/************************************
* 端口初始化函数 *
************************************/
void port_init(void)
{
MCUCR=0x00;
DDRC=0x01;
}
/***********************************
* 定时器0初始化函数 *
***********************************/
void timer0_init(void)
{
TCCR0 = 0x00; //暂停定时器0
TCNT0 = 0x19; //装初值
TCCR0 = 0x04; //启动定时器0
}
/**********************************
*定时器0中断入口函数:产生音乐节拍*
**********************************/
#pragma interrupt_handler timer0:8 //_ovf_isr:10
void timer0(void) //_ovf_isr(void)
{
delay++;
TCNT0 = 0x19; //重装初值
}
/***********************************
* 定时器1初始化函数 *
***********************************/
void timer1_init(void) //定时器1初始化:1秒定时,预分频256
{
TCCR1B = 0x00; //停止定时器
// TCNT1H = 0xF0; //初值高字节
// TCNT1L = 0xBE; //定时初值低字节
TCCR1A = 0x00;
TCCR1B = 0x04; //启动定时器
}
/**********************************
*定时器1中断入口函数:产生方波发声*
**********************************/
#pragma interrupt_handler timer1:5 //_ovf_isr:9
void timer1(void) //_ovf_isr(void) //定时器1中断入口
{
// TCNT1H = 0xF0; //重装初值
// TCNT1L = 0xBE; //
PORTC^=0x01; //产生方波,发声
}
/*********************************
SOUND函数
功能:输出频率为x的方波,延时y MS
范围:x:100-20000Hz,0:不发声
y:0-65536 MS
*********************************/
void sound(uint x,uint y)
{
SEI(); //
delay=0;
if(x!=0)
{
x=4000000/x;
OCR1A=x;
TCNT1=0x00;
TIMSK|=0x40;
while(delay<y)
;
TIMSK&=0xBF;
}
else
{
TIMSK&=0xBF;
while(delay<y)
;
}
CLI();
}
/***********************
*************************/
void main(void)
{
uchar i=0;
port_init();
timer0_init();
timer1_init();
while(1)
{
while(music_data[i][0]!=0)
{
sound(music_data[i][0],music_data[i][1]);
i++;
}
i=0;
}
}
|
|