《ARM微控制器与嵌入式系统》慕课---实验四 PWM实验

任务:使用PWM驱动蜂鸣器来播放简单音乐

分析:声音的特性可由三个要素来描述,即响度、音调和音色。音调主要与声波的频率有关

  音调 频率
L1 261.6
L2 293.7
L3 329.6
L4 349.2
L5 392
L6 440
L7 493.9
M1 523.3
M2 587.3
M3 659.3
M4 698.5
M5 784
M6 880
M7 987.8
H1 1045.5
H2 1174.7
H3 1318.5
H4 1396.9
H5 1568
H6 1760
H7 1975.5

两只老虎简谱:

《ARM微控制器与嵌入式系统》慕课---实验四 PWM实验_第1张图片

如果数字下方有点,代表低音,如果数字上方有点,代表高音,否则默认中音。

音长:一般一节为4拍,如果相邻数字下面有连线,说明两个一起是一拍

实现代码片段如下:

#define PWM0_CLK_FREQ 164*1000 //20.97M / 128

#define L1 M1*2
#define L2 M2*2
#define L3 M3*2
#define L4 M4*2
#define L5 M5*2
#define L6 M6*2
#define L7 M7*2

#define M1 (PWM0_CLK_FREQ/523)
#define M2 (PWM0_CLK_FREQ/587)
#define M3 (PWM0_CLK_FREQ/659)
#define M4 (PWM0_CLK_FREQ/698)
#define M5 (PWM0_CLK_FREQ/784)
#define M6 (PWM0_CLK_FREQ/880)
#define M7 (PWM0_CLK_FREQ/988)

#define H1 M1/2
#define H2 M2/2
#define H3 M3/2
#define H4 M4/2
#define H5 M5/2
#define H6 M6/2
#define H7 M7/2

#define NN 0

static unsigned int During;
static unsigned int num;

struct Music_data {
	unsigned int freq;
	unsigned int During_time;
};

//两只老虎乐谱
static struct Music_data md[] = {
		{M1, 0x2},
		{M2, 0x2},
		{M3, 0x2},
		{M1, 0x2},

		{M1, 0x2},
		{M2, 0x2},
		{M3, 0x2},
		{M1, 0x2},

		{M3, 0x2},
		{M4, 0x2},
		{M5, 0x4},
		
		{M3, 0x2},
		{M4, 0x2},
		{M5, 0x4},

		{M5, 0x1},
		{M6, 0x1},
		{M5, 0x1},
		{M4, 0x1},
		{M3, 0x2},
		{M1, 0x2},

		{M5, 0x1},
		{M6, 0x1},
		{M5, 0x1},
		{M4, 0x1},
		{M3, 0x2},
		{M1, 0x2},

		{M1, 0x2},
		{L5, 0x2},
		{M1, 0x4},

		{M1, 0x2},
		{L5, 0x2},
		{M1, 0x4},

		{0xff, 0x0},
};

void TPM0_init(void)
{
	SIM_SOPT2 |= (1 << 24); //select TPM Clock source
	SIM_SCGC5 |= (1 << 11); //enable portC Clock
	SIM_SCGC6 |= (1 << 24); //enable TPM0 Clock

	PORTC_PCR8 |= (3 << 8); //conifg portc_8 as TPM0_ch4
	
	TPM0_SC |= (1 << 3) | 0x7; //CPWMS and CMOD and PS
	TPM0_CNT = 0;
	TPM0_MOD = 0; // period =  (MOD + 0x0001)
	TPM0_C4SC |= (1 << 5) | (1 << 3); //MSnB:MSnA ELSnB:ELSnA EPWM
	TPM0_C4V = 0; //duty cycle
}

void TPM0_set(int period)
{
	TPM0_MOD = period;
	TPM0_C4V = period / 2;
}

void systick_init(void)
{
	SYST_RVR = 2621250; //1/8s
	SYST_CVR = 0;
	SYST_CSR |= 0x7; 
}

void __enable_irq(void)
{
	asm("CPSIE i");
}

void SysTick_Handler(void)
{
	int i;

	if(During == 0)
	{
		if(md[num].freq == 0xff)
		{
			num = 0;
		}
		TPM0_set(md[num].freq);
		During = md[num].During_time;
		num++;
	}
	During--;
	i = SYST_CSR;
}

int main(void)
{
	int counter = 0;
	
	TPM0_init();
	systick_init();
	__enable_irq();
	for(;;) {	   
	   	counter++;
	}
	
	return 0;
}

至此,该实验就玩完啦,别忘记点赞哦,欢迎大家留言讨论,谢谢!

你可能感兴趣的:(ARM,PWM,播放音乐,BLAZAR-β,Cortex-M0,KL26z256)