使用PWM生成基本的钢琴音符

2016-12-021.9万
AI 快速预览详细 收起
本文介绍了如何使用Arduino Uno、蜂鸣器和4*4矩阵键盘,通过PWM生成基本的钢琴音符。项目包括详细的电路图和代码示例,适合STEM教育场景。通过配置TCCR2A和TCCR2B寄存器,可以精确控制PWM频率,生成特定音符。例如,生成261Hz的C音符,配置为TCCR2A = B01000011, TCCR2B = B00001110, OCR2A = 119。上传代码后,用户可以尝试弹奏“生日快乐”等简单曲目。


所需硬件: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


创作许可协议

本项目采用 None(不开放任何权利,保留所有权利) 进行许可。

评论(5)
kimi423520
kimi423520
不错, 赞
老曾
老曾
感谢分享
dsweiliang
dsweiliang
感谢分享爱啊
yuzhunyu
yuzhunyu
作者
回复dsweiliang
评论内容
吹口琴的钢铁侠
吹口琴的钢铁侠
我记得有一个专门的音符的函数库,跟这个有点类似
yuzhunyu
yuzhunyu
作者
回复吹口琴的钢铁侠
:handshake
hnyzcj
hnyzcj
不错不错,
yuzhunyu
yuzhunyu
作者
回复hnyzcj
哈哈:handshake:victory:
- 没有更多了 -