MCU控制蜂鸣器演奏音乐小程序

算法&编程学院 发表于 2018-04-20 09:17:00 收藏 已收藏
赞(0) •  评论(0

MCU控制蜂鸣器演奏音乐小程序

算法&编程学院 发表于 2018-04-20 09:17:00

程序功能:MCU控制蜂鸣器演奏歌曲《祝你平安》

----------------------------------------------

拨码开关设置:将BUZZER位拨至ON,其余位拨至OFF

测试说明:聆听蜂鸣器“唱出”的乐曲

既然是演奏乐曲对于一个音符应该包括两个部分

一是声调 二是持续时间,在这个程序中声调是用简单的

延时-电平翻转来实现的,改变了延时的时间就改变了

声调,而时间是通过计数比较来实现的,当计数值相等时

就跳出循环演奏下一个音符。

MCU控制蜂鸣器演奏音乐小程序

*********************************************/

#include 《msp430x14x.h》

typedef unsigned char uchar;

#include “music.h”

#define Buzzer BIT7

#define Buzzer_Port P6OUT

#define Buzzer_DIR P6DIR

uchar counter;

void Play_Song(void);

/***************主函数****************/

void main(void)

{

uchar i;

/*下面六行程序关闭所有的IO口*/

P1DIR = 0XFF;P1OUT = 0XFF;

P2DIR = 0XFF;P2OUT = 0XFF;

P3DIR = 0XFF;P3OUT = 0XFF;

P4DIR = 0XFF;P4OUT = 0XFF;

P5DIR = 0XFF;P5OUT = 0XFF;

P6DIR = 0XFF;P6OUT = 0XFF;

P6DIR |= BIT2;P6OUT |= BIT2; //关闭电平转换

WDTCTL = WDTPW + WDTHOLD; //关闭看门狗

/*------选择系统主时钟为8MHz-------*/

BCSCTL1 &= ~XT2OFF; // 打开XT2高频晶体振荡器

do

{

IFG1 &= ~OFIFG; //清除晶振失败标志

for (i = 0xFF; i 》 0; i--); // 等待8MHz晶体起振

}

while ((IFG1 & OFIFG)); // 晶振失效标志仍然存在?

BCSCTL2 |= SELM_2 + SELS; //主时钟和从时钟都选择高频晶振

//设置定时器A每10ms中断一次

CCTL0 = CCIE;

CCR0 = 10000;//改变这个值就改变了演奏的速度

TACTL |= TASSEL_2 + ID_3;

//设置控制蜂鸣器的IO方向为输出

Buzzer_DIR |= Buzzer;

//打开全局中断

_EINT();

//循环演奏歌曲

while(1)

{

Play_Song();

}

}

/*******************************************

函数名称:TimerA_ISR

功 能:定时器A的中断服务函数

参 数:无

返回值 :无

********************************************/

#pragma vector = TIMERA0_VECTOR

__interrupt void TimerA_ISR(void)

{

counter++;

}

/*******************************************

函数名称:Delay_Nms

功 能:延时N个ms的函数 ps:不知道这个地方怎么算出来的是延时毫秒

参 数:n--延时长度

返回值 :无

********************************************/

void Delay_Nms(uchar n)

{

uchar i,j;

for( i = 0;i 《 n; i++ )

{

for( j = 0;j 《 3;j++ )

_NOP();

}

}

/*******************************************

函数名称:Play_Song

功 能:播放《祝你平安》的乐曲

参 数:无

返回值 :无

********************************************/

void Play_Song(void)

{

uchar Temp1,Temp2;

uchar addr = 0;

counter = 0; //中断计数器清0

while(1)

{

Temp1 = SONG[addr++];

if ( Temp1 == 0xFF ) //休止符

{

TACTL &=~MC_1; //停止计数

Delay_Nms(100);

}

else if ( Temp1 == 0x00 ) //歌曲结束符

{

return;

}

else

{

Temp2 = SONG[addr++];

TACTL |=MC_1; //开始计数

while(1)

{

Buzzer_Port ^= Buzzer;//电平取反

Delay_Nms(Temp1);//Temp1的值决定了延时的长短,也决定了声音的频率

if ( Temp2 == counter )//决定了音调持续的时间,计数时间到时就跳出循环演奏下一个。

{

counter = 0;

break;

}

}

}

}

}

收藏

相关话题
文章来源专栏

评论(0)

加载更多评论

参与评论

分享到

QQ空间 QQ好友 微博
取消