打印

单片机控制蜂鸣器唱歌,程序里的speak为什么要取反

[复制链接]
4197|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
luabc|  楼主 | 2012-6-16 10:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 luabc 于 2012-6-16 10:28 编辑

/********************************************************************
* 文件名  : 蜂鸣器唱歌.c
* 描述    :  该程序实现控制蜂鸣器演奏音乐。     
***********************************************************************/
#include<reg52.h>
#define uchar unsigned char
#define uint  unsigned int
uchar Count;
sbit Speak =P1^2;      //蜂鸣器器控制脚  
/*以下数组是音符编码*/
unsigned char code SONG[] ={      //祝你平安
0x26,0x20,0x20,0x20,0x20,0x20,0x26,0x10,0x20,0x10,0x20,0x80,0x26,0x20,0x30,0x20,
0x30,0x20,0x39,0x10,0x30,0x10,0x30,0x80,0x26,0x20,0x20,0x20,0x20,0x20,0x1c,0x20,
0x20,0x80,0x2b,0x20,0x26,0x20,0x20,0x20,0x2b,0x10,0x26,0x10,0x2b,0x80,0x26,0x20,
0x30,0x20,0x30,0x20,0x39,0x10,0x26,0x10,0x26,0x60,0x40,0x10,0x39,0x10,0x26,0x20,
0x30,0x20,0x30,0x20,0x39,0x10,0x26,0x10,0x26,0x80,0x26,0x20,0x2b,0x10,0x2b,0x10,
0x2b,0x20,0x30,0x10,0x39,0x10,0x26,0x10,0x2b,0x10,0x2b,0x20,0x2b,0x40,0x40,0x20,
0x20,0x10,0x20,0x10,0x2b,0x10,0x26,0x30,0x30,0x80,0x18,0x20,0x18,0x20,0x26,0x20,
0x20,0x20,0x20,0x40,0x26,0x20,0x2b,0x20,0x30,0x20,0x30,0x20,0x1c,0x20,0x20,0x20,
0x20,0x80,0x1c,0x20,0x1c,0x20,0x1c,0x20,0x30,0x20,0x30,0x60,0x39,0x10,0x30,0x10,
0x20,0x20,0x2b,0x10,0x26,0x10,0x2b,0x10,0x26,0x10,0x26,0x10,0x2b,0x10,0x2b,0x80,
0x18,0x20,0x18,0x20,0x26,0x20,0x20,0x20,0x20,0x60,0x26,0x10,0x2b,0x20,0x30,0x20,
0x30,0x20,0x1c,0x20,0x20,0x20,0x20,0x80,0x26,0x20,0x30,0x10,0x30,0x10,0x30,0x20,
0x39,0x20,0x26,0x10,0x2b,0x10,0x2b,0x20,0x2b,0x40,0x40,0x10,0x40,0x10,0x20,0x10,
0x20,0x10,0x2b,0x10,0x26,0x30,0x30,0x80,0x00,
                                  //路边的野华不要采
0x30,0x1C,0x10,0x20,0x40,0x1C,0x10,0x18,0x10,0x20,0x10,0x1C,0x10,0x18,0x40,0x1C,
0x20,0x20,0x20,0x1C,0x20,0x18,0x20,0x20,0x80,0xFF,0x20,0x30,0x1C,0x10,0x18,0x20,
0x15,0x20,0x1C,0x20,0x20,0x20,0x26,0x40,0x20,0x20,0x2B,0x20,0x26,0x20,0x20,0x20,
0x30,0x80,0xFF,0x20,0x20,0x1C,0x10,0x18,0x10,0x20,0x20,0x26,0x20,0x2B,0x20,0x30,
0x20,0x2B,0x40,0x20,0x20,0x1C,0x10,0x18,0x10,0x20,0x20,0x26,0x20,0x2B,0x20,0x30,
0x20,0x2B,0x40,0x20,0x30,0x1C,0x10,0x18,0x20,0x15,0x20,0x1C,0x20,0x20,0x20,0x26,
0x40,0x20,0x20,0x2B,0x20,0x26,0x20,0x20,0x20,0x30,0x80,0x20,0x30,0x1C,0x10,0x20,
0x10,0x1C,0x10,0x20,0x20,0x26,0x20,0x2B,0x20,0x30,0x20,0x2B,0x40,0x20,0x15,0x1F,
0x05,0x20,0x10,0x1C,0x10,0x20,0x20,0x26,0x20,0x2B,0x20,0x30,0x20,0x2B,0x40,0x20,
0x30,0x1C,0x10,0x18,0x20,0x15,0x20,0x1C,0x20,0x20,0x20,0x26,0x40,0x20,0x20,0x2B,
0x20,0x26,0x20,0x20,0x20,0x30,0x30,0x20,0x30,0x1C,0x10,0x18,0x40,0x1C,0x20,0x20,
0x20,0x26,0x40,0x13,0x60,0x18,0x20,0x15,0x40,0x13,0x40,0x18,0x80,0x00,
};
/********************************************************************
* 名称 : Time0_Init()
* 功能 : 定时器的初始化,定时时间可用光碟中软件计算,11.0592MZ晶振,10ms
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Time0_Init()
{
TMOD = 0x01;
IE   = 0x82;
TH0  = 0xDC;
TL0  = 0x00;  
}
/********************************************************************
* 名称 : Time0_Int()
* 功能 : 定时器中断,中断中实现 Count 加一
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Time0_Int() interrupt 1
{
TH0 = 0xDC;
TL0 = 0x00;
Count++;   //长度加1
}
/********************************************************************
* 名称 : Delay_xMs()
* 功能 : 延时子程序,经过软件调试,测得延时程序大概为55us.
* 输入 : x
* 输出 : 无
***********************************************************************/
void Delay_xMs(uint x)
{
    uint i,j;
    for(i=0; i<x; i++)
    {
        for(j=0; j<3; j++);
    }
}
/********************************************************************
* 名称 : Play_Song()
* 功能 : 播放蜂鸣器控制程序
* 输入 : i (选择播放哪首歌曲,0为“祝你平安”,1为“路边的野花你不要采”
* 输出 : 无
***********************************************************************/
void Play_Song(uchar i)
{
uchar Temp1,Temp2;
uint Addr;
Count = 0;      //中断计数器清0
Addr = i * 217;
while(1)
{
  Temp1 = SONG[Addr++];
     if (Temp1 == 0xFF)          //休止符
     {
      TR0 = 0;
      Delay_xMs(100);
     }
     else if (Temp1 == 0x00)   //歌曲结束符
     {
      return;
     }
     else
     {
      Temp2 = SONG[Addr++];
      TR0 = 1;
     while(1)
     {
       Speak = ~Speak;
       Delay_xMs(Temp1);
       if(Temp2 == Count)
       {
        Count = 0;
        break;
       }
      }
     }
}
}
/********************************************************************
* 名称 : Main()
* 功能 : 主函数
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Main()
{
Time0_Init();   //定时器0中断初始化
while(1)
{
  Play_Song(1);  //Play_Song(0)为祝你平安    Play_Song(1)为路边的野花你不要裁
}
}

相关帖子

沙发
yushiqian2012| | 2012-6-16 10:25 | 只看该作者
能不能贴一下图啊

使用特权

评论回复
板凳
luabc|  楼主 | 2012-6-16 10:26 | 只看该作者
本帖最后由 luabc 于 2012-6-16 10:30 编辑

突然明白了,这样不停给蜂鸣器加上高低电平,蜂鸣器振动发声,是不是这样?
突然想起以前自己写的让蜂鸣器发声的程序,只是不断给speak赋1和0,虽然可以发声,但是声音很小。
speak取反和给speak赋1和0有什么区别?

想想,其实效果都一样

使用特权

评论回复
地板
yushiqian2012| | 2012-6-16 10:40 | 只看该作者
..

使用特权

评论回复
5
yushiqian2012| | 2012-6-16 10:40 | 只看该作者
...对的,是靠震动才发声的

使用特权

评论回复
6
wukunshan| | 2012-6-16 15:34 | 只看该作者
speak取反、延时就是以一定的频率不断给speak赋1和0,达到改变蜂鸣器音色的目的。因为要让蜂鸣器唱出歌声来,不仅让它响还要控制声音起伏。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

26

帖子

0

粉丝