3826|0

2781

帖子

419

TA的资源

五彩晶圆(中级)

楼主
 

MSP430学习笔记5-利用蜂鸣器演奏音乐 [复制链接]

这个小程序仍然是定时器的运用,比较简单,具体的地方都在注释中注明了,参考注释。
  1. /*********************************************
  2. 程序功能:MCU控制蜂鸣器演奏歌曲《祝你平安》
  3. ----------------------------------------------
  4. 拨码开关设置:将BUZZER位拨至ON,其余位拨至OFF
  5. 测试说明:聆听蜂鸣器“唱出”的乐曲

  6. 既然是演奏乐曲对于一个音符应该包括两个部分
  7. 一是声调 二是持续时间,在这个程序中声调是用简单的
  8. 延时-电平翻转来实现的,改变了延时的时间就改变了
  9. 声调,而时间是通过计数比较来实现的,当计数值相等时
  10. 就跳出循环演奏下一个音符。
  11. *********************************************/
  12. #include  

  13. typedef unsigned char uchar;

  14. #include  "music.h"

  15. #define   Buzzer        BIT7
  16. #define   Buzzer_Port   P6OUT
  17. #define   Buzzer_DIR    P6DIR

  18. uchar counter;
  19. void Play_Song(void);

  20. /***************主函数****************/
  21. void main(void)
  22. {
  23.     uchar i;
  24.    
  25.     /*下面六行程序关闭所有的IO口*/
  26.     P1DIR = 0XFF;P1OUT = 0XFF;
  27.     P2DIR = 0XFF;P2OUT = 0XFF;
  28.     P3DIR = 0XFF;P3OUT = 0XFF;
  29.     P4DIR = 0XFF;P4OUT = 0XFF;
  30.     P5DIR = 0XFF;P5OUT = 0XFF;
  31.     P6DIR = 0XFF;P6OUT = 0XFF;
  32.     P6DIR |= BIT2;P6OUT |= BIT2;         //关闭电平转换
  33.      
  34.     WDTCTL = WDTPW + WDTHOLD;                 //关闭看门狗
  35.     /*------选择系统主时钟为8MHz-------*/
  36.     BCSCTL1 &= ~XT2OFF;                       // 打开XT2高频晶体振荡器
  37.     do
  38.     {
  39.         IFG1 &= ~OFIFG;                       //清除晶振失败标志
  40.         for (i = 0xFF; i > 0; i--);           // 等待8MHz晶体起振
  41.     }
  42.     while ((IFG1 & OFIFG));                   // 晶振失效标志仍然存在?
  43.     BCSCTL2 |= SELM_2 + SELS;                 //主时钟和从时钟都选择高频晶振
  44.    
  45.    
  46.     //设置定时器A每10ms中断一次
  47.     CCTL0 = CCIE;
  48.     CCR0 = 10000;//改变这个值就改变了演奏的速度
  49.     TACTL |= TASSEL_2 + ID_3;
  50.     //设置控制蜂鸣器的IO方向为输出
  51.     Buzzer_DIR |= Buzzer;
  52.     //打开全局中断
  53.     _EINT();
  54.     //循环演奏歌曲
  55.     while(1)
  56.     {
  57.         Play_Song();
  58.     }
  59. }

  60. /*******************************************
  61. 函数名称:TimerA_ISR
  62. 功    能:定时器A的中断服务函数
  63. 参    数:无
  64. 返回值  :无
  65. ********************************************/
  66. #pragma vector = TIMERA0_VECTOR
  67. __interrupt void TimerA_ISR(void)
  68. {
  69.     counter++;
  70. }
  71. /*******************************************
  72. 函数名称:Delay_Nms
  73. 功    能:延时N个ms的函数              ps:不知道这个地方怎么算出来的是延时毫秒
  74. 参    数:n--延时长度
  75. 返回值  :无
  76. ********************************************/
  77. void Delay_Nms(uchar n)
  78. {
  79.     uchar i,j;
  80.    
  81.     for( i = 0;i < n; i++ )
  82.     {
  83.         for( j = 0;j < 3;j++ )
  84.           _NOP();
  85.     }
  86. }
  87. /*******************************************
  88. 函数名称:Play_Song
  89. 功    能:播放《祝你平安》的乐曲
  90. 参    数:无
  91. 返回值  :无
  92. ********************************************/
  93. void Play_Song(void)
  94. {
  95.     uchar Temp1,Temp2;
  96.     uchar addr = 0;
  97.    
  98.     counter = 0; //中断计数器清0
  99.     while(1)
  100.     {
  101.         Temp1 = SONG[addr++];
  102.         if ( Temp1 == 0xFF )        //休止符
  103.         {
  104.             TACTL &=~MC_1;          //停止计数
  105.             Delay_Nms(100);
  106.         }
  107.         else if ( Temp1 == 0x00 )   //歌曲结束符
  108.         {
  109.             return;
  110.         }
  111.         else
  112.         {
  113.             Temp2 = SONG[addr++];
  114.             TACTL |=MC_1;           //开始计数
  115.             while(1)
  116.             {
  117.                 Buzzer_Port ^= Buzzer;//电平取反
  118.                 Delay_Nms(Temp1);//Temp1的值决定了延时的长短,也决定了声音的频率
  119.                 if ( Temp2 == counter )//决定了音调持续的时间,计数时间到时就跳出循环演奏下一个。
  120.                 {
  121.                     counter = 0;
  122.                     break;
  123.                 }
  124.             }
  125.         }
  126.     }
  127. }
复制代码

[ 本帖最后由 qinkaiabc 于 2013-11-29 10:55 编辑 ]
 
点赞 关注
个人签名

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表