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

📄 main.c

📁 这是一个用单片机来演奏音乐的程序
💻 C
字号:
/*
	音乐测试程序
	main.c
	硬件:CA-M8
	时钟:外部4MHz
	
	芯艺 2005-01-09
*/

#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include <avr/delay.h>

#define uchar unsigned char
#define uint unsigned int

  
const uint g_aMusicTab[] ={0,7633,7220,6802,6430,6060,5730,5405,5102,4819,4545,4291,4048,
							3824,3610,3460,3215,3034,2865,2702,2551,2406,2272,2145,2024,
							1912,1803,1702,1606,1517,1431,1351,1275,1204,1136,1072,1012};

//万水千山总是情
const uchar g_aMusic1[] PROGMEM = {	17,04,18,04,20,06,20,02,22,04,20,04,17,12,15,04,
									13,06,17,02,15,04,13,04,10,12,10,04,8,8,13,04 ,
									15,04,17,04,20,04,22,04,17,04,15,15,15,04,00,04 ,
									17,04,18,04,20,06,20,02,22,04,20,04,17,12,15,04,
									13,06,17,02,15,04,13,04,10,12,10,04,8,8,13,06 ,
									17,02,15,06,13,02,13,04,10,04,13,15,13,8,17,04 ,
									20,04,22,12,25,10,22,04,18,04,20,06,22,02,20,12 ,
									17,04,20,8,17,04,20,04,22,12,25,04,25,04,22,04 ,
									20,04,17,04,15,15,15, 8,17,04,18,04,20,06,20,02 ,
									22,04,20,04,17,12,15,04,13,06,17,02,15,04,13,04, 
									10,12,10,04,8,8,13,04,17,04,15,06,13,02,10,04,
									12,04,13,15,13,15,00,00};
									
									
const uchar g_aMusic2[] PROGMEM = { 20,02,00,01,20,01,22,04,20,04,25,04,24,04,00,04,
									20,02,00,01,20,01,22,04,20,04,27,04,25,04,00,04,
									20,02,00,01,20,01,32,04,29,04,25,04,24,04,22,04,
									30,02,00,01,30,01,29,04,25,04,27,04,25,04,00,04,
									20,02,00,01,20,01,22,04,20,04,25,04,24,04,00,04,
									20,02,00,01,20,01,22,04,20,04,27,04,25,04,00,04,
									20,02,00,01,20,01,32,04,29,04,25,04,24,04,22,04,
									30,02,00,01,30,01,29,04,25,04,27,04,25,04,00,04,
									00,00};
void DelayMs(uint t)
{
	uint i;
	for(i=0;i<t;i++)
		_delay_loop_2(250*4);
}

void PwmInit(void)
{
	PORTB&=~_BV(PB2);
	DDRB|=0X04;	//输出引脚允许

	//PWM相关定时器中断禁止
	TIMSK=0;//_BV(TICIE1)|_BV(OCIE1A)|_BV(OCIE1B)|_BV(TOIE1);
	
	//	可调相位、可调频率 PWM模式
	//	OCR1A为上限值,OC1B(PB2)输出PWM
	//	向上计数过程中比较匹配清零,向下计数过程中比较匹配时置位
	//	时钟源:4MHz/1  PWM频率:4MHz/( 1 * X ) = 可调
	TCCR1A=_BV(COM1B1)|_BV(WGM10);
	TCCR1B=_BV(WGM13)|_BV(CS10);
	
    OCR1A=0XFFFF;	//上限值设置
    OCR1B=0X0000;   //输出初始化为低电平
	
	TCNT1=0;
}

void SetPWMFrq(uint val)
{
	OCR1A=val;
	OCR1B=val/2;
}

void Play(void)
{
	int i=0;
	uchar msc[2];
	while(1)
	{
		msc[0]=pgm_read_byte(g_aMusic2+i++);
		msc[1]=pgm_read_byte(g_aMusic2+i++);
		if(msc[1]==0)
			break;
		if(msc[0]==0)
		{
			
			DelayMs(187*msc[1]);
			continue;
		}
		SetPWMFrq(g_aMusicTab[msc[0]]);
		DelayMs(187*msc[1]);
	}
	SetPWMFrq(0);
}

int main(void)
{
	PORTD|=_BV(PD2);	
	PwmInit();
	
	while(1)
	{
		if((PIND&_BV(PD2))==0)
		  Play();
		else
		  DelayMs(10);
	}		
}

⌨️ 快捷键说明

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