使用MSP430制作一个简单电子琴
作品功能
这个项目基于MSP430单片机,实现了一个简单的电子琴。通过按键输入,电子琴可以发出对应的音符声音。具体功能包括:
- 按下按键时发出对应音符的声音。
- 松开按键时停止发声。
- 支持C调低音、中音和高音。
硬件材料
- MSP430 单片机
- 蜂鸣器
- 矩阵键盘
电子元器件如何连接
按键
- 按键1 接 P1.3
- 按键2 接 P1.4
- 按键3 接 P1.5
- 按键4 接 P2.0
- 其他按键 P1.0 P1.1 P1.2
蜂鸣器
- 蜂鸣器控制引脚 接 P2.2
代码讲解
1. 宏定义和函数声明
定义了延时函数和不同音调的频率宏,提供了音符与频率之间的映射。
#include <msp430.h>
#define SYSCLK 1000000
#define CPU_F ( (double) 1000000)
#define delay_us(x) __delay_cycles((long)(CPU_F * (double)x / 1000000.0))
#define delay_ms(x) __delay_cycles((long)(CPU_F * (double)x / 1000.0))
#define L1 262
#define L2 286
#define L3 311
#define L4 349
#define L5 392
#define L6 440
#define L7 494
#define Z1 523
#define Z2 587
#define Z3 659
#define Z4 698
#define Z5 784
#define Z6 880
#define Z7 987
#define H1 1046
#define H2 1174
#define H3 1318
#define H4 1396
#define H5 1567
#define H6 1760
#define H7 1975
#define IN1 (P1IN & BIT3)
#define IN2 (P1IN & BIT4)
#define IN3 (P1IN & BIT5)
#define IN4 (P2IN & BIT0)
const char map[] = { 12, 9, 6, 3, 11, 8, 5, 2, 10, 7, 4, 1 };
int fre_st[] = { L1, L2, L3, L4, L5, L6, L7, Z1, Z2, Z3, Z4, Z5, Z6, Z7, H1, H2, H3, H4, H5, H6, H7 };
2. 主函数
初始化系统时钟、按键、蜂鸣器等模块。通过循环检测按键输入,根据按键播放对应的音调。按下按键时蜂鸣器发声,松开按键时停止发声。
int main(void) {
char key;
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
if (CALBC1_1MHZ == 0xFF) { // If calibration constant erased
while (1); // do not load, trap CPU!!
}
DCOCTL = 0; // Select lowest DCOx and MODx settings
BCSCTL1 = CALBC1_1MHZ; // Set range
DCOCTL = CALDCO_1MHZ; // Set DCO step + modulation
// 定时器中断初始化
CCTL0 = CCIE; // CCR0 interrupt enabled
CCR0 = 0;
TACTL = TASSEL_2 + MC_0; // SMCLK, upmode
// 键盘引脚初始化
P1SEL = 0;
P1DIR |= (BIT0 + BIT1 + BIT2); // P1.0, P1.1, P1.2是输出
P1OUT |= (BIT0 + BIT1 + BIT2); // P1.0, P1.1, P1.2输出高电平
P1DIR &= ~(BIT3 + BIT4 + BIT5);
P1REN |= (BIT3 + BIT4 + BIT5);
P1OUT |= (BIT3 + BIT4 + BIT5);
P2DIR &= ~(BIT0);
P2REN |= (BIT0);
P2OUT |= (BIT0);
// 蜂鸣器引脚初始化
P2DIR |= BIT2; // P2.2 output
P2SEL |= BIT2; // P2.2 for TA1.1 output
while (1) {
key = get_key(); // 获取按键
if (key) {
key = map[key - 1];
TA1CCR0 = SYSCLK / fre_st[key - 1]; // 选一个频率
TA1CTL = TASSEL_2 + MC_1; // SMCLK, up mode
} else {
TA1CTL = TASSEL_2 + MC_0; // 停止蜂鸣器
}
}
}
全部代码
https://docs.qq.com/sheet/DUEdqZ2lmbmR6UVdU?tab=BB08J2