极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 15169|回复: 5

OCROBOT入门教程012--简易乐器

[复制链接]
发表于 2014-4-25 16:09:46 | 显示全部楼层 |阅读模式
本帖最后由 董董soul 于 2016-10-27 11:02 编辑

上节课我们学习了怎样使一个无源蜂鸣器发出声音,这节课我们学习怎样用一个无源蜂鸣器和5个微动开关,做出来一个简易乐器。

这次我们使用函数tone()来发声。


tone()
描述
在一个引脚上产生一个特定频率的方波(50%占空比)。持续时间可以设定,否则波形会一直产生直到调用noTone()函数。该引脚可以连接压电蜂鸣器或其他喇叭播放声音。
在同一时刻只能产生一个声音。如果一个引脚已经在播放音乐,那调用tone()将不会有任何效果。如果音乐在同一个引脚上播放,它会自动调整频率。
使用tone()函数会与3脚和11脚的PWM产生干扰(Mega板除外)。

注意:如果你要在多个引脚上产生不同的音调,你要在对下一个引脚使用tone()函数前对此引脚调用noTone()函数。

语法
tone(pin, frequency)
tone(pin, frequency, duration)
参数
pin:要产生声音的引脚
frequency: 产生声音的频率,单位Hz,类型unsigned int
duration:声音持续的时间,单位毫秒(可选),类型unsigned long


这次我们使用了5个微动开关,如果每一个开关都加一个上拉电阻的话电路就略显复杂。所以这里我们使用内上拉。

ATmega328P芯片内部其实有上拉的功能,我们可以使用ATmega328P内部的上拉功能替代外部上拉。
ATmega328P Datasheet中有内部上拉的结构介绍,如下图:




介绍一下上拉电阻
在数字电路中,上拉电阻(英语:Pull-up resistors)是当某输入端口未连接设备或处于高阻抗的情况下,一种用于保证输入信号为预期逻辑电平的电阻元件。他们通常在不同的逻辑器件之间工作,提供一定的电压信号。

上拉电阻的作用
在上拉电阻所连接的导线上,如果外部组件未启用,上拉电阻将“微弱地”将输入电压信号“拉高”。当外部组件未连接时,对输入端来说,外部“看上去”就是高阻抗的。这时,通过上拉电阻可以将输入端口处的电压拉高到高电平。如果外部组件启用,它将取消上拉电阻所设置的高电平。通过这样,上拉电阻可以使引脚即使在未连接外部组件的时候也能保持确定的逻辑电平。




  1. #define time 50
  2. void setup()
  3. {
  4.   for (int i=2; i<=6; i++)    //通过循环的方式设置2-7号引脚为输出状态
  5.   {
  6.     pinMode(i,INPUT_PULLUP);
  7.   }
  8. }
  9. void loop()
  10. {
  11.   //D2
  12.   if(digitalRead(2)==LOW)
  13.   {
  14.     delay(5);
  15.     if(digitalRead(2)==LOW)
  16.     {
  17.       tone(7,523,time); //Do
  18.       while(digitalRead(2)==LOW)
  19.       {
  20.         delay(1);
  21.       }
  22.     }
  23.   }
  24.   //D3
  25.   if(digitalRead(3)==LOW)
  26.   {
  27.     delay(5);
  28.     if(digitalRead(3)==LOW)
  29.     {
  30.       tone(7,587,time); //Re
  31.       while(digitalRead(3)==LOW)
  32.       {
  33.         delay(1);
  34.       }
  35.     }
  36.   }  
  37.   //D4
  38.   if(digitalRead(4)==LOW)
  39.   {
  40.     delay(5);
  41.     if(digitalRead(4)==LOW)
  42.     {
  43.       tone(7,659,time); //Mi
  44.       while(digitalRead(4)==LOW)
  45.       {
  46.         delay(1);
  47.       }
  48.     }
  49.   }  
  50.   //D5
  51.   if(digitalRead(5)==LOW)
  52.   {
  53.     delay(5);
  54.     if(digitalRead(5)==LOW)
  55.     {
  56.       tone(7,698,time); //Fa
  57.       while(digitalRead(5)==LOW)
  58.       {
  59.         delay(1);
  60.       }
  61.     }
  62.   }
  63.   //D6
  64.   if(digitalRead(6)==LOW)
  65.   {
  66.     delay(5);
  67.     if(digitalRead(6)==LOW)
  68.     {
  69.       tone(7,784,time); //So
  70.       while(digitalRead(6)==LOW)
  71.       {
  72.         delay(1);
  73.       }
  74.     }
  75.   }
  76. }
复制代码


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复

使用道具 举报

发表于 2014-8-26 20:05:21 | 显示全部楼层
本帖最后由 musteryu 于 2014-8-26 20:07 编辑
  1. #define time 50
  2. int button[6]={6,5,4,3,2};
  3. int freq[6]={523,587,659,784,880};//设定对应频率
  4. int buzzer=7;
  5. void setup() {
  6.         for(int i=1;i<6;i++){
  7.                 pinMode(button[i-1], INPUT_PULLUP);
  8.         }
  9. }

  10. void loop() {
  11.         for(int i=1; i<6; i++){
  12.             if(digitalRead(button[i-1])==LOW){
  13.                         delay(5);
  14.                         while(digitalRead(button[i-1])==LOW){
  15.                                 tone(buzzer,freq[i-1],time);
  16.                                 delay(1);
  17.                         }
  18.                 }
  19.         }       
  20. }
复制代码
弘毅大哥的代码还是有点长,其实可以这么改一下。
不完全一样,道理差不多。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-8-29 23:23:38 | 显示全部楼层
musteryu 发表于 2014-8-26 20:05
弘毅大哥的代码还是有点长,其实可以这么改一下。
不完全一样,道理差不多。

恩。。。这样子简洁很多
回复 支持 反对

使用道具 举报

发表于 2015-7-21 15:43:42 | 显示全部楼层
顶一下{:soso_e113:}
回复 支持 反对

使用道具 举报

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

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-4-25 01:36 , Processed in 0.043648 second(s), 22 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表