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

📄 yinxiang.c

📁 单片机制作电子音响的原代码.单片机初学者必看.
💻 C
字号:
//-----------------------------------------------------------------------------
// 版权归新华龙电子公司所有
//-----------------------------------------------------------------------------
//
//文件名:	YinXiang.c
//
//编写人:	LC
//
//编写时间:2005/03/10
//
//目标器件: C8051F02x
//
//编译工具: Silicon Laboratories IDE
//
//程序说明:	此程序将某段音乐用特定的频率播放出来

//P54--MUSIC
//------------------------------------------------------------------------------------
// 头文件包含
//------------------------------------------------------------------------------------
#include <C8051F020.h>
#include <ctype.h>

//------------------------------------------------------------------------------------
// Global CONSTANTS
//------------------------------------------------------------------------------------
#pragma ot(0)
#define uint  unsigned int
#define uchar unsigned char
#define OSFREQ 6000000l                 /*所使用的晶振频率*/


/**************音符频率表****************/
uint code notefreq[]={ 	523, 587, 659, 698, 784, 880, 988,
						1047,1175,1319,1396,1568,1760,1976,
						2093,2349,2637,2793,3136,3520,3961};
//uint code timreg[]={ 	65058, 65110, 65157, 65178, 65217, 65252, 65283,
//						65297,65323,65347,65357,65377,65394,65410,
//						65417,65430,65441,65447,65456,65465,65473};
/*************音名***************/

uchar code notename[]={	'c','d','e','f','g','a','b',
						'1','2','3','4','5','6','7',
						'C','D','E','F','G','A','B',0};

/*************半音频率表*****************/
uint code halfnotefreq[]={ 	554, 622, 740, 831, 933,
							1109,1245,1480,1161,1865,
							2218,2489,2960,3322,3729};
//uint code halftimreg[]={ 	65085, 65134, 65198, 65235, 65268,
//							65311,65335,65367,65321,65402,
//							65423,65436,65452,65461,65469};
/*************音名***************/
uchar code halfnotename[]={	'c','d','f','g','a',
							'1','2','4','5','6',
							'C','D','F','G','A',0};

//sbit  BEEP_PWR=P1^0;
uchar  FreqSandH,FreqSandL;  /*产生方波的定时器的初值*/
uchar timer1cnt;             /*定时器延时计数        */
uchar timer1cntflg;          /*定时器定时完成标志    */


/***************************************************************************************
函数名称:	void timer0int() interrupt 1
功能描述:	定时器0中断用来产生方波
输入:		无
输出:		无
全局变量:	TH0,TL0,P5
调用模块:	无
***************************************************************************************/
void timer0int () interrupt 1
{
	TH0=FreqSandH;		
	TL0=FreqSandL;
	P5 = P5 ^ 0x10;		// change state of P5.4
}


/***************************************************************************************
函数名称:	void delay(uchar time)
功能描述:	延时
输入:		uchar time:	延时时间长度
输出:		无
全局变量:	无
调用模块:	无
***************************************************************************************/
void delay(uchar time)
{
	uchar i;
	uint j;
	for(i=0;i<time;i++)
    	for(j=0;j<0x900;j++);
}

/***************************************************************************************
函数名称:	void sound(uint freq)
功能描述:	
输入:		uint freq:	频率值
输出:		无
全局变量:	OSFFEQ,FreqSandH,FreqSandL,TR0,ET0
调用模块:	无
***************************************************************************************/
void Sound(uint freq)
{
	uint timreg;
	timreg=65536l-(OSFREQ/(24l*freq));
	FreqSandH=timreg/256;
	FreqSandL=timreg&0x00ff;
	TR0=1;
	ET0=1;
}


/***************************************************************************************
函数名称:	void Soundoff(void)
功能描述:	停止发声
输入:		无
输出:		无
全局变量:	TR0,ET0,P5
调用模块:	无
***************************************************************************************/
void SoundOff(void)
{
	TR0=0;		  
	ET0=0;
	//P5 = P5 & 0xef;
	P5 = P5 | 0x10;
}

/***************************************************************************************
函数名称:	void GetFreq(uchar ch, uchar flag)
功能描述:	依据音名取对应的频率
输入:		uchar ch:	音名
			uchar flg:	全音/半音选择
输出:		返回频率值
全局变量:	halfnotename[],notename[],halfnotefreq[],notefreq[]
调用模块:	无
***************************************************************************************/
uint GetFreq(uchar ch,uchar flg)
{
	uchar * pn,i=0;
	uint * pf;
	if(flg)   {pn=halfnotename; pf=halfnotefreq;}
	else      {pn=notename;     pf=notefreq;}
	while(1)
    {
		if(pn[i]==0)     return 0;
     	if(ch==pn[i])  return pf[i];
     	i++;
    }
}

/***************************************************************************************
函数名称:	void PORT_Init(void)
功能描述:	初始化I/O
输入:		无
输出:		无
全局变量:	XBR2,P74OUT
调用模块:	无
***************************************************************************************/
void PORT_Init (void)
{
   XBR2    = 0x40;      /*使能交叉开关和弱上拉*/
   P74OUT |= 0xff;      /*使能P6,P7推挽输出*/
}

void Play(char * str)
{
	uchar i=0,ch,halfflg=0;
	uchar lasttime;
	uint freq;
	/*无效看门狗*/
   	WDTCN = 0xde;
   	WDTCN = 0xad;
   	PORT_Init ();
	OSCICN=0x14;		/*使用内部晶振*/
	while(1)
    {
		for(;;i++)
        {
			ch=str[i];   /*允许曲谱用空格符 '|'符,换行回车等分隔以便阅读*/
          	if((ch==' ')||(ch=='|')||(ch=='\r')||(ch=='\n')) {i++;continue;}
          	if(!ch) {SoundOff(); return;}         /*乐曲结束则播放完毕*/
          	if(ch=='#')  {halfflg=1;  continue;}  /*半音标志*/
          	if(isdigit(ch)||isalpha(ch))
            {
				freq=GetFreq(ch,halfflg);		/*从音名获取频率*/
               	lasttime=16;
               	break;
            }
          	else {halfflg=0;  continue;}
        }
      	i++;
      	ch=str[i];       /*从下一个符号获取额外音长符号*/
      	while(1)
        {
			if(!ch) break;
          	if(isdigit(ch)||isalpha(ch)) break;   /*非音长符号则下次处理*/
          	if(ch=='-') lasttime+=8;              /*额外延时一拍*/
          	if(ch=='.') lasttime+=4;              /*额外延时半拍*/
          	if(ch=='_') lasttime/=2;              /*下划线相当于简谱中音名下面的下划线,延时减半*/
          	if(ch=='=') lasttime/=4;              /*双下划线相当于简谱中音名下面的双下划线,延时减为1/4*/
          	i++;
          	ch=str[i];
        }
     	if(freq!=0) Sound(freq);             	/*发声*/
     	else        SoundOff();
     	delay(lasttime);                      	/*延时*/
     	SoundOff();
     	delay(1);                    			/*两个引之间的间歇*/
    }
}

/*
编谱说明,低音(简谱中数字下面有一个点的)1234567对应的为小写cdefgab
中音(简谱中数字上下都没有点的)1234567对应的也为1234567
高音(简谱中数字上面有一个点的)1234567对应的为大写CDEFGAB
对于降音符b或声音符#一律用#+合适的音名例如#5
一个音符本身为一拍,加下划线后为半拍加等号为1/4拍 如:65_ 4= 则音6为一拍,音5为半拍,音4为1/4拍
下划线或等号连续书写则音长连续变短
音符后加-或.表示延长。‘-’延长一拍‘.’延长半拍多加则延长连续增加
*/

void main(void)
{
	//uint i;
	TMOD=0x11; ET0=1;  EA=1;
	delay(10);
	//Play("1_1_5_5_6_6_5   4_4_3_3_2_2_1  5_5_4_4_3_3_2 5_5_4_4_3_3_21_1_5_5_6_6_5  4_4_3_3_2_2_1"); /*满天都是小星星*/
	//Play("1_2_3_1_  1_2_3_1_  3_4_5 3_4_5  5=6=5=4=3_1_ 5=6=5=4=3_1_ 2_g_12_g_1");    /*两只老虎*/
	//Play("a-a1-a2--a-b1b13-2a--a--   a-33-12--a-b1b13-21--1-- 5-55432--a-b1-12123--3-- 1-1_1_1235--4-32-b3-2a--a--  a-66565--4-34-56543--3--1-1_1_1235--4-32-b3-2a--a--"); /*山楂树*/
	//Play("5._3=2_1_5-12_3_g-5.3_23_5_1a_3_2-356.5_352._3=2_1_a32_21_a1g05.3_6562_3_50"); /*学习雷锋好榜样*/
	//Play("C-53.2_1530C-53.2_1650 5_C6_5_C05_C6_5_6_0_3_C.6_53C.6_C0C53_6_5_3_2.1_30_5_C56_C_6_5_33_1_6-60C._C=5_5_2._3=5_5_6.5_6DC6_5_C6_5_33_5_C-");  /*团结就是力量*/
	//Play("3- 2_3_4_3 3- 2_3_4_3 3- 4- 3_4_5_4 4- 3-2-  3- 2_3_4_3 3- 2_3_4_3 3-4- 3_4_5_4 4- 3-2");/*许巍-星空前奏*/
	//Play("543 3_2_1_2_30 g53 3_2_1_2_30 a65 4_3_2_3_4 1 b a g");/*许巍-时光*/
	Play("g_g_ag  1b- g_g_ag  21-  g_g_53  1ba 004_4_  312  1--1  ");	/*生日快乐*/
	SoundOff();
	while(1);
}


⌨️ 快捷键说明

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