历史上的今天
今天是:2024年10月17日(星期四)
2019年10月17日 | MSP430学习笔记5-利用蜂鸣器演奏音乐
2019-10-17 来源:eefocus
这个小程序仍然是定时器的运用,比较简单,具体的地方都在注释中注明了,参考注释。
/*********************************************
程序功能: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; } } } } }
史海拾趣
|
开发板移植好教程,入门者的福音 还在为Linux移植入门而烦恼吗?还在为Linux驱动而头痛吗?还在为没有一本从入门到真正移植的好书苦闷吗? 现在您有一个好的选择,天嵌科技推出一部和开发板完美结合的教程:从下载源码到将内核移植适合于TQ2440开 ...… 查看全部问答> |
|
ActiveSync通过USB接口连接设备一直挺好的,可今天我拔usb线断开连接啊,机子死机了,重启过后就不行了,ce设备起来后无法自动连上,我只好手动运行repllop.exe进行连接,连上后,下载程序,运行很慢。我卸载重装都不行,换USB接口也不行,请问我改 ...… 查看全部问答> |
|
at89c51芯片加上cd4511bcn做一个计数器出错,请教下挫在那里? at89c51芯片的p0管脚作为2个四位bcd码的输出到cd4511bcn中去,然后通过cd4511bcn输出到2个8段显示器中,但是总是没有任何反应,请各位帮忙看看:以下是代码: -+ COUNT EQU ...… 查看全部问答> |
|
填充圆内的颜色, wince里不能用CreateHatchBrush显示各种阴影,那有什么其他函数能显示呢? 画直线, wince里不能用CreatePen的另一种函数,那如果我想画各种线该怎么做呢?比如点线… 查看全部问答> |
|
已经决定和微软合作开发Windows Phone手机的诺基亚,就把原来收购的 Qt放到了角落。据国外媒体报道,诺基亚决定将QT商业授权和服务业务出售给一家芬兰Digia公司,Digia计划雇用19名的诺基亚原来QT 相关雇员。   ...… 查看全部问答> |
|
我的MCU与上位机通信,同时需要处理一些事务,但当处理某些事务时是不允许上位机通信中断的,这样上位机通信有些时候就不通,当比较严重的时候是无法接受的,这是不是就要用到多任务操作系统了,专门用一个任务来与上位机中断通信,另外的任务来处 ...… 查看全部问答> |




