[资料分享] 你会用MSP430让蜂鸣器演奏音乐么

fish001   2017-8-21 22:13 楼主
这个小程序仍然是定时器的运用,比较简单,具体的地方都在注释中注明了,参考注释。

  • /*********************************************
  • 程序功能:MCU控制蜂鸣器演奏歌曲《祝你平安》
  • ----------------------------------------------
  • 拨码开关设置:将BUZZER位拨至ON,其余位拨至OFF
  • 测试说明:聆听蜂鸣器“唱出”的乐曲
  • 既然是演奏乐曲对于一个音符应该包括两个部分
  • 一是声调 二是持续时间,在这个程序中声调是用简单的
  • 延时-电平翻转来实现的,改变了延时的时间就改变了
  • 声调,而时间是通过计数比较来实现的,当计数值相等时
  • 就跳出循环演奏下一个音符。
  • *********************************************/  
  • #include    
  •   
  • 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;  
  •                 }  
  •             }  
  •         }  
  •     }  
  • }  



回复评论

暂无评论,赶紧抢沙发吧
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复