📄 music.c
字号:
/*******************************************
广州双龙电子
www.sl.com.cn
Chip type : ATMEGA16
Clock frequency : 8MHz
/**************************************************************
声控启动,分别按下A,B,C,D键,小车
作前进,后退,左右转弯动作并演奏不同乐曲
演奏过程中若有键按下,则即时切换到相应状态
********************************************/
#include <iom16v.h>
#include <macros.h>
#include <diy0206.c>
#pragma interrupt_handler timer0:10
#pragma interrupt_handler timer1:7
unsigned char remote_in;
const unsigned int music_data[][2]=
/*******************************************
卡秋莎音乐数据{x,y}
x:对应音符音阶(频率),0表示休止符
y:对应音符节拍
********************************************/
{
{440,600},{494,200},{523,600} ,{440,200},
{523,400},{494,200},{440,200} ,{494,400},
{330,400},{494,600},{523,200} ,{578,600},
{494,200},{578,400},{523,200} ,{0,0},
{494,200},{440,800},{659,400} ,{880,400},
{784,400},{880,200},{784,200} ,{698,400},
{659,200},{578,200},{659,400} ,{440,400},
{698,400},{578,200},{659,600} ,{0,0},
{523,200},{494,200},{330,200} ,{523,200},
{494,200},{440,800},{659,400} ,{880,400},
{784,400},{880,200},{784,200} ,{0,0},
{698,400},{659,200},{578,200} ,{659,400} ,
{440,400},{698,400},{578,200} , {659,600},
{523,200},{494,200},{330,200} , {523,200},
{494,200},{440,800},{0,0}};
#pragma data:data
unsigned int delay=0;
/*******************************
MCU初始化
*******************************/
void music_init(void)
{
MCUCR=0x00;//低电平时产生中断
DDRC=0x01;
TCCR1A=0x00;
TCCR1B=0x09;//TIMER1无预分频
TCCR0=0x03;//CK/64
TCNT0=0x19;
TIMSK=(1<<OCIE1A)|(1<<TOIE0);
}
/**************************************************
T0中断程序,产生音乐节拍
**************************************************/
void timer0(void)
{
delay++;
TCNT0=0x19;
}
/**************************************************
T1中断程序,根据SOUND函数输出一定频率的方波
**************************************************/
void timer1(void)
{
PORTC^=0x01;
}
/*****************************************************
SOUND程序,输出频率为 x HZ的方波,延时 y MS
x:100~20000 HZ, 0表示不发声
y:0~65536 MS
*****************************************************/
void sound(unsigned int x,unsigned int y)
{
SEI(); //开总中断
delay=0;
if (x!=0)//不是休止符
{
x=4000000/x; //计算发声频率
OCR1A=x; //放入输出比较寄存器
TCNT1=0x00;
TIMSK|=(1<<OCIE1A); //T/C1输出比较匹配中断使能
while(delay<y)
;
TIMSK&=~(1<<OCIE1A);
}
else
{
TIMSK&=~(1<<OCIE1A);
while(delay<y)
;
}
CLI();
}
void play_1(void)
{
unsigned char i=0;
music_init(); //MCU初始化
while(music_data[i][1]!=0)//是否终止
{
sound(music_data[i][0],music_data[i][1]);
i++;
remote_in = PINB & 0xF0; //再检测,若有键按下,中断播放并返回
if(remote_in!=0)
return;
}
i=0;
}
void play_2(void)
{
unsigned char i=17;
music_init(); //MCU初始化
while(music_data[i][1]!=0)//是否终止
{
sound(music_data[i][0],music_data[i][1]);
i++;
remote_in = PINB & 0xF0; //再检测,若有键按下,中断播放并返回
if(remote_in!=0)
return;
}
i=17;
}
void play_3(void)
{
unsigned char i=33;
music_init(); //MCU初始化
while(music_data[i][1]!=0)//是否终止
{
sound(music_data[i][0],music_data[i][1]);
i++;
remote_in = PINB & 0xF0; //再检测,若有键按下,中断播放并返回
if(remote_in!=0)
return;
}
i=33;
}
void play_4(void)
{
unsigned char i=45;
music_init(); //MCU初始化
while(music_data[i][1]!=0)//是否终止
{
sound(music_data[i][0],music_data[i][1]);
i++;
remote_in = PINB & 0xF0;
while(remote_in!=0) //再检测,若有键按下,中断播放并返回
return;
}
i=45;
}
/*******************************
主程序
*******************************/
void main(void)
{//遥控车程序
port_init();//调用端口初始化函数
PORTA = 0xFF;
mic_startup();//等待声控启动函数
PORTA = 0x00;
delay_ms(20);
while(1)
{
remote_in = PINB & 0xF0;
switch (remote_in)
{//检测遥控器是否有键按下
case 0x00:
{
stop(); //停止运动
delay_ms(10);
break;
}
case 0x20:
{ // < A >
turn_right(); //右转
play_1(); //播放乐曲1
break;
}
case 0x40:
{ // < B >
backward(); //后退
play_2(); //播放乐曲2
break;
}
case 0x10:
{// < C >
forward(); //前进
play_3(); //播放乐曲3
break;
}
case 0x80:
{ // < D >
turn_left(); //左转
play_4(); //播放乐曲4
break;
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -