⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 music_m48.c

📁 这是用AVR ATMega48单片机做的一个音乐播放程序.
💻 C
字号:
/******************************************************************************/
/*                          单片机放音机源程序(V1.0b)                         */
/*                   创建人:QQQ             创建日期:2005-3-8               */
/*                   修改人:QQQ             修改日期:2005-3-18              */
/*                   修改人:CWD             修改日期:2005-6-15              */
/******************************************************************************/
/*修改内容:改为M48,并用GCC编译。	*/
// 目标CPU : ATmega48
// 晶    振: 默认:8.0000MHz/8
/*                           ---------
						1---|         |---28
                        2---|         |---27   PC4-->9012-->SPEAK              
                        3---|         |---26                                       
						4---|   AT    |---25                                       
						5---|  MEGA   |---24                                       
                        6---|   48L    |---23                    
                        7---|         |---22                                       
                        8---|         |---21                                       
                        9---|         |---20                                       
                       10---|  1MHz   |---19                                       
                       11---|         |---18                                       
                       12---|         |---17                                       
                       13---|         |---16                                       
                       14---|         |---15                                                                                
                             ---------
                                                                              */
//============================================================================//
//             头文件和变量定义                                               //
//============================================================================//
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
//#include <avr/eeprom.h>
#include <avr/pgmspace.h>
//#include <avr/wdt.h>
#include <avr/sleep.h>
#include <avr/delay.h>
#include <inttypes.h>
#include "music.h"
#include "music_data.h"

#define music_out PC4

volatile byte tone_dl,play_flag;
volatile word nop_time;
byte yinyue,jiepai,play_num,play_tmp,j;
word i;
const byte (*p)[2];	//指向flash存储区的二维数组指针
//============================================================================//
//             函数名称:timer0_ovf_isr()                                     //
//             功    能:定时器0中断服务程序,对节拍等提供时基                //
//             参    数:无                                                   //
//             影响变量:tone_dl                                              // 
//             创    建:2005-3-8  by  QQQ                                    //
//             修    改:                                                     //
//============================================================================//
//#pragma interrupt_handler timer0_ovf_isr:10
//void timer0_ovf_isr(void)

SIGNAL(SIG_OVERFLOW0)
{
 TCNT0=0xb7;
 tone_dl++;
 nop_time++;
}
//==============================================================================
//             函数名称:timer1_compa_isr()
//             功    能:定时器1中断服务程序,翻转PC.0口的状态
//             参    数:无
//             影响变量:无
//             创    建:2005-3-8  by  QQQ
//             修    改:
//==============================================================================
//#pragma interrupt_handler timer1_compa_isr:7
//void timer1_compa_isr(void)

SIGNAL(SIG_OUTPUT_COMPARE1A)
{
 PORTC^=_BV(music_out);
}


//==============================================================================
//             函数名称:init_device() 
//             功    能:初始化各寄存器及I/O口
//             参    数:无 
//             影响变量:无
//             创    建:2005-3-8  by  QQQ
//             修    改:
//==============================================================================
void init_device(void)
{
 cli();
 //port initialized
 DDRB=0xFF;PORTB=0xFF;
 DDRC=0xFF;PORTC=0xef;
 DDRD=0xFF;PORTD=0xFF;
 
 //timer0 initialized
 TCCR0A=0x00;
 TCCR0B=0X00;
 TCNT0=0xb7;//定时时长18mS,则1/4拍为 2*5*18ms~~187ms。1M
 TIMSK0=0x01;//开溢出中断。

 //timer1 initialized
 TCCR1B=0x00;
 TCNT1H=0x00;
 TCNT1L=0x00;
 OCR1AH=0xFF;
 OCR1AL=0xFF;
 TCCR1A=0x00;
 TIMSK1=0X02;

 //
 //	MCUCR=0x00;
 //EICRA=0X00;	//外部中断
 //EIMSK=0x03;
 
 set_sleep_mode(SLEEP_MODE_IDLE);
}
//==============================================================================
//             函数名称:get_music_num()
//             功    能:通过曲目值让指针指向对应的歌曲,实现曲目查找
//             参    数:无
//             影响变量:*p
//             创    建:2005-3-9  by  QQQ
//             修    改:
//==============================================================================
void get_music_num(void)
{
 switch(play_num)
   {
    case 0 : p=music_dt0;break;
    case 1 : p=music_dt1;break;
    case 2 : p=music_dt2;break;
    case 3 : p=music_dt3;break;
    case 4 : p=music_dt4;break;
    case 5 : p=music_dt5;break;
    case 6 : p=music_dt6;break;
    case 7 : p=music_dt7;break;
   }
}
//==============================================================================
//             函数名称:sound()
//             功    能:将得到的数据转化为声音信号
//             参    数:无
//             影响变量:yinyue,yinfu,jiepai,num
//             创    建:2005-3-9  by  QQQ
//             修    改:2005-3-14 by  QQQ
//============================================================================== 
void sound(void)
{
 yinyue=pgm_read_byte(p);
 if(yinyue != 0)
      {
       OCR1A=pgm_read_word(tone_frq+yinyue);//取得音符对应的频率值
	   TCCR1B=0x09;	//+TCCR1A 0X00,设置为CTC,时钟无分频。
	   TCNT1=0x00;
	  }
 else TCCR1B=0x00;//若音乐为零,表示休止符
 
 while((tone_dl<jiepai)&&(play_num==play_tmp)&&(play_flag!=0));
 if(play_flag==0)
	 {  
	//   MCUCR|=0xA0;
	   PORTC=0xef;
	   j=0x01;//等待标志
       sleep_mode();
	//   MCUCR=0x00;
	   TCCR0A=0X00;
	   TCCR0B=0x04;
	   TCCR1B=0x09;
	  }
 while((tone_dl<jiepai)&&(play_num==play_tmp)&&(play_flag!=0));
 tone_dl=0;
 p++;
 jiepai=pgm_read_byte(*p+1);
}
//==============================================================================
//             函数名称:main()
//             创    建:2005-3-9  by  QQQ
//             修    改:2005-3-14 by  QQQ
//==============================================================================
int main(void)
{

 init_device();
 nop_time=0;
 play_num=0;
 play_flag=0x01;
 sei();//开中断
 while(1)
 {
 start:
   get_music_num();
   play_tmp=play_num;
   if(play_flag==0x01)
     {TCCR0B=0x04;TCCR1B=0x09;}
   jiepai=pgm_read_byte(*p+1);//取得第一个节拍
   while(jiepai!=0)//若为零,表示结束
   {
	if(play_tmp!=play_num)//播放与用户指定乐曲不同
	   {TCCR0B=0x00;
	    TCCR1B=0x00;
		goto start;}	//结束当前播放的曲子
    sound();
	}
   TCCR0B=0x00;TCCR1B=0x00;
   if(play_num<7)play_num++;
   else play_num=0;   
   
 }

}

/******************************************************************************/
/*                                 END                                        */
/******************************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -