天天看点

MSP430学习笔记5-利用蜂鸣器演奏音乐

这个小程序仍然是定时器的运用,比较简单,具体的地方都在注释中注明了,参考注释。

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

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

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

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

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

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

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

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

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

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

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

#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  

        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;  

                }  

            }  

本文转自emouse博客园博客,原文链接:http://www.cnblogs.com/emouse/archive/2010/07/22/2198220.html,如需转载请自行联系原作者

继续阅读