10761浏览
查看: 10761|回复: 8

[进阶] 使用PWM生成基本的钢琴音符

[复制链接]
本帖最后由 yuzhunyu 于 2016-12-2 11:32 编辑

所需硬件:1.  Arduino uno   *1
                 2.  蜂鸣器              *1
                 3.  4*4矩阵键盘     *1
电路图:
蜂鸣器接在11号口,矩阵键盘占用2-9号口(r0、r1、r2、r3、c0、c1、c2、c3
使用PWM生成基本的钢琴音符图1

代码:
[mw_shl_code=applescript,true]#define c3 9
#define c2 8
#define c1 7
#define c0 6
#define r3 5
#define r2 4
#define r1 3
#define r0 2
void setup() {
  Serial.begin(9600);
  pinMode(c0, INPUT_PULLUP);
  pinMode(c1, INPUT_PULLUP);
  pinMode(c2, INPUT_PULLUP);
  pinMode(c3, INPUT_PULLUP);
  pinMode(r0, OUTPUT);
  pinMode(r1, OUTPUT);
  pinMode(r2, OUTPUT);
  pinMode(r3, OUTPUT);
  pinMode(11, OUTPUT);
}
void loop() {
  digitalWrite(r0, LOW);
  digitalWrite(r1, HIGH);
  digitalWrite(r2, HIGH);
  digitalWrite(r3, HIGH);
  if (digitalRead(c0) == LOW) {
    TCCR2A = B01000011;
    TCCR2B = B00001110;
    OCR2A = 119;
    delay(100);
    TCCR2B = B00001000;
    TCCR2A = B00000000;
    digitalWrite(11, LOW);
  }
  else if (digitalRead(c1) == LOW) {
    TCCR2A = B01000011;
    TCCR2B = B00001110;
    OCR2A = 106;
    delay(100);
    TCCR2B = B00001000;
    TCCR2A = B00000000;
    digitalWrite(11, LOW);
  }
  else if (digitalRead(c2) == LOW) {
    TCCR2A = B01000011;
    TCCR2B = B00001110;
    OCR2A = 94;
    delay(100);
    TCCR2B = B00001000;
    TCCR2A = B00000000;
    digitalWrite(11, LOW);
  }
  else if (digitalRead(c3) == LOW) {
    TCCR2A = B01000011;
    TCCR2B = B00001110;
    OCR2A = 89;
    delay(100);
    TCCR2B = B00001000;
    TCCR2A = B00000000;
    digitalWrite(11, LOW);
  }
  digitalWrite(r0, HIGH);
  digitalWrite(r1, LOW);
  digitalWrite(r2, HIGH);
  digitalWrite(r3, HIGH);
  if (digitalRead(c0) == LOW) {
    TCCR2A = B01000011;
    TCCR2B = B00001110;
    OCR2A = 79;
    delay(100);
    TCCR2B = B00001000;
    TCCR2A = B00000000;
    digitalWrite(11, LOW);
  }
  else if (digitalRead(c1) == LOW) {
    TCCR2A = B01000011;
    TCCR2B = B00001110;
    OCR2A = 71;
    delay(100);
    TCCR2B = B00001000;
    TCCR2A = B00000000;
    digitalWrite(11, LOW);
  }
  else if (digitalRead(c2) == LOW) {
    TCCR2A = B01000011;
    TCCR2B = B00001110;
    OCR2A = 63;
    delay(100);
    TCCR2B = B00001000;
    TCCR2A = B00000000;
    digitalWrite(11, LOW);
  }
  else if (digitalRead(c3) == LOW) {
    TCCR2A = B01000011;
    TCCR2B = B00001110;
    OCR2A = 59;
    delay(100);
    TCCR2B = B00001000;
    TCCR2A = B00000000;
    digitalWrite(11, LOW);
  }
  digitalWrite(r0, HIGH);
  digitalWrite(r1, HIGH);
  digitalWrite(r2, LOW);
  digitalWrite(r3, HIGH);
  if (digitalRead(c0) == LOW) {
    TCCR2A = B01000011;
    TCCR2B = B00001110;
    OCR2A = 25;
    delay(100);
    TCCR2B = B00001000;
    TCCR2A = B00000000;
    digitalWrite(11, LOW);
  }
  else if (digitalRead(c1) == LOW) {
    TCCR2A = B01000011;
    TCCR2B = B00001110;
    OCR2A = 20;
    delay(100);
    TCCR2B = B00001000;
    TCCR2A = B00000000;
    digitalWrite(11, LOW);
  }
  else if (digitalRead(c2) == LOW) {
    TCCR2A = B01000011;
    TCCR2B = B00001110;
    OCR2A = 10;
    delay(100);
    TCCR2B = B00001000;
    TCCR2A = B00000000;
    digitalWrite(11, LOW);
  }
  else if (digitalRead(c3) == LOW) {
    TCCR2A = B01000011;
    TCCR2B = B00001110;
    OCR2A = 50;
    delay(100);
    TCCR2B = B00001000;
    TCCR2A = B00000000;
    digitalWrite(11, LOW);
  }
  digitalWrite(r0, HIGH);
  digitalWrite(r1, HIGH);
  digitalWrite(r2, HIGH);
  digitalWrite(r3, LOW);
  if (digitalRead(c0) == LOW) {
    TCCR2A = B01000011;
    TCCR2B = B00001110;
    OCR2A = 50;
    delay(100);
    TCCR2B = B00001000;
    TCCR2A = B00000000;
    digitalWrite(11, LOW);
  }
  else if (digitalRead(c1) == LOW) {
    TCCR2A = B01000011;
    TCCR2B = B00001110;
    OCR2A = 50;
    delay(100);
    TCCR2B = B00001000;
    TCCR2A = B00000000;
    digitalWrite(11, LOW);
  }
  else if (digitalRead(c2) == LOW) {
    TCCR2A = B01000011;
    TCCR2B = B00001110;
    OCR2A = 50;
    delay(100);
    TCCR2B = B00001000;
    TCCR2A = B00000000;
    digitalWrite(11, LOW);
  }
  else if (digitalRead(c3) == LOW) {
    TCCR2A = B01000011;
    TCCR2B = B00001110;
    OCR2A = 50;
    delay(100);
    TCCR2B = B00001000;
    TCCR2A = B00000000;
    digitalWrite(11, LOW);
  }
}[/mw_shl_code]
原理:
钢琴的基本音符的频率如下
c - 261 HZ
d - 294 HZ
e - 329 HZ
f - 349 HZ
g - 392 HZ
a - 440 HZ
b - 493 HZ
C - 523 HZ
涉及到的公式:
frequency in Hz = 16MHz/prescalar/(OCRA+1)/2 (for register A i.e. pin 11)
比如:生成261hz
TCCR2A = B01000011; (com2a1 com2a0计数器值达到119)
TCCR2B = B00001110; (ca22 ca21 cs20 prescalar选择256)
OCR2A = 119;
代入公式得:16MHZ/256/120/2 = 260.42HZ


上传至UNO,现在你可以试试自己弹一曲“生日快乐”了:lol
下载附件piano.zip


hnyzcj  版主

发表于 2016-12-2 13:31:10

不错不错,
回复

使用道具 举报

yuzhunyu  见习技师
 楼主|

发表于 2016-12-2 13:40:11


哈哈:handshake:victory:
回复

使用道具 举报

吹口琴的钢铁侠  初级技匠

发表于 2016-12-3 15:45:29

我记得有一个专门的音符的函数库,跟这个有点类似
回复

使用道具 举报

yuzhunyu  见习技师
 楼主|

发表于 2016-12-5 09:40:24

吹口琴的钢铁侠 发表于 2016-12-3 15:45
我记得有一个专门的音符的函数库,跟这个有点类似

:handshake
回复

使用道具 举报

dsweiliang  初级技神

发表于 2016-12-8 16:41:55

感谢分享爱啊
回复

使用道具 举报

yuzhunyu  见习技师
 楼主|

发表于 2016-12-8 18:53:24

回复

使用道具 举报

zsh888888  初级技神

发表于 2017-1-2 23:53:39

感谢分享
回复

使用道具 举报

kimi423520  学徒

发表于 2018-6-11 17:00:36

不错, 赞
回复

使用道具 举报

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

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail