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

📄 mymusic.c

📁 普通单片机产生MIDI音乐的程序,使用任何无源蜂鸣器,利用单片机的PWM输出功能,可以实现你需要的任何音乐输出,该程序作为模块已经在产品上大量使用,性能稳定
💻 C
📖 第 1 页 / 共 2 页
字号:
#endif
void abort(void);
#ifdef __cplusplus
}
#endif

void main(void)
{
uchar lst1;
	nop();
	nop();
main_1:
	ini_ram();	//RAM初始化,主要写入0外的数据
	ini_pp();	//端口及外围功能初始化
	lst1=200;
	for(;;) 
	{
main_2:
		emi_p();
main_6:
		RESET_WATCHDOG(); 
		if (!mflg10ms) goto main_2;
		mflg10ms=0;
		lst1++;

		if (!buzstp)
		{
			if (lst1>=200)
			{
//				btMusicSet=MFSELF;
//				music_sel_ts_flg=1;
				btMusicSet=8;
				buzstp=1;
			}
		}
		else lst1=0;

		Music_Select();
		Musicing();
	}
}





//------******---START---******---音---******---乐---******---程---******---序---******---START---******------//
//音乐选择
//如果选择特殊音乐,则设置btMusicSet后,需要同时设置music_sel_ts_flg=1
void Music_Select(void)
{
	if (btMusicSet==0) return;
	if (!music_sel_ts_flg) goto Music_sel2;
	switch(btMusicSet)
	{
		case MF2591:	
			music_ptr=mf2591;
			music_yinf_nu=(sizeof(mf2591))/2;
			break;
		case MF2165:	
			music_ptr=mf2165;
			music_yinf_nu=(sizeof(mf2165))/2;
			break;
		case MF2220:
			music_ptr=mf2220;
			music_yinf_nu=(sizeof(mf2220))/2;
			break;
		case MF2294:	
			music_ptr=mf2294;
			music_yinf_nu=(sizeof(mf2294))/2;
			break;
		case MF2370:
			music_ptr=mf2370;
			music_yinf_nu=(sizeof(mf2370))/2;
			break;
		case MF2427:
			music_ptr=mf2427;
			music_yinf_nu=(sizeof(mf2427))/2;
			break;
		case MF2525:
			music_ptr=mf2525;
			music_yinf_nu=(sizeof(mf2525))/2;
			break;
		case MF2564:
			music_ptr=mf2564;
			music_yinf_nu=(sizeof(mf2564))/2;
			break;
		case MFPWON:
			music_ptr=openbuz;
			music_yinf_nu=(sizeof(openbuz))/2;
			break;
		case MFSTRT:
			music_ptr=startbuz;
			music_yinf_nu=(sizeof(startbuz))/2;
			break;
		case MFPASU:
			music_ptr=pausebuz;
			music_yinf_nu=(sizeof(pausebuz))/2;
			break;
		case MFERRO:
			music_ptr=errbuz;
			music_yinf_nu=(sizeof(errbuz))/2;
			break;
		case MFNWTR:
			music_ptr=nwbuz;
			music_yinf_nu=(sizeof(nwbuz))/2;
			break;
		case MFZHQI:
			music_ptr=lastbuz;
			music_yinf_nu=(sizeof(lastbuz))/2;
			break;
		case MFSELF:
			music_ptr=testbuz;
			music_yinf_nu=(sizeof(testbuz))/2;
			break;
		case MFEND:
			music_ptr=endbuz;
			music_yinf_nu=(sizeof(endbuz))/2;
			break;
		case MFPOFF:
			music_ptr=closebuz;
			music_yinf_nu=(sizeof(closebuz))/2;
			break;
		case MF2304:
			music_ptr=lkeybuz;
			music_yinf_nu=(sizeof(lkeybuz))/2;
			break;
		default:
			break;
	}

	goto Music_sel1;
Music_sel2:
	switch (btMusicSet)
	{
		case 1:
			music_ptr=mybonie;
			music_yinf_nu=(sizeof(mybonie))/2;
			break;
		case 2:
			music_ptr=mysunshine;
			music_yinf_nu=(sizeof(mysunshine))/2;
			break;
		case 3:
			music_ptr=jingle_bell1;
			music_yinf_nu=(sizeof(jingle_bell1))/2;
			break;
		case 4:
			music_ptr=jingle_bell2;
			music_yinf_nu=(sizeof(jingle_bell2))/2;
			break;
		case 5:
			music_ptr=blue_danube;
			music_yinf_nu=(sizeof(blue_danube))/2;
			break;
		case 6:
			music_ptr=happy_new_year;
			music_yinf_nu=(sizeof(happy_new_year))/2;
			break;
		case 7:
			music_ptr=good_night;
			music_yinf_nu=(sizeof(good_night))/2;
			break;
		case 8:
			music_ptr=small_boat;
			music_yinf_nu=(sizeof(small_boat))/2;
			break;
		case 9:
			music_ptr=happy_new_year;
			music_yinf_nu=(sizeof(happy_new_year))/2;
			break;
		case 10:
			music_ptr=happy_new_year;
			music_yinf_nu=(sizeof(happy_new_year))/2;
			break;
		default:
			break;
	}
Music_sel1:
	musicruning=1;
	btMusicSet=0;
	music_1st_flg=0;
	Buzzeron();

}

//音乐输出
void Musicing(void)
{
	if (!musicruning)
	{
		jiepai_kx=0;	//停止输出
		buzstp=0;
		return;
	}
	if (music_pai_ct==0)
	{//当前拍输出完毕
		if (music_yinf_nu!=0) 
		{//下一个音符
			music_yinf_nu--;
			music_pai_ct=*music_ptr;	//该音符输出长度
			music_pai_ct&=0x1f;
			if (!music_sel_ts_flg) music_pai_ct*=4;
			music_ptr++;
			music_peri=*(music_ptr);
			if (music_peri==xz) 
			{
				music_peri=*(music_ptr-2);
				jiepai_kx=0;
			}
			else jiepai_kx=1;
			music_ptr++;

			#ifdef PWM8B_CM
			if (music_sel_ts_flg)
			{
				music_peri=pwm8b_ts[music_peri];
				pwm_period=music_peri;
				pwm_duty=music_peri/2;
			}
			else
			{
				music_peri=pwm8b_mc[music_peri];
				pwm_period=music_peri;
				pwm_duty=music_peri/2;
			}
			#endif

			#ifdef PWM10B_CM
			ls1=pwm10b_mc[music_peri*2];
			ls2=pwm10b_mc[music_peri*2+1];
			pwm_period_h=ls1;
			pwm_period_l=ls2;
			pwm_duty_h=ls1/2;
			pwm_duty_l=ls2/2;
			#endif

			#ifdef PWM16B_CM
			ls1=pwm16b_mc[music_peri*2];
			ls2=pwm16b_mc[music_peri*2+1];
			pwm_period_h=ls1;
			pwm_period_l=ls2;
			pwm_duty_h=ls1/2;
			pwm_duty_l=ls2/2;
			#endif
		}
		else
		{//音乐输出完毕
			musicruning=0;
			buzstp=0;
			jiepai_kx=0;
			music_sel_ts_flg=0;
			return;
		}
	}
	if (music_pai_ct!=0)	
	{
		music_pai_ct--;
	}
}



//------******---END---******---音---******---乐---******---程---******---序---******---END---******------//


void pPIT_ISR_P (void)
{
	//1毫秒
	TW.TSRW.BYTE&=0x7f;
	TW.TCNT=57536;		//1毫秒
	jsq10ms++;
	if (jsq10ms>=10)
	{
		jsq10ms=0;
		mflg10ms=1;
//		lsct++;
	}
}






//----------------------------------------------------------------------//
//内部RAM初始化程序,														//
//从00~1ff全部清0
//----------------------------------------------------------------------//
void ini_ram(void)
{
uint *p;
uint i;
	p=&STAFLGU;
	for (i=0;i<400;i++)
	{
		*p=0;
		p++;
	}
}



//----------------------------------------------------------------------//
//内部外围功能初始化--为抗干扰, 再处理
//----------------------------------------------------------------------//
void emi_p(void)
{
	portcr1 =0x67;	//0b01100111;	//方向
	portcr2 =0x07;	//0b00000111;	//方向
	portcr5 =0xff;	//0b11111111;	//方向
	portcr7 =0x59;	//0b01011001;	//方向
	portcr8 =0x0f;	//0b00001111;	//方向
}


//----------------------------------------------------------------------//
void ini_pp(void)
{
	portmr1 =0x08;	//0b00001000;	// TXD2
	PORT1 =0x98;	//0b10011000;
	portur1=0x00;	//0b00000000;

	PORT2 =0x00;	//0b00000000;

	portmr5 =0x00;	//0b00000000;	//为普通IO
	PORT5 =0xc0;	//0b11000000;
	portur5=0x00;	//0b00000000;

	PORT7 =0x16;	//0b00010110;

	PORT8 =0x07;	//0b00000111;

	emi_p();

//TIMERV初始化
//计数模式,水位处理
//	TV.TCNTV=0;
//	TV.TCRV0.BYTE=0x05;	//0b00000101	//外部脉冲--计数模式


//TIMERV初始化
//输出2.5K频率 驱动蜂鸣器
	TV.TCNTV=0;
	TV.TCRV0.BYTE=0x0b;	//0b00001011;	//与A匹配 计数器清0  输入脉冲为1/64振荡频率
//	TV.TCRV1.BIT.ICKS=1;
	TV.TCORA=0xFF;			//2.5K比较常数
	TV.TCORB=0xFF;			//在50%时与B比较匹配, 则获得了50%占空比

/*
//TIMERV初始化
//定时1毫秒中断
	TV.TCNTV=0;
	TV.TCRV0.BYTE=0x4a;	//01001010 与A匹配中断, 且清0
	TV.TCSRV.BYTE=0x10;	//00010000
	TV.TCRV1.BYTE=0xe3;	//11100011
	TV.TCORA=250;
*/


//TIMERW初始化
//定时1毫秒,用于显示扫描和定时计时
	TW.GRA=0xffff;
	TW.GRB=0xffff;
	TW.GRC=0xffff;
	TW.GRD=0xffff;
	TW.TCNT=57536;	//1毫秒						//25536;		//5毫秒
	TW.TIOR0.BYTE=0x88;	//0b10001000;
	TW.TIOR1.BYTE=0x88;	//0b10001000;
	TW.TMRW.BYTE=0xc8;	//0b11001000;
	TW.TCRW.BYTE=0x80;	//0b10000000;
	TW.TSRW.BYTE=0x70;	//0b01110000
	TW.TIERW.BYTE=0xf0;	//0b11110000;
	TW.TMRW.BIT.CTS=1;	//START

/*
//TIMERW初始化
//外部脉冲测水位
	TW.GRA=0xffff;
	TW.GRB=0xffff;
	TW.GRC=0xffff;
	TW.GRD=0xffff;
	TW.TCNT=0;	//
	TW.TIOR0.BYTE=0x88;	//10001000;
	TW.TIOR1.BYTE=0x88;	//0b10001000;
	TW.TMRW.BYTE=0xc8;	//0b11001000;
	TW.TCRW.BYTE=0x40;	//0b01000000;	//外部脉冲
	TW.TSRW.BYTE=0x70;	//0b01110000
	TW.TIERW.BYTE=0x70;	//0b01110000;
	TW.TMRW.BIT.CTS=1;	//START
*/	

//ADC初始化
	AD.ADCSR.BYTE=0x03;	//00000011   单次模式 4通道
/*
//SCI--2 初始化
//9600BPS 1个起始  1个停止 无校验
	SCI3_2.SCR3.BYTE=0x00;
	SCI3_2.SMR.BYTE=0x00;	//00000000  1 开始  1结束  8数据 内部1:1 无校验
	SCI3_2.BRR=25;		//9600BPS
	delayus(120);
	SCI3_2.SSR.BYTE=(SCI3_2.SSR.BYTE|0x80)&0x80;
	SCI3_2.SCR3.BYTE=0x50;	//接收允许  发送禁止 接收中断允许  发送中断禁止
*/
//WDT初始化
//WDT时间为120毫秒
	WDT.TMWD.BYTE  =0x0e;	//0b00001110;	//时间常数 
	WDT.TCSRWD.BIT.B4WI=0;
	WDT.TCSRWD.BIT.TCSRWE=1;
	WDT.TCSRWD.BIT.WDON=1;		//WDT开启
	WDT.TCSRWD.BIT.TCSRWE=0;
	WDT.TCSRWD.BIT.B4WI=0;


//中断初始化
//  IRQ0中断  其它关闭
//	IENR1.BYTE=0x01;	//0b00000001;	IRQ3 disable  IRQ0 ENABLE
//	CCR.BIT.I=0;		//总中断允许
	set_imask_ccr(0);
}

⌨️ 快捷键说明

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